Repository: n0shake/Clocker
Branch: master
Commit: 18778bad0ec9
Files: 547
Total size: 2.4 MB
Directory structure:
gitextract_ww47k156/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .swiftformat
├── .swiftlint.yml
├── .travis.yml
├── Archive/
│ └── New Icons/
│ └── Older Icons/
│ ├── New Icons/
│ │ └── NewIcon.xcf
│ └── Old Icons/
│ └── ClockerIcon.xcf
├── CLAUDE.md
├── Clocker/
│ ├── AppDelegate.swift
│ ├── Clocker/
│ │ ├── Clocker-Info.plist
│ │ ├── Clocker-Prefix.pch
│ │ ├── Clocker.entitlements
│ │ ├── LocationController.swift
│ │ ├── MainMenu.xib
│ │ ├── ShortcutRecorder-master/
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE.md
│ │ │ ├── Library/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── Prefix.pch
│ │ │ │ ├── SRCommon.h
│ │ │ │ ├── SRCommon.m
│ │ │ │ ├── SRKeyCodeTransformer.h
│ │ │ │ ├── SRKeyCodeTransformer.m
│ │ │ │ ├── SRKeyEquivalentModifierMaskTransformer.h
│ │ │ │ ├── SRKeyEquivalentModifierMaskTransformer.m
│ │ │ │ ├── SRKeyEquivalentTransformer.h
│ │ │ │ ├── SRKeyEquivalentTransformer.m
│ │ │ │ ├── SRModifierFlagsTransformer.h
│ │ │ │ ├── SRModifierFlagsTransformer.m
│ │ │ │ ├── SRRecorderControl.h
│ │ │ │ ├── SRRecorderControl.m
│ │ │ │ ├── SRValidator.h
│ │ │ │ ├── SRValidator.m
│ │ │ │ └── ShortcutRecorder.h
│ │ │ ├── PTHotKey/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── PTHotKey+ShortcutRecorder.h
│ │ │ │ ├── PTHotKey+ShortcutRecorder.m
│ │ │ │ ├── PTHotKey.h
│ │ │ │ ├── PTHotKey.m
│ │ │ │ ├── PTHotKeyCenter.h
│ │ │ │ ├── PTHotKeyCenter.m
│ │ │ │ ├── PTKeyCodeTranslator.h
│ │ │ │ ├── PTKeyCodeTranslator.m
│ │ │ │ ├── PTKeyCombo.h
│ │ │ │ └── PTKeyCombo.m
│ │ │ ├── README.md
│ │ │ ├── Resources/
│ │ │ │ ├── LICENSE.txt
│ │ │ │ ├── ShorcutRecorder Yosemite.sketch
│ │ │ │ ├── ar.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── ca.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── cs.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── de.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── el.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── es-MX.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── ja.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── ko.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── nb.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── pl.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── pt-BR.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── pt.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── ro.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── sk.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── sv.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── th.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── tr.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ ├── zh-Hans.lproj/
│ │ │ │ │ └── ShortcutRecorder.strings
│ │ │ │ └── zh-Hant.lproj/
│ │ │ │ └── ShortcutRecorder.strings
│ │ │ ├── ShortcutRecorder.podspec
│ │ │ └── ShortcutRecorder.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ ├── PTHotKey.framework.xcscheme
│ │ │ └── ShortcutRecorder.framework.xcscheme
│ │ ├── ar.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── ca.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── com.abhishek.ClockerHelper.plist
│ │ ├── de.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── en.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ ├── Localizable.strings
│ │ │ └── Panel.xib
│ │ ├── es.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── fr.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── hi.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── hr.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── it.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── ja.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── ko.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── main.m
│ │ ├── nl.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── pl.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── pt-BR.lproj/
│ │ │ └── Localizable.strings
│ │ ├── pt-PT.lproj/
│ │ │ └── InfoPlist.strings
│ │ ├── ru.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── tr.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ ├── uk.lproj/
│ │ │ └── Localizable.strings
│ │ ├── zh-Hans.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Localizable.strings
│ │ └── zh-Hant.lproj/
│ │ └── Localizable.strings
│ ├── Clocker-Bridging-Header.h
│ ├── Clocker.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ ├── xcshareddata/
│ │ │ │ ├── Clocker.xcscmblueprint
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcuserdata/
│ │ │ ├── abhishek_banthia.xcuserdatad/
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ ├── abhishekbanthia.xcuserdatad/
│ │ │ │ └── IDEFindNavigatorScopes.plist
│ │ │ └── ban.xcuserdatad/
│ │ │ └── IDEFindNavigatorScopes.plist
│ │ ├── xcshareddata/
│ │ │ ├── IDETemplateMacros.plist
│ │ │ └── xcschemes/
│ │ │ ├── Clocker.xcscheme
│ │ │ └── Tests.xcscheme
│ │ └── xcuserdata/
│ │ ├── abhi.xcuserdatad/
│ │ │ └── xcschemes/
│ │ │ └── xcschememanagement.plist
│ │ ├── abhishek_banthia.xcuserdatad/
│ │ │ └── xcschemes/
│ │ │ ├── Clocker.xcscheme
│ │ │ ├── ClockerHelper.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ ├── abhishekbanthia.xcuserdatad/
│ │ │ ├── xcdebugger/
│ │ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes/
│ │ │ ├── ClockerHelper.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── ban.xcuserdatad/
│ │ ├── xcdebugger/
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes/
│ │ └── xcschememanagement.plist
│ ├── ClockerHelper/
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ └── Main.storyboard
│ │ ├── ClockerHelper.entitlements
│ │ ├── Info.plist
│ │ ├── de.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Main.strings
│ │ ├── main.m
│ │ ├── ru.lproj/
│ │ │ ├── InfoPlist.strings
│ │ │ └── Main.strings
│ │ └── zh-Hans.lproj/
│ │ ├── InfoPlist.strings
│ │ └── Main.strings
│ ├── ClockerUITests/
│ │ ├── AboutUsTests.swift
│ │ ├── ClockerUITests-Bridging-Header.h
│ │ ├── ClockerUITests.m
│ │ ├── CopyToClipboardTests.swift
│ │ ├── FloatingWindowTests.swift
│ │ ├── Info.plist
│ │ ├── NetworkDisconnectionTests.swift
│ │ ├── OnboardingSearchTests.swift
│ │ ├── OnboardingTests.swift
│ │ ├── PanelTests.swift
│ │ ├── PermissionsTests.swift
│ │ ├── PreferencesTest.swift
│ │ ├── ReviewTests.swift
│ │ ├── ShortcutTests.swift
│ │ ├── de.lproj/
│ │ │ └── InfoPlist.strings
│ │ ├── ru.lproj/
│ │ │ └── InfoPlist.strings
│ │ └── zh-Hans.lproj/
│ │ └── InfoPlist.strings
│ ├── ClockerUnitTests/
│ │ ├── AppDelegateTests.swift
│ │ ├── ClockerUnitTests.swift
│ │ ├── DateFormatterManagerTests.swift
│ │ ├── EventInfoTests.swift
│ │ ├── Info.plist
│ │ ├── ReviewControllerTests.swift
│ │ ├── SearchDataSourceTests.swift
│ │ ├── StandardMenubarHandlerTests.swift
│ │ └── ThemerTests.swift
│ ├── CoreLoggerKit/
│ │ ├── .gitignore
│ │ ├── Package.swift
│ │ ├── README.md
│ │ ├── Sources/
│ │ │ └── CoreLoggerKit/
│ │ │ └── Logger.swift
│ │ └── Tests/
│ │ ├── CoreLoggerKitTests/
│ │ │ ├── CoreLoggerKitTests.swift
│ │ │ └── XCTestManifests.swift
│ │ └── LinuxMain.swift
│ ├── CoreModelKit/
│ │ ├── .gitignore
│ │ ├── Package.swift
│ │ ├── README.md
│ │ ├── Sources/
│ │ │ └── CoreModelKit/
│ │ │ ├── SearchResults.swift
│ │ │ └── TimezoneData.swift
│ │ └── Tests/
│ │ ├── CoreModelKitTests/
│ │ │ ├── TimezoneDataEqualityTests.swift
│ │ │ └── XCTestManifests.swift
│ │ └── LinuxMain.swift
│ ├── Dependencies/
│ │ ├── Date Additions/
│ │ │ ├── Constants.swift
│ │ │ ├── Date+Bundle.swift
│ │ │ ├── Date+Comparators.swift
│ │ │ ├── Date+Components.swift
│ │ │ ├── Date+Format.swift
│ │ │ ├── Date+Inits.swift
│ │ │ ├── Date+Manipulations.swift
│ │ │ ├── Date+TimeAgo.swift
│ │ │ ├── DateTools.bundle/
│ │ │ │ ├── am.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ar.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── bg.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ca.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── cs.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── cy.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── da.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── de.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── eu.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── fi.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── gre.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── gu.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── he.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── hi.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── hr.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── hu.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── id.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── is.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ja.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ko.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── lv.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ms.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── nb.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── pl.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── pt-PT.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── pt.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ro.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── sk.lproj/
│ │ │ │ │ └── NSDateTimeAgo.strings
│ │ │ │ ├── sl.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── sv.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── th.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── tr.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── uk.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── vi.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ ├── zh-Hans.lproj/
│ │ │ │ │ └── DateTools.strings
│ │ │ │ └── zh-Hant.lproj/
│ │ │ │ └── DateTools.strings
│ │ │ ├── Enums.swift
│ │ │ ├── Integer+DateTools.swift
│ │ │ └── TimeChunk.swift
│ │ ├── Solar.swift
│ │ └── iVersion/
│ │ ├── iVersion.bundle/
│ │ │ ├── da.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── de.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── el.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── en-GB.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── en.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── es.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── fr.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── it.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── ja.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── pt-PT.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── pt.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── ru.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── tr.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ ├── zh-Hans.lproj/
│ │ │ │ └── Localizable.strings
│ │ │ └── zh-Hant.lproj/
│ │ │ └── Localizable.strings
│ │ ├── iVersion.h
│ │ └── iVersion.m
│ ├── Events and Reminders/
│ │ ├── CalendarHandler.swift
│ │ ├── EventCenter.swift
│ │ └── RemindersHandler.swift
│ ├── Firebase.h
│ ├── Frameworks/
│ │ └── Firebase/
│ │ ├── FirebaseCore.framework/
│ │ │ ├── FirebaseCore
│ │ │ ├── Headers/
│ │ │ │ ├── FIRApp.h
│ │ │ │ ├── FIRConfiguration.h
│ │ │ │ ├── FIRLoggerLevel.h
│ │ │ │ ├── FIROptions.h
│ │ │ │ ├── FIRVersion.h
│ │ │ │ └── FirebaseCore.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── FirebaseCoreDiagnostics.framework/
│ │ │ ├── FirebaseCoreDiagnostics
│ │ │ ├── Headers/
│ │ │ │ ├── FIRCoreDiagnostics.h
│ │ │ │ └── FirebaseCoreDiagnostics-umbrella.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── FirebaseCrashlytics.framework/
│ │ │ ├── FirebaseCrashlytics
│ │ │ ├── Headers/
│ │ │ │ ├── FIRCrashlytics.h
│ │ │ │ ├── FIRCrashlyticsReport.h
│ │ │ │ ├── FIRExceptionModel.h
│ │ │ │ ├── FIRStackFrame.h
│ │ │ │ └── FirebaseCrashlytics.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── FirebaseDatabase.framework/
│ │ │ ├── FirebaseDatabase
│ │ │ ├── Headers/
│ │ │ │ ├── FIRDataEventType.h
│ │ │ │ ├── FIRDataSnapshot.h
│ │ │ │ ├── FIRDatabase.h
│ │ │ │ ├── FIRDatabaseQuery.h
│ │ │ │ ├── FIRDatabaseReference.h
│ │ │ │ ├── FIRMutableData.h
│ │ │ │ ├── FIRServerValue.h
│ │ │ │ ├── FIRTransactionResult.h
│ │ │ │ └── FirebaseDatabase.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── FirebaseInstallations.framework/
│ │ │ ├── FirebaseInstallations
│ │ │ ├── Headers/
│ │ │ │ ├── FIRInstallations.h
│ │ │ │ ├── FIRInstallationsAuthTokenResult.h
│ │ │ │ ├── FIRInstallationsErrors.h
│ │ │ │ └── FirebaseInstallations.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── GoogleDataTransport.framework/
│ │ │ ├── GoogleDataTransport
│ │ │ ├── Headers/
│ │ │ │ ├── GDTCORClock.h
│ │ │ │ ├── GDTCORConsoleLogger.h
│ │ │ │ ├── GDTCOREndpoints.h
│ │ │ │ ├── GDTCOREvent.h
│ │ │ │ ├── GDTCOREventDataObject.h
│ │ │ │ ├── GDTCOREventTransformer.h
│ │ │ │ ├── GDTCORTargets.h
│ │ │ │ ├── GDTCORTransport.h
│ │ │ │ └── GoogleDataTransport.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── GoogleUtilities.framework/
│ │ │ ├── GoogleUtilities
│ │ │ ├── Headers/
│ │ │ │ ├── GULAppDelegateSwizzler.h
│ │ │ │ ├── GULAppEnvironmentUtil.h
│ │ │ │ ├── GULApplication.h
│ │ │ │ ├── GULHeartbeatDateStorable.h
│ │ │ │ ├── GULHeartbeatDateStorage.h
│ │ │ │ ├── GULHeartbeatDateStorageUserDefaults.h
│ │ │ │ ├── GULKeychainStorage.h
│ │ │ │ ├── GULKeychainUtils.h
│ │ │ │ ├── GULLogger.h
│ │ │ │ ├── GULLoggerLevel.h
│ │ │ │ ├── GULMutableDictionary.h
│ │ │ │ ├── GULNSData+zlib.h
│ │ │ │ ├── GULNetwork.h
│ │ │ │ ├── GULNetworkConstants.h
│ │ │ │ ├── GULNetworkLoggerProtocol.h
│ │ │ │ ├── GULNetworkMessageCode.h
│ │ │ │ ├── GULNetworkURLSession.h
│ │ │ │ ├── GULReachabilityChecker.h
│ │ │ │ ├── GULSceneDelegateSwizzler.h
│ │ │ │ ├── GULSecureCoding.h
│ │ │ │ ├── GULURLSessionDataResponse.h
│ │ │ │ ├── GULUserDefaults.h
│ │ │ │ ├── GoogleUtilities-umbrella.h
│ │ │ │ └── NSURLSession+GULPromises.h
│ │ │ ├── Info.plist
│ │ │ └── Modules/
│ │ │ └── module.modulemap
│ │ ├── PromisesObjC.framework/
│ │ │ ├── Headers/
│ │ │ │ ├── FBLPromise+All.h
│ │ │ │ ├── FBLPromise+Always.h
│ │ │ │ ├── FBLPromise+Any.h
│ │ │ │ ├── FBLPromise+Async.h
│ │ │ │ ├── FBLPromise+Await.h
│ │ │ │ ├── FBLPromise+Catch.h
│ │ │ │ ├── FBLPromise+Delay.h
│ │ │ │ ├── FBLPromise+Do.h
│ │ │ │ ├── FBLPromise+Race.h
│ │ │ │ ├── FBLPromise+Recover.h
│ │ │ │ ├── FBLPromise+Reduce.h
│ │ │ │ ├── FBLPromise+Retry.h
│ │ │ │ ├── FBLPromise+Testing.h
│ │ │ │ ├── FBLPromise+Then.h
│ │ │ │ ├── FBLPromise+Timeout.h
│ │ │ │ ├── FBLPromise+Validate.h
│ │ │ │ ├── FBLPromise+Wrap.h
│ │ │ │ ├── FBLPromise.h
│ │ │ │ ├── FBLPromiseError.h
│ │ │ │ ├── FBLPromises.h
│ │ │ │ └── PromisesObjC-umbrella.h
│ │ │ ├── Info.plist
│ │ │ ├── Modules/
│ │ │ │ └── module.modulemap
│ │ │ └── PromisesObjC
│ │ ├── leveldb-library.framework/
│ │ │ ├── Headers/
│ │ │ │ ├── c.h
│ │ │ │ ├── cache.h
│ │ │ │ ├── comparator.h
│ │ │ │ ├── db.h
│ │ │ │ ├── dumpfile.h
│ │ │ │ ├── env.h
│ │ │ │ ├── export.h
│ │ │ │ ├── filter_policy.h
│ │ │ │ ├── iterator.h
│ │ │ │ ├── leveldb-library-umbrella.h
│ │ │ │ ├── options.h
│ │ │ │ ├── slice.h
│ │ │ │ ├── status.h
│ │ │ │ ├── table.h
│ │ │ │ ├── table_builder.h
│ │ │ │ └── write_batch.h
│ │ │ ├── Info.plist
│ │ │ ├── Modules/
│ │ │ │ └── module.modulemap
│ │ │ └── leveldb-library
│ │ └── nanopb.framework/
│ │ ├── Headers/
│ │ │ ├── nanopb-umbrella.h
│ │ │ ├── pb.h
│ │ │ ├── pb_common.h
│ │ │ ├── pb_decode.h
│ │ │ └── pb_encode.h
│ │ ├── Info.plist
│ │ ├── Modules/
│ │ │ └── module.modulemap
│ │ └── nanopb
│ ├── GoogleService-Info.plist
│ ├── Keys.plist.example
│ ├── Media.xcassets/
│ │ ├── Accent Color.colorset/
│ │ │ └── Contents.json
│ │ ├── Add Icon/
│ │ │ ├── Add Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Add Highlighted.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Add Icon.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Add White.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Calendar Icon Remove/
│ │ │ ├── Contents.json
│ │ │ ├── Remove Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Remove.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── WhiteRemove.imageset/
│ │ │ └── Contents.json
│ │ ├── Clocker Icon/
│ │ │ ├── ClockerIcon-512.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Extra Options/
│ │ │ ├── Contents.json
│ │ │ ├── Extra Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Extra.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ExtraHighlighted Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ExtraHighlighted.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ExtraWhite.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── ExtraWhiteHighlighted.imageset/
│ │ │ └── Contents.json
│ │ ├── Location/
│ │ │ ├── Contents.json
│ │ │ ├── CurrentLocation.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── CurrentLocationDynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── CurrentLocationWhite.imageset/
│ │ │ └── Contents.json
│ │ ├── Menubar Icons/
│ │ │ ├── Contents.json
│ │ │ └── LightModeIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── Onboarding/
│ │ │ ├── Contents.json
│ │ │ ├── Dark Menubar.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Dynamic Menubar.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Light Menubar.imageset/
│ │ │ └── Contents.json
│ │ ├── Pin/
│ │ │ ├── Contents.json
│ │ │ ├── Float-White.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Float.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Pin.imageset/
│ │ │ └── Contents.json
│ │ ├── Power Icon/
│ │ │ ├── Contents.json
│ │ │ ├── Power.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── PowerIcon-White.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── PowerIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── Preferences Toolbar.imageset/
│ │ │ └── Contents.json
│ │ ├── Privacy/
│ │ │ ├── Contents.json
│ │ │ ├── Privacy Dark.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Privacy Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Privacy.imageset/
│ │ │ └── Contents.json
│ │ ├── Settings/
│ │ │ ├── Contents.json
│ │ │ ├── Settings-White.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Settings.imageset/
│ │ │ └── Contents.json
│ │ ├── Sharing/
│ │ │ ├── Contents.json
│ │ │ ├── Sharing Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Sharing.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── SharingDarkIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── Sunrise/
│ │ │ ├── Contents.json
│ │ │ ├── Sunrise Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Sunrise.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Sunset Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Sunset.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── WhiteSunrise.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── WhiteSunset.imageset/
│ │ │ └── Contents.json
│ │ ├── Tabs/
│ │ │ ├── Appearance Dark.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Appearance Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Appearance.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Calendar Tab Dark.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Calendar Tab Dynamic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Calendar Tab Icon.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Trash.imageset/
│ │ └── Contents.json
│ ├── Menu Bar/
│ │ ├── MenubarHandler.swift
│ │ ├── StatusContainerView.swift
│ │ ├── StatusItemHandler.swift
│ │ └── StatusItemView.swift
│ ├── Onboarding/
│ │ ├── FinalOnboardingViewController.swift
│ │ ├── Onboarding.storyboard
│ │ ├── OnboardingController.swift
│ │ ├── OnboardingParentViewController.swift
│ │ ├── OnboardingPermissionsViewController.swift
│ │ ├── OnboardingSearchController.swift
│ │ ├── OnboardingWelcomeViewController.swift
│ │ ├── StartAtLoginViewController.swift
│ │ └── WelcomeView.xib
│ ├── Overall App/
│ │ ├── AppDefaults.swift
│ │ ├── AppKit + Additions.swift
│ │ ├── ConfigExport.swift
│ │ ├── DataStore.swift
│ │ ├── DateFormatterManager.swift
│ │ ├── Foundation + Additions.swift
│ │ ├── NetworkManager.swift
│ │ ├── Reach.swift
│ │ ├── String + Additions.swift
│ │ ├── Strings.swift
│ │ ├── Themer.swift
│ │ ├── Timer.swift
│ │ ├── UserDefaults + KVOExtensions.swift
│ │ └── VersionUpdateHandler.swift
│ ├── Panel/
│ │ ├── Data Layer/
│ │ │ └── TimezoneDataOperations.swift
│ │ ├── FloatingWindowController.swift
│ │ ├── Notes Popover/
│ │ │ ├── NotesPopover.swift
│ │ │ ├── NotesPopover.xib
│ │ │ └── TextViewWithPlaceholder.swift
│ │ ├── PanelController.swift
│ │ ├── ParentPanelController+ModernSlider.swift
│ │ ├── ParentPanelController.swift
│ │ ├── Rate Controller/
│ │ │ ├── ReviewController.swift
│ │ │ └── UpcomingEventView.swift
│ │ ├── UI/
│ │ │ ├── AddTableViewCell.swift
│ │ │ ├── BackgroundPanelView.swift
│ │ │ ├── CustomSliderCell.swift
│ │ │ ├── FloatingWindow.xib
│ │ │ ├── HourMarkerViewItem.xib
│ │ │ ├── NoTimezoneView.swift
│ │ │ ├── PanelTableView.swift
│ │ │ ├── Panelr.swift
│ │ │ ├── TimeMarkerViewItem.swift
│ │ │ ├── TimezoneCellView.swift
│ │ │ ├── TimezoneDataSource.swift
│ │ │ └── Toasty.swift
│ │ └── Upcoming Events/
│ │ ├── ParentPanelController+UpcomingEvents.swift
│ │ ├── UpcomingEventViewItem.swift
│ │ ├── UpcomingEventViewItem.xib
│ │ └── UpcomingEventsDataSource.swift
│ ├── Preferences/
│ │ ├── About/
│ │ │ ├── AboutViewController.swift
│ │ │ └── PointingHandCursorButton.swift
│ │ ├── App Feedback/
│ │ │ ├── AppFeedbackWindow.xib
│ │ │ └── AppFeedbackWindowController.swift
│ │ ├── Appearance/
│ │ │ └── AppearanceViewController.swift
│ │ ├── Calendar/
│ │ │ └── CalendarViewController.swift
│ │ ├── General/
│ │ │ ├── PreferencesDataSource.swift
│ │ │ ├── PreferencesViewController.swift
│ │ │ └── SearchDataSource.swift
│ │ ├── Menu Bar/
│ │ │ ├── MenubarTitleProvider.swift
│ │ │ ├── StatusContainerView.swift
│ │ │ ├── StatusItemHandler.swift
│ │ │ ├── StatusItemView.swift
│ │ │ └── UpcomingEventStatusItemView.swift
│ │ ├── OneWindowController.swift
│ │ ├── ParentViewController.swift
│ │ ├── Permissions/
│ │ │ └── PermissionsViewController.swift
│ │ ├── Preferences.storyboard
│ │ └── StartupManager.swift
│ ├── Releases/
│ │ ├── appcast.xml
│ │ └── changelog.md
│ ├── StartupKit/
│ │ ├── .gitignore
│ │ ├── Package.swift
│ │ ├── README.md
│ │ └── Sources/
│ │ └── StartupKit/
│ │ └── StartupManager.swift
│ ├── release.py
│ ├── run
│ └── upload-symbols
├── Readme.md
└── swiftlint-install.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: n0shake
================================================
FILE: .gitignore
================================================
*.xcuserstate
.DS_Store
.DS_Store
Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishek_banthia.xcuserdatad/UserInterfaceState.xcuserstate
Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
*.xcuserstate
.DS_Store
**/Keys.plist
================================================
FILE: .swiftformat
================================================
--disable
================================================
FILE: .swiftlint.yml
================================================
disabled_rules: # rule identifiers to exclude from running
- type_body_length
- file_length
- type_name
- variable_name
- nesting
opt_in_rules: # some rules are only opt-in
- empty_count
# included: # paths to include during linting. `--path` is ignored if present.
# - Clocker
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Clocker/Dependencies
- Clocker/ClockerUnitTests
- Clocker/ClockerUITests
# - Pods
# - Source/ExcludedFolder
# - Source/ExcludedFile.swift
# - Source/*/ExcludedFile.swift # Exclude files with a wildcard
analyzer_rules: # Rules run by `swiftlint analyze` (experimental)
- explicit_self
# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
force_try:
severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length: 200
# they can set both implicitly with an array
type_body_length:
- 300 # warning
- 400 # error
# or they can set both explicitly
file_length:
warning: 500
error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
min_length: 3 # only warning
max_length: # warning and error
warning: 40
error: 50
excluded: iPhone # excluded via string
identifier_name:
min_length: # only min_length
error: 3 # only error
# excluded: # excluded via string array
# - id
# - URL
# - GlobalAPIKey
reporter: "xcode"
================================================
FILE: .travis.yml
================================================
os: osx
language: swift
xcode_project: Clocker.xcodeproj # path to your xcodeproj folder
osx_image: xcode12.2
before_install:
- export TZ=America/Chicago
before_script:
- xcodebuild -version
install:
- ./swiftlint-install.sh
script:
- set -o pipefail && env "NSUnbufferedIO=YES"
- pwd
- swiftlint
- xcodebuild -project Clocker/Clocker.xcodeproj -scheme Clocker build analyze CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY= | xcpretty
- xcodebuild -project Clocker/Clocker.xcodeproj -scheme Clocker test CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY= | xcpretty
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Clocker is a macOS menu bar utility (Swift 5, AppKit) that helps users track time across different time zones. It's a native macOS app targeting Sierra 10.12+, distributed via the Mac App Store and Homebrew.
## Build & Test Commands
```bash
# Build
xcodebuild -project Clocker/Clocker.xcodeproj -scheme Clocker build
# Lint
swiftlint lint --path Clocker/Clocker
# Lint with analyzer rules (requires build)
swiftlint analyze --compiler-log-path build/CompileSwift.log
```
The project uses Xcode directly — open `Clocker/Clocker.xcodeproj` for day-to-day development.
## Verification Policy
**Only build to verify changes — never run unit tests.** Use `xcodebuild ... build` to confirm the project compiles. Tests must be run manually from within Xcode.
Unit tests via `xcodebuild ... test` launch the full app host process, which can produce misleading fatal errors unrelated to the change under review. UI tests cannot be run via xcodebuild at all due to a code signing Team ID mismatch between the app and the UI test runner bundle.
## Architecture
### Module Structure
The app is split into the main `Clocker` target plus three Swift packages:
- **CoreModelKit** — data models (`TimezoneData`, `SearchResults`, etc.)
- **CoreLoggerKit** — centralized logging
- **StartupKit** — app initialization/startup orchestration
### Feature Modules (inside `Clocker/Clocker/`)
| Directory | Purpose |
|-----------|---------|
| `Overall App/` | App-wide services: `DataStore`, `AppDefaults`, `Themer`, `DateFormatterManager`, `NetworkManager` |
| `Menu Bar/` | `StatusItemHandler`, `MenubarHandler` — manages the menu bar status item |
| `Panel/` | Main UI panel: `ParentPanelController` (primary controller), `PanelController`, `FloatingWindowController`, `TimezoneDataSource`, `TimezoneDataOperations` |
| `Preferences/` | Settings UI split into General, Appearance, Menu Bar, Calendar, and About sub-controllers |
| `Onboarding/` | First-run flow: search, permissions, start-at-login, and final screens |
| `Events and Reminders/` | `EventCenter`, `CalendarHandler`, `RemindersHandler` for OS calendar/reminder integration |
### Key Data Flow
```
AppDelegate
└── StatusItemHandler (menu bar)
└── PanelController / FloatingWindowController
└── ParentPanelController
├── TimezoneDataSource ←→ DataStore (UserDefaults)
└── UpcomingEventsDataSource ←→ EventCenter
```
`DataStore` is the single source of truth for persisted timezone list and settings; it wraps `UserDefaults` and is accessed throughout the app as a shared instance.
### Panel vs. Floating Window
The app has two display modes controlled by a user preference:
- **Panel** (`PanelController`) — anchored to the menu bar item
- **Floating Window** (`FloatingWindowController`) — free-floating, always-on-top window
Both share `ParentPanelController` for the core UI logic (time display, slider scrubbing, upcoming events).
### Theming
`Themer.swift` manages light/dark/system appearance. UI components observe `Themer` notifications to update colors. Always use `Themer` for colors rather than hardcoded values.
## SwiftLint Configuration
Line length limit: 200. `explicit_self` is enforced via the analyzer rules. Tests and `Dependencies/` are excluded from linting.
## Release Process
`release.py` automates version bumping (`agvtool`), clean build+analyze, test run, and GitHub release creation. Firebase Crashlytics is integrated for crash reporting in Release builds only.
================================================
FILE: Clocker/AppDelegate.swift
================================================
// Copyright © 2015 Abhishek Banthia
import Cocoa
import CoreLoggerKit
import CoreModelKit
import FirebaseCore
import FirebaseCrashlytics
open class AppDelegate: NSObject, NSApplicationDelegate {
private lazy var floatingWindow = FloatingWindowController.shared()
internal lazy var panelController = PanelController(windowNibName: .panel)
private var statusBarHandler: StatusItemHandler!
// TODO: Replace iVersion with this!
// private let versionUpdateHandler: VersionUpdateHandler = VersionUpdateHandler(with: DataStore.shared())
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
if let path = keyPath, path == PreferencesConstants.hotKeyPathIdentifier {
let hotKeyCenter = PTHotKeyCenter.shared()
// Unregister old hot key
let oldHotKey = hotKeyCenter?.hotKey(withIdentifier: path)
hotKeyCenter?.unregisterHotKey(oldHotKey)
// We don't register unless there's a valid key combination
guard let newObject = object as? NSObject, let newShortcut = newObject.value(forKeyPath: path) as? [AnyHashable: Any] else {
return
}
// Register new key
let newHotKey = PTHotKey(identifier: keyPath,
keyCombo: newShortcut,
target: self,
action: #selector(ping(_:)))
hotKeyCenter?.register(newHotKey)
}
}
public func applicationDidFinishLaunching(_: Notification) {
AppDefaults.initialize(with: DataStore.shared(), defaults: UserDefaults.standard)
// Check if we can show the onboarding flow!
showOnboardingFlowIfEligible()
// Ratings Controller initialization
ReviewController.applicationDidLaunch(UserDefaults.standard)
#if RELEASE
FirebaseApp.configure()
checkIfRunFromApplicationsFolder()
#endif
}
public func applicationWillFinishLaunching(_: Notification) {
iVersion.sharedInstance().useAllAvailableLanguages = true
iVersion.sharedInstance().verboseLogging = false
}
public func applicationDockMenu(_: NSApplication) -> NSMenu? {
let menu = NSMenu(title: "Quick Access")
let toggleMenuItem = NSMenuItem(title: "Toggle Panel", action: #selector(AppDelegate.togglePanel(_:)), keyEquivalent: "")
let openPreferences = NSMenuItem(title: "Settings", action: #selector(AppDelegate.openPreferencesWindow), keyEquivalent: ",")
let hideFromDockMenuItem = NSMenuItem(title: "Hide from Dock", action: #selector(AppDelegate.hideFromDock), keyEquivalent: "")
[toggleMenuItem, openPreferences, hideFromDockMenuItem].forEach {
$0.isEnabled = true
menu.addItem($0)
}
return menu
}
@objc private func openPreferencesWindow() {
let displayMode = DataStore.shared().shouldDisplay(.showAppInForeground)
if displayMode {
let floatingWindow = FloatingWindowController.shared()
floatingWindow.openPreferences(NSButton())
} else {
panelController.openPreferences(NSButton())
}
}
@objc func hideFromDock() {
UserDefaults.standard.set(0, forKey: UserDefaultKeys.appDisplayOptions)
NSApp.setActivationPolicy(.accessory)
}
private var controller: OnboardingController?
private func showOnboardingFlowIfEligible() {
let isTestInProgress = ProcessInfo.processInfo.arguments.contains(UserDefaultKeys.onboardingTestsLaunchArgument)
let shouldLaunchOnboarding =
(DataStore.shared().retrieve(key: UserDefaultKeys.showOnboardingFlow) == nil
&& DataStore.shared().timezones().isEmpty)
|| isTestInProgress
if shouldLaunchOnboarding {
let onboardingStoryboard = NSStoryboard(name: NSStoryboard.Name("Onboarding"), bundle: nil)
controller = onboardingStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController
controller?.launch()
} else {
continueUsually()
}
}
func continueUsually() {
// Cleanup onboarding controller after its done!
if controller != nil {
controller = nil
}
// Check if another instance of the app is already running. If so, then stop this one.
checkIfAppIsAlreadyOpen()
// Install the menubar item!
statusBarHandler = StatusItemHandler(with: DataStore.shared())
if ProcessInfo.processInfo.arguments.contains(UserDefaultKeys.testingLaunchArgument) {
FirebaseApp.configure()
ReviewController.setPreviewMode(true)
}
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
assignShortcut()
let defaults = UserDefaults.standard
setActivationPolicy()
// Set the display mode default as panel!
if let displayMode = defaults.object(forKey: UserDefaultKeys.showAppInForeground) as? NSNumber, displayMode.intValue == 1 {
showFloatingWindow()
} else if let displayMode = defaults.object(forKey: UserDefaultKeys.showAppInForeground) as? Int, displayMode == 1 {
showFloatingWindow()
}
}
// Should we have a dock icon or just stay in the menubar?
private func setActivationPolicy() {
let defaults = UserDefaults.standard
let currentActivationPolicy = NSRunningApplication.current.activationPolicy
let activationPolicy: NSApplication.ActivationPolicy = defaults.integer(forKey: UserDefaultKeys.appDisplayOptions) == 0 ? .accessory : .regular
if currentActivationPolicy != activationPolicy {
NSApp.setActivationPolicy(activationPolicy)
}
}
private func checkIfAppIsAlreadyOpen() {
guard let bundleID = Bundle.main.bundleIdentifier else {
return
}
let apps = NSRunningApplication.runningApplications(withBundleIdentifier: bundleID)
if apps.count > 1 {
let currentApplication = NSRunningApplication.current
for app in apps where app != currentApplication {
app.terminate()
}
}
}
private func showAlert(message: String, informativeText: String, buttonTitle: String) {
NSApplication.shared.activate(ignoringOtherApps: true)
let alert = NSAlert()
alert.messageText = message
alert.informativeText = informativeText
alert.addButton(withTitle: buttonTitle)
alert.runModal()
}
@IBAction func ping(_ sender: NSButton) {
if let statusItemButton = statusBarHandler.statusItem.button {
statusItemButton.state = statusItemButton.state == .on ? .off : .on
togglePanel(statusItemButton)
}
}
private func retrieveLatestLocation() {
let locationController = LocationController(withStore: DataStore.shared())
locationController.determineAndRequestLocationAuthorization()
}
private func showFloatingWindow() {
// Display the Floating Window!
floatingWindow.showWindow(nil)
floatingWindow.updateTableContent()
floatingWindow.startWindowTimer()
NSApp.activate(ignoringOtherApps: true)
}
private func assignShortcut() {
NSUserDefaultsController.shared.addObserver(self,
forKeyPath: PreferencesConstants.hotKeyPathIdentifier,
options: [.initial, .new],
context: nil)
}
private func checkIfRunFromApplicationsFolder() {
if let shortCircuit = UserDefaults.standard.object(forKey: "AllowOutsideApplicationsFolder") as? Bool, shortCircuit == true {
return
}
let bundlePath = Bundle.main.bundlePath
let applicationDirectory = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationDirectory,
FileManager.SearchPathDomainMask.localDomainMask,
true)
for appDir in applicationDirectory {
if bundlePath.hasPrefix(appDir) {
return
}
}
let informativeText = """
Clocker must be run from the Applications folder in order to work properly.
Please quit Clocker, move it to the Applications folder, and relaunch.
Current folder: \(applicationDirectory)"
"""
// Clocker is installed out of Applications directory
// This breaks start at login! Time to show an alert and terminate
showAlert(message: "Move Clocker to the Applications folder",
informativeText: informativeText,
buttonTitle: "Quit")
// Terminate
NSApp.terminate(nil)
}
@IBAction open func togglePanel(_ sender: NSButton) {
Logger.info("Toggle Panel called with sender state \(sender.state.rawValue)")
let displayMode = UserDefaults.standard.integer(forKey: UserDefaultKeys.showAppInForeground)
if displayMode == 1 {
// No need to call NSApp.activate here since `showFloatingWindow` takes care of this
showFloatingWindow()
} else {
panelController.showWindow(nil)
panelController.setActivePanel(newValue: sender.state == .on)
NSApp.activate(ignoringOtherApps: true)
}
}
open func setupFloatingWindow(_ hide: Bool) {
hide ? floatingWindow.window?.close() : showFloatingWindow()
}
func statusItemForPanel() -> StatusItemHandler {
return statusBarHandler
}
open func setupMenubarTimer() {
statusBarHandler.setupStatusItem()
}
open func invalidateMenubarTimer(_ showIcon: Bool) {
statusBarHandler.invalidateTimer(showIcon: showIcon, isSyncing: true)
}
}
================================================
FILE: Clocker/Clocker/Clocker-Info.plist
================================================
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
Clocker - World Clock
CFBundlePackageType
APPL
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleSignature
????
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
ITSAppUsesNonExemptEncryption
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
${MACOSX_DEPLOYMENT_TARGET}
LSUIElement
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSCalendarsUsageDescription
Clocker can be more useful when it can display upcoming events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy
NSHumanReadableCopyright
Copyright © 2024, Abhishek Banthia
NSLocationAlwaysAndWhenInUseUsageDescription
Clocker can be more useful when it can use your location to determine your current timezone.
NSLocationUsageDescription
Clocker can be more useful when it can use your location to determine your current timezone.
NSMainNibFile
MainMenu
NSPrincipalClass
NSApplication
NSRemindersUsageDescription
Clocker can be more useful when it can set reminders for your selected timezone(s). You can change this setting in System Preferences › Security & Privacy › Privacy.
NSSupportsAutomaticGraphicsSwitching
RequestsOpenAccess
YES
================================================
FILE: Clocker/Clocker/Clocker-Prefix.pch
================================================
//
// Prefix header for all source files of the 'Clocker' target in the 'Clocker' project
//
#ifdef __OBJC__
#import
#endif
================================================
FILE: Clocker/Clocker/Clocker.entitlements
================================================
com.apple.security.app-sandbox
com.apple.security.cs.disable-library-validation
com.apple.security.network.client
com.apple.security.personal-information.calendars
com.apple.security.temporary-exception.apple-events
com.apple.reminders
================================================
FILE: Clocker/Clocker/LocationController.swift
================================================
// Copyright © 2015 Abhishek Banthia
import Cocoa
import CoreLocation
import CoreLoggerKit
import CoreModelKit
protocol LocationControllerDelegate: NSObject {
func didChangeAuthorizationStatus()
}
class LocationController: NSObject {
private let store: DataStore
init(withStore dataStore: DataStore) {
store = dataStore
super.init()
}
private var locationManager: CLLocationManager = {
let locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
return locationManager
}()
func authorizationStatus() -> CLAuthorizationStatus {
return locationManager.authorizationStatus
}
func locationAccessNotDetermined() -> Bool {
return locationManager.authorizationStatus == .notDetermined
}
func locationAccessGranted() -> Bool {
print("Location Status is ", locationManager.authorizationStatus.rawValue.description)
return locationManager.authorizationStatus == .authorizedAlways || locationManager.authorizationStatus == .authorized
}
func locationAccessDenied() -> Bool {
return locationManager.authorizationStatus == .restricted || locationManager.authorizationStatus == .denied
}
func setDelegate() {
locationManager.delegate = self
}
func determineAndRequestLocationAuthorization() {
setDelegate()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
switch authorizationStatus() {
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .notDetermined:
locationManager.startUpdatingLocation()
case .denied, .restricted:
locationManager.startUpdatingLocation()
default:
fatalError("Unexpected Authorization Status")
}
}
private func updateHomeObject(with customLabel: String, coordinates: CLLocationCoordinate2D?) {
let timezones = store.timezones()
var timezoneObjects: [TimezoneData] = []
for timezone in timezones {
if let model = TimezoneData.customObject(from: timezone) {
timezoneObjects.append(model)
}
}
for timezoneObject in timezoneObjects where timezoneObject.isSystemTimezone == true {
timezoneObject.setLabel(customLabel)
if let latlong = coordinates {
timezoneObject.longitude = latlong.longitude
timezoneObject.latitude = latlong.latitude
}
}
var datas: [Data] = []
for updatedObject in timezoneObjects {
guard let dataObject = NSKeyedArchiver.clocker_archive(with: updatedObject) else {
continue
}
datas.append(dataObject)
}
store.setTimezones(datas)
}
}
extension LocationController: CLLocationManagerDelegate {
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard !locations.isEmpty, let coordinates = locations.first?.coordinate else { return }
let reverseGeoCoder = CLGeocoder()
reverseGeoCoder.reverseGeocodeLocation(locations[0]) { placemarks, _ in
guard let customLabel = placemarks?.first?.locality else { return }
self.updateHomeObject(with: customLabel, coordinates: coordinates)
self.locationManager.stopUpdatingLocation()
}
}
func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .denied || status == .restricted {
updateHomeObject(with: TimeZone.autoupdatingCurrent.identifier, coordinates: nil)
locationManager.stopUpdatingLocation()
} else if status == .notDetermined || status == .authorized || status == .authorizedAlways {
locationManager.startUpdatingLocation()
}
}
func locationManager(_: CLLocationManager, didFailWithError error: Error) {
Logger.info(error.localizedDescription)
}
}
================================================
FILE: Clocker/Clocker/MainMenu.xib
================================================
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/.gitignore
================================================
# Xcode
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
## Ignore incredibly annoying .DS_Store files
.DS_Store
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/LICENSE.md
================================================
# ShortcutRecorder
Copyright (c) 2006, Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the organization nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# PTHotKey
Copyright (c) 2003 Quentin D. Carnicelli.
All rights reserved.
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/Info.plist
================================================
CFBundleDevelopmentRegion
English
CFBundleExecutable
ShortcutRecorder
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
FMWK
CFBundleShortVersionString
2.17
CFBundleSignature
????
CFBundleVersion
2.17
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/Prefix.pch
================================================
#ifdef __OBJC__
#import
#import
#endif
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.h
================================================
//
// SRCommon.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Ilya Kulakov
#import
#import
/*!
Mask representing subset of Cocoa modifier flags suitable for shortcuts.
*/
static const NSEventModifierFlags SRCocoaModifierFlagsMask = NSEventModifierFlagCommand | NSEventModifierFlagOption | NSEventModifierFlagShift | NSEventModifierFlagControl;
/*!
Mask representing subset of Carbon modifier flags suitable for shortcuts.
*/
static const NSUInteger SRCarbonModifierFlagsMask = cmdKey | optionKey | shiftKey | controlKey;
/*!
Converts carbon modifier flags to cocoa.
*/
FOUNDATION_STATIC_INLINE NSEventModifierFlags SRCarbonToCocoaFlags(UInt32 aCarbonFlags)
{
NSEventModifierFlags cocoaFlags = 0;
if (aCarbonFlags & cmdKey)
cocoaFlags |= NSEventModifierFlagCommand;
if (aCarbonFlags & optionKey)
cocoaFlags |= NSEventModifierFlagOption;
if (aCarbonFlags & controlKey)
cocoaFlags |= NSEventModifierFlagControl;
if (aCarbonFlags & shiftKey)
cocoaFlags |= NSEventModifierFlagShift;
return cocoaFlags;
}
/*!
Converts cocoa modifier flags to carbon.
*/
FOUNDATION_STATIC_INLINE UInt32 SRCocoaToCarbonFlags(NSEventModifierFlags aCocoaFlags)
{
UInt32 carbonFlags = 0;
if (aCocoaFlags & NSEventModifierFlagCommand)
carbonFlags |= cmdKey;
if (aCocoaFlags & NSEventModifierFlagOption)
carbonFlags |= optionKey;
if (aCocoaFlags & NSEventModifierFlagControl)
carbonFlags |= controlKey;
if (aCocoaFlags & NSEventModifierFlagShift)
carbonFlags |= shiftKey;
return carbonFlags;
}
/*!
Return Bundle where resources can be found.
@discussion Throws NSInternalInconsistencyException if bundle cannot be found.
*/
NSBundle *SRBundle(void);
/*!
Convenient method to get localized string from the framework bundle.
*/
NSString *SRLoc(NSString *aKey);
/*!
Convenient method to get image from the framework bundle.
*/
NSImage *SRImage(NSString *anImageName);
/*!
Returns string representation of shortcut with modifier flags replaced with their localized
readable equivalents (e.g. ? -> Option).
*/
NSString *SRReadableStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode);
/*!
Returns string representation of shortcut with modifier flags replaced with their localized
readable equivalents (e.g. ? -> Option) and ASCII character for key code.
*/
NSString *SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode);
/*!
Determines if given key code with flags is equal to key equivalent and flags
(usually taken from NSButton or NSMenu).
@discussion On Mac OS X some key combinations can have "alternates". E.g. option-A can be represented both as option-A and as .
*/
BOOL SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags);
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.m
================================================
//
// SRCommon.m
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Ilya Kulakov
#import "SRCommon.h"
#import "SRKeyCodeTransformer.h"
NSBundle *SRBundle(void)
{
static dispatch_once_t onceToken;
static NSBundle *Bundle = nil;
dispatch_once(&onceToken, ^{
Bundle = [NSBundle bundleWithIdentifier:@"com.kulakov.ShortcutRecorder"];
if (!Bundle)
{
// Could be a CocoaPods framework with embedded resources bundle.
// Look up "use_frameworks!" and "resources_bundle" in CocoaPods documentation.
Bundle = [NSBundle bundleWithIdentifier:@"org.cocoapods.ShortcutRecorder"];
if (!Bundle)
{
Class c = NSClassFromString(@"SRRecorderControl");
if (c)
{
Bundle = [NSBundle bundleForClass:c];
}
}
if (Bundle)
{
Bundle = [NSBundle bundleWithPath:[Bundle pathForResource:@"ShortcutRecorder" ofType:@"bundle"]];
}
}
});
if (!Bundle)
{
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:@"Unable to find bundle with resources."
userInfo:nil];
}
else
{
return Bundle;
}
}
NSString *SRLoc(NSString *aKey)
{
return NSLocalizedStringFromTableInBundle(aKey, @"ShortcutRecorder", SRBundle(), nil);
}
NSImage *SRImage(NSString *anImageName)
{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
return [[NSImage alloc] initByReferencingURL:[SRBundle() URLForImageResource:anImageName]];
else
return [SRBundle() imageForResource:anImageName];
}
NSString *SRReadableStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedPlainTransformer];
NSString *c = [t transformedValue:@(aKeyCode)];
return [NSString stringWithFormat:@"%@%@%@%@%@",
(aModifierFlags & NSEventModifierFlagCommand ? SRLoc(@"Command-") : @""),
(aModifierFlags & NSEventModifierFlagOption ? SRLoc(@"Option-") : @""),
(aModifierFlags & NSEventModifierFlagControl ? SRLoc(@"Control-") : @""),
(aModifierFlags & NSEventModifierFlagShift ? SRLoc(@"Shift-") : @""),
c];
}
NSString *SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedPlainASCIITransformer];
NSString *c = [t transformedValue:@(aKeyCode)];
return [NSString stringWithFormat:@"%@%@%@%@%@",
(aModifierFlags & NSEventModifierFlagCommand ? SRLoc(@"Command-") : @""),
(aModifierFlags & NSEventModifierFlagOption ? SRLoc(@"Option-") : @""),
(aModifierFlags & NSEventModifierFlagControl ? SRLoc(@"Control-") : @""),
(aModifierFlags & NSEventModifierFlagShift ? SRLoc(@"Shift-") : @""),
c];
}
static BOOL _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags,
SRKeyCodeTransformer *aTransformer)
{
if (!aKeyEquivalent)
return NO;
aKeyCodeFlags &= SRCocoaModifierFlagsMask;
aKeyEquivalentModifierFlags &= SRCocoaModifierFlagsMask;
if (aKeyCodeFlags == aKeyEquivalentModifierFlags)
{
NSString *keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:nil
explicitModifierFlags:@(aKeyCodeFlags)];
return [keyCodeRepresentation isEqual:aKeyEquivalent];
}
else if (!aKeyEquivalentModifierFlags ||
(aKeyCodeFlags & aKeyEquivalentModifierFlags) == aKeyEquivalentModifierFlags)
{
// Some key equivalent modifier flags can be implicitly set by using special unicode characters. E.g. insetead of opt-a.
// However all modifier flags explictily set in key equivalent MUST be also set in key code flags.
// E.g. ctrl-/ctrl-opt-a and /opt-a match this condition, but cmd-/ctrl-opt-a doesn't.
NSString *keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:nil
explicitModifierFlags:@(aKeyCodeFlags)];
if ([keyCodeRepresentation isEqual:aKeyEquivalent])
{
// Key code and key equivalent are not equal key code representation matches key equivalent, but modifier flags are not.
return NO;
}
else
{
NSEventModifierFlags possiblyImplicitFlags = aKeyCodeFlags & ~aKeyEquivalentModifierFlags;
keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:@(possiblyImplicitFlags)
explicitModifierFlags:@(aKeyEquivalentModifierFlags)];
return [keyCodeRepresentation isEqual:aKeyEquivalent];
}
}
else
return NO;
}
BOOL SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags)
{
BOOL isEqual = _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode,
aKeyCodeFlags,
aKeyEquivalent,
aKeyEquivalentModifierFlags,
[SRKeyCodeTransformer sharedASCIITransformer]);
if (!isEqual)
{
isEqual = _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode,
aKeyCodeFlags,
aKeyEquivalent,
aKeyEquivalentModifierFlags,
[SRKeyCodeTransformer sharedTransformer]);
}
return isEqual;
}
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.h
================================================
//
// SRKeyCodeTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
// Silvio Rizzi
#import
#import
/*!
Transforms key code into unicode character or plain string.
*/
@interface SRKeyCodeTransformer : NSValueTransformer
/*!
Returns initialized key code transformer.
@param aUsesASCII Determines whether transformer uses only ASCII capable keyboard input source.
@param aUsesPlainStrings Determines whether key codes without readable glyphs (e.g. F1...F19) are transformed to
to unicode characters (NSF1FunctionKey...NSF19FunctionKey) suitable for setting key equivalents
of Cocoa controls or to plain strings (@"F1"...@"F19") suitable for drawing, logging and accessibility.
@discussion This method is the designated initializer for SRKeyCodeTransformer.
*/
- (instancetype)initWithASCIICapableKeyboardInputSource:(BOOL)aUsesASCII plainStrings:(BOOL)aUsesPlainStrings;
/*!
Determines whether transformer uses ASCII capable keyboard input source.
*/
@property (readonly) BOOL usesASCIICapableKeyboardInputSource;
/*!
Determines whether key codes without readable glyphs are transformed to unicode characters
suitable for setting keqEquivalents or to plain strings suitable for drawing, logging and accessibility.
*/
@property (readonly) BOOL usesPlainStrings;
/*!
Returns the shared transformer.
*/
+ (instancetype)sharedTransformer;
/*!
Returns the shared transformer configured to use only ASCII capable keyboard input source.
*/
+ (instancetype)sharedASCIITransformer;
/*!
Returns the shared transformer configured to transform key codes to plain strings.
*/
+ (SRKeyCodeTransformer *)sharedPlainTransformer;
/*!
Returns the shared transformer configured to use only ASCII capable keyboard input source
and to transform key codes to plain strings.
*/
+ (SRKeyCodeTransformer *)sharedPlainASCIITransformer;
/*!
Returns mapping from special key codes to unicode characters.
*/
+ (NSDictionary *)specialKeyCodesToUnicodeCharactersMapping;
/*!
Returns mapping from special key codes to plain strings.
*/
+ (NSDictionary *)specialKeyCodesToPlainStringsMapping;
/*!
Determines whether key code is special.
@param aKeyCode Key code to be checked.
*/
- (BOOL)isKeyCodeSpecial:(unsigned short)aKeyCode;
/*!
Transforms given special key code into unicode character by taking into account modifier flags.
@discussion E.g. the key code 0x30 is transformed to ⇥. But if shift is pressed, it is transformed to ⇤.
@result Unicode character or plain string. nil if not a special key code.
*/
- (NSString *)transformedSpecialKeyCode:(NSNumber *)aKeyCode withExplicitModifierFlags:(NSNumber *)aModifierFlags;
/*!
Shorcut to [self transformedValue:aValue withImplicitModifierFlags:aModifierFlags explicitModifierFlags:0]
*/
- (NSString *)transformedValue:(NSNumber *)aValue withModifierFlags:(NSNumber *)aModifierFlags;
/*!
Transfroms given key code into unicode character by taking into account modifier flags.
@param aValue An instance of NSNumber (unsigned short) that represents key code.
@param anImplicitModifierFlags An instance of NSNumber (NSEventModifierFlags) that represents implicit modifier flags like opt in å.
@param anExplicitModifierFlags An instance of NSNumber (NSEventModifierFlags) that represents explicit modifier flags like shift in shift-⇤.
*/
- (NSString *)transformedValue:(NSNumber *)aValue withImplicitModifierFlags:(NSNumber *)anImplicitModifierFlags explicitModifierFlags:(NSNumber *)anExplicitModifierFlags;
@end
/*!
These constants represents drawable unicode characters for key codes that do not have
appropriate constants in Carbon and Cocoa.
*/
typedef NS_ENUM(unichar, SRKeyCodeGlyph)
{
SRKeyCodeGlyphTabRight = 0x21E5, // ⇥
SRKeyCodeGlyphTabLeft = 0x21E4, // ⇤
SRKeyCodeGlyphReturn = 0x2305, // ⌅
SRKeyCodeGlyphReturnR2L = 0x21A9, // ↩
SRKeyCodeGlyphDeleteLeft = 0x232B, // ⌫
SRKeyCodeGlyphDeleteRight = 0x2326, // ⌦
SRKeyCodeGlyphPadClear = 0x2327, // ⌧
SRKeyCodeGlyphLeftArrow = 0x2190, // ←
SRKeyCodeGlyphRightArrow = 0x2192, // →
SRKeyCodeGlyphUpArrow = 0x2191, // ↑
SRKeyCodeGlyphDownArrow = 0x2193, // ↓
SRKeyCodeGlyphPageDown = 0x21DF, // ⇟
SRKeyCodeGlyphPageUp = 0x21DE, // ⇞
SRKeyCodeGlyphNorthwestArrow = 0x2196, // ↖
SRKeyCodeGlyphSoutheastArrow = 0x2198, // ↘
SRKeyCodeGlyphEscape = 0x238B, // ⎋
SRKeyCodeGlyphSpace = 0x0020, // ' '
};
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.m
================================================
//
// SRKeyCodeTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
// Silvio Rizzi
#import "SRKeyCodeTransformer.h"
#import "SRCommon.h"
FOUNDATION_STATIC_INLINE NSString* _SRUnicharToString(unichar aChar)
{
return [NSString stringWithFormat: @"%C", aChar];
}
@implementation SRKeyCodeTransformer
- (instancetype)initWithASCIICapableKeyboardInputSource:(BOOL)aUsesASCII plainStrings:(BOOL)aUsesPlainStrings
{
self = [super init];
if (self)
{
_usesASCIICapableKeyboardInputSource = aUsesASCII;
_usesPlainStrings = aUsesPlainStrings;
}
return self;
}
- (instancetype)init
{
return [self initWithASCIICapableKeyboardInputSource:NO plainStrings:NO];
}
#pragma mark Methods
+ (instancetype)sharedTransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:NO
plainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedASCIITransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:YES
plainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedPlainTransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:NO
plainStrings:YES];
});
return Transformer;
}
+ (SRKeyCodeTransformer *)sharedPlainASCIITransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:YES
plainStrings:YES];
});
return Transformer;
}
+ (NSDictionary *)specialKeyCodesToUnicodeCharactersMapping
{
// Most of these keys are system constans.
// Values for rest of the keys were given by setting key equivalents in IB.
static dispatch_once_t OnceToken;
static NSDictionary *Mapping = nil;
dispatch_once(&OnceToken, ^{
Mapping = @{
@(kVK_F1): _SRUnicharToString(NSF1FunctionKey),
@(kVK_F2): _SRUnicharToString(NSF2FunctionKey),
@(kVK_F3): _SRUnicharToString(NSF3FunctionKey),
@(kVK_F4): _SRUnicharToString(NSF4FunctionKey),
@(kVK_F5): _SRUnicharToString(NSF5FunctionKey),
@(kVK_F6): _SRUnicharToString(NSF6FunctionKey),
@(kVK_F7): _SRUnicharToString(NSF7FunctionKey),
@(kVK_F8): _SRUnicharToString(NSF8FunctionKey),
@(kVK_F9): _SRUnicharToString(NSF9FunctionKey),
@(kVK_F10): _SRUnicharToString(NSF10FunctionKey),
@(kVK_F11): _SRUnicharToString(NSF11FunctionKey),
@(kVK_F12): _SRUnicharToString(NSF12FunctionKey),
@(kVK_F13): _SRUnicharToString(NSF13FunctionKey),
@(kVK_F14): _SRUnicharToString(NSF14FunctionKey),
@(kVK_F15): _SRUnicharToString(NSF15FunctionKey),
@(kVK_F16): _SRUnicharToString(NSF16FunctionKey),
@(kVK_F17): _SRUnicharToString(NSF17FunctionKey),
@(kVK_F18): _SRUnicharToString(NSF18FunctionKey),
@(kVK_F19): _SRUnicharToString(NSF19FunctionKey),
@(kVK_F20): _SRUnicharToString(NSF20FunctionKey),
@(kVK_Space): _SRUnicharToString(' '),
@(kVK_Delete): _SRUnicharToString(NSBackspaceCharacter),
@(kVK_ForwardDelete): _SRUnicharToString(NSDeleteCharacter),
@(kVK_ANSI_KeypadClear): _SRUnicharToString(NSClearLineFunctionKey),
@(kVK_LeftArrow): _SRUnicharToString(NSLeftArrowFunctionKey),
@(kVK_RightArrow): _SRUnicharToString(NSRightArrowFunctionKey),
@(kVK_UpArrow): _SRUnicharToString(NSUpArrowFunctionKey),
@(kVK_DownArrow): _SRUnicharToString(NSDownArrowFunctionKey),
@(kVK_End): _SRUnicharToString(NSEndFunctionKey),
@(kVK_Home): _SRUnicharToString(NSHomeFunctionKey),
@(kVK_Escape): _SRUnicharToString('\e'),
@(kVK_PageDown): _SRUnicharToString(NSPageDownFunctionKey),
@(kVK_PageUp): _SRUnicharToString(NSPageUpFunctionKey),
@(kVK_Return): _SRUnicharToString(NSCarriageReturnCharacter),
@(kVK_ANSI_KeypadEnter): _SRUnicharToString(NSEnterCharacter),
@(kVK_Tab): _SRUnicharToString(NSTabCharacter),
@(kVK_Help): _SRUnicharToString(NSHelpFunctionKey)
};
});
return Mapping;
}
+ (NSDictionary *)specialKeyCodesToPlainStringsMapping
{
static dispatch_once_t OnceToken;
static NSDictionary *Mapping = nil;
dispatch_once(&OnceToken, ^{
Mapping = @{
@(kVK_F1): @"F1",
@(kVK_F2): @"F2",
@(kVK_F3): @"F3",
@(kVK_F4): @"F4",
@(kVK_F5): @"F5",
@(kVK_F6): @"F6",
@(kVK_F7): @"F7",
@(kVK_F8): @"F8",
@(kVK_F9): @"F9",
@(kVK_F10): @"F10",
@(kVK_F11): @"F11",
@(kVK_F12): @"F12",
@(kVK_F13): @"F13",
@(kVK_F14): @"F14",
@(kVK_F15): @"F15",
@(kVK_F16): @"F16",
@(kVK_F17): @"F17",
@(kVK_F18): @"F18",
@(kVK_F19): @"F19",
@(kVK_F20): @"F20",
@(kVK_Space): SRLoc(@"Space"),
@(kVK_Delete): _SRUnicharToString(SRKeyCodeGlyphDeleteLeft),
@(kVK_ForwardDelete): _SRUnicharToString(SRKeyCodeGlyphDeleteRight),
@(kVK_ANSI_KeypadClear): _SRUnicharToString(SRKeyCodeGlyphPadClear),
@(kVK_LeftArrow): _SRUnicharToString(SRKeyCodeGlyphLeftArrow),
@(kVK_RightArrow): _SRUnicharToString(SRKeyCodeGlyphRightArrow),
@(kVK_UpArrow): _SRUnicharToString(SRKeyCodeGlyphUpArrow),
@(kVK_DownArrow): _SRUnicharToString(SRKeyCodeGlyphDownArrow),
@(kVK_End): _SRUnicharToString(SRKeyCodeGlyphSoutheastArrow),
@(kVK_Home): _SRUnicharToString(SRKeyCodeGlyphNorthwestArrow),
@(kVK_Escape): _SRUnicharToString(SRKeyCodeGlyphEscape),
@(kVK_PageDown): _SRUnicharToString(SRKeyCodeGlyphPageDown),
@(kVK_PageUp): _SRUnicharToString(SRKeyCodeGlyphPageUp),
@(kVK_Return): _SRUnicharToString(SRKeyCodeGlyphReturnR2L),
@(kVK_ANSI_KeypadEnter): _SRUnicharToString(SRKeyCodeGlyphReturn),
@(kVK_Tab): _SRUnicharToString(SRKeyCodeGlyphTabRight),
@(kVK_Help): @"?⃝"
};
});
return Mapping;
}
- (BOOL)isKeyCodeSpecial:(unsigned short)aKeyCode
{
switch (aKeyCode)
{
case kVK_F1:
case kVK_F2:
case kVK_F3:
case kVK_F4:
case kVK_F5:
case kVK_F6:
case kVK_F7:
case kVK_F8:
case kVK_F9:
case kVK_F10:
case kVK_F11:
case kVK_F12:
case kVK_F13:
case kVK_F14:
case kVK_F15:
case kVK_F16:
case kVK_F17:
case kVK_F18:
case kVK_F19:
case kVK_F20:
case kVK_Space:
case kVK_Delete:
case kVK_ForwardDelete:
case kVK_ANSI_KeypadClear:
case kVK_LeftArrow:
case kVK_RightArrow:
case kVK_UpArrow:
case kVK_DownArrow:
case kVK_End:
case kVK_Home:
case kVK_Escape:
case kVK_PageDown:
case kVK_PageUp:
case kVK_Return:
case kVK_ANSI_KeypadEnter:
case kVK_Tab:
case kVK_Help:
return YES;
default:
return NO;
}
}
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass;
{
return [NSString class];
}
- (NSString *)transformedValue:(NSNumber *)aValue
{
return [self transformedValue:aValue withModifierFlags:nil];
}
- (NSString *)transformedValue:(NSNumber *)aValue withModifierFlags:(NSNumber *)aModifierFlags
{
return [self transformedValue:aValue withImplicitModifierFlags:aModifierFlags explicitModifierFlags:nil];
}
- (NSString *)transformedValue:(NSNumber *)aValue withImplicitModifierFlags:(NSNumber *)anImplicitModifierFlags explicitModifierFlags:(NSNumber *)anExplicitModifierFlags
{
if ([anImplicitModifierFlags unsignedIntegerValue] & [anExplicitModifierFlags unsignedIntegerValue] & SRCocoaModifierFlagsMask)
{
[NSException raise:NSInvalidArgumentException format:@"anImplicitModifierFlags and anExplicitModifierFlags MUST NOT have common elements"];
}
if (![aValue isKindOfClass:[NSNumber class]])
return @"";
// Some key codes cannot be translated directly.
NSString *unmappedString = [self transformedSpecialKeyCode:aValue withExplicitModifierFlags:anExplicitModifierFlags];
if (unmappedString)
return unmappedString;
CFDataRef layoutData = NULL;
if (self.usesASCIICapableKeyboardInputSource)
{
TISInputSourceRef tisSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
}
else
{
TISInputSourceRef tisSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
// For non-unicode layouts such as Chinese, Japanese, and Korean, get the ASCII capable layout
if (!layoutData)
{
tisSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
}
}
if (!layoutData)
return @"";
const UCKeyboardLayout *keyLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
static const UniCharCount MaxLength = 255;
UniCharCount actualLength = 0;
UniChar chars[MaxLength] = {0};
UInt32 deadKeyState = 0;
OSStatus err = UCKeyTranslate(keyLayout,
[aValue unsignedShortValue],
kUCKeyActionDisplay,
SRCocoaToCarbonFlags([anImplicitModifierFlags unsignedIntegerValue]) >> 8,
LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
&deadKeyState,
sizeof(chars) / sizeof(UniChar),
&actualLength,
chars);
if (err != noErr)
return @"";
if (self.usesPlainStrings)
return [[NSString stringWithCharacters:chars length:actualLength] uppercaseString];
else
return [NSString stringWithCharacters:chars length:actualLength];
}
- (NSString *)transformedSpecialKeyCode:(NSNumber *)aKeyCode withExplicitModifierFlags:(NSNumber *)anExplicitModifierFlags
{
if ([anExplicitModifierFlags unsignedIntegerValue] & NSEventModifierFlagShift && [aKeyCode unsignedShortValue] == kVK_Tab)
{
if (self.usesPlainStrings)
return _SRUnicharToString(SRKeyCodeGlyphTabLeft);
else
return _SRUnicharToString(NSBackTabCharacter);
}
if (self.usesPlainStrings)
return [[self class] specialKeyCodesToPlainStringsMapping][aKeyCode];
else
return [[self class] specialKeyCodesToUnicodeCharactersMapping][aKeyCode];
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.h
================================================
//
// SRKeyEquivalentModifierMaskTransformer.h
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Ilya Kulakov
#import
/*!
Transform dictionary representation of shortcut into string suitable
for -setKeyEquivalentModifierMask: of NSButton and NSMenuItem.
*/
@interface SRKeyEquivalentModifierMaskTransformer : NSValueTransformer
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.m
================================================
//
// SRKeyEquivalentModifierMaskTransformer.m
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRKeyEquivalentModifierMaskTransformer.h"
#import "SRKeyCodeTransformer.h"
#import "SRRecorderControl.h"
@implementation SRKeyEquivalentModifierMaskTransformer
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass
{
return [NSNumber class];
}
- (NSNumber *)transformedValue:(NSDictionary *)aValue
{
if (![aValue isKindOfClass:[NSDictionary class]])
return @(0);
NSNumber *modifierFlags = aValue[SRShortcutModifierFlagsKey];
if (![modifierFlags isKindOfClass:[NSNumber class]])
return @(0);
return modifierFlags;
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.h
================================================
//
// SRKeyEquivalentTransformer.h
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Ilya Kulakov
#import
/*!
Transform dictionary representation of shortcut into string suitable
for -setKeyEquivalent: of NSButton and NSMenuItem.
*/
@interface SRKeyEquivalentTransformer : NSValueTransformer
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.m
================================================
//
// SRKeyEquivalentTransformer.m
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRKeyEquivalentTransformer.h"
#import "SRKeyCodeTransformer.h"
#import "SRRecorderControl.h"
@implementation SRKeyEquivalentTransformer
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass
{
return [NSString class];
}
- (NSString *)transformedValue:(NSDictionary *)aValue
{
if (![aValue isKindOfClass:[NSDictionary class]])
return @"";
NSNumber *keyCode = aValue[SRShortcutKeyCode];
if (![keyCode isKindOfClass:[NSNumber class]])
return @"";
NSNumber *modifierFlags = aValue[SRShortcutModifierFlagsKey];
if (![modifierFlags isKindOfClass:[NSNumber class]])
modifierFlags = @(0);
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedASCIITransformer];
return [t transformedValue:keyCode
withImplicitModifierFlags:nil
explicitModifierFlags:modifierFlags];
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.h
================================================
//
// SRModifierFlagsTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import
/*!
Transforms mask of Cocoa modifier flags to string of unicode characters.
*/
@interface SRModifierFlagsTransformer : NSValueTransformer
- (instancetype)initWithPlainStrings:(BOOL)aUsesPlainStrings;
/*!
Determines whether modifier flags are transformed to unicode characters or to plain strings.
*/
@property (readonly) BOOL usesPlainStrings;
/*!
Returns the shared transformer.
*/
+ (instancetype)sharedTransformer;
/*!
Returns the shared plain transformer.
*/
+ (instancetype)sharedPlainTransformer;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.m
================================================
//
// SRModifierFlagsTransformer.m
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRModifierFlagsTransformer.h"
#import "SRCommon.h"
@implementation SRModifierFlagsTransformer
- (instancetype)initWithPlainStrings:(BOOL)aUsesPlainStrings
{
self = [super init];
if (self)
{
_usesPlainStrings = aUsesPlainStrings;
}
return self;
}
- (instancetype)init
{
return [self initWithPlainStrings:NO];
}
#pragma mark Methods
+ (instancetype)sharedTransformer
{
static dispatch_once_t OnceToken;
static SRModifierFlagsTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithPlainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedPlainTransformer
{
static dispatch_once_t OnceToken;
static SRModifierFlagsTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithPlainStrings:YES];
});
return Transformer;
}
#pragma mark NSValueTransformer
+ (Class)transformedValueClass
{
return [NSString class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (NSString *)transformedValue:(NSNumber *)aValue
{
if (![aValue isKindOfClass:[NSNumber class]])
return nil;
else if (self.usesPlainStrings)
{
NSEventModifierFlags modifierFlags = [aValue unsignedIntegerValue];
NSMutableString *s = [NSMutableString string];
if (modifierFlags & NSEventModifierFlagControl)
[s appendString:SRLoc(@"Control-")];
if (modifierFlags & NSEventModifierFlagOption)
[s appendString:SRLoc(@"Option-")];
if (modifierFlags & NSEventModifierFlagShift)
[s appendString:SRLoc(@"Shift-")];
if (modifierFlags & NSEventModifierFlagCommand)
[s appendString:SRLoc(@"Command-")];
if (s.length > 0)
[s deleteCharactersInRange:NSMakeRange(s.length - 1, 1)];
return s;
}
else
{
NSEventModifierFlags f = [aValue unsignedIntegerValue];
return [NSString stringWithFormat:@"%@%@%@%@",
(f & NSEventModifierFlagControl ? @"⌃" : @""),
(f & NSEventModifierFlagOption ? @"⌥" : @""),
(f & NSEventModifierFlagShift ? @"⇧" : @""),
(f & NSEventModifierFlagCommand ? @"⌘" : @"")];
}
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.h
================================================
//
// SRRecorderControl.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
#import
#import
/*!
Key code.
@discussion NSNumber representation of unsigned short.
Required key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutKeyCode;
/*!
Modifier flags.
@discussion NSNumber representation of NSEventModifierFlags.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutModifierFlagsKey;
/*!
Interpretation of key code and modifier flags depending on system locale and input source
used when shortcut was taken.
@discussion NSString.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutCharacters;
/*!
Interpretation of key code without modifier flags depending on system locale and input source
used when shortcut was taken.
@discussion NSString.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutCharactersIgnoringModifiers;
@protocol SRRecorderControlDelegate;
/*!
An SRRecorderControl object is a control (but not a subclass of NSControl) that allows you to record shortcuts.
@discussion In addition to NSView bindings, exposes:
NSValueBinding. This binding supports 2 options:
- NSValueTransformerBindingOption
- NSValueTransformerNameBindingOption
NSEnabledBinding. This binding supports 2 options:
- NSValueTransformerBindingOption
- NSValueTransformerNameBindingOption
Note that at that moment, this binding _is not_ multivalue.
Required height: 25 points
Recommended min width: 100 points
*/
IB_DESIGNABLE
@interface SRRecorderControl : NSView /* */
/*!
The receiver’s delegate.
@discussion A recorder control delegate responds to editing-related messages. You can use to to prevent editing
in some cases or to validate typed shortcuts.
*/
@property (assign) IBOutlet NSObject *delegate;
/*!
Returns an integer bit field indicating allowed modifier flags.
@discussion Defaults to SRCocoaModifierFlagsMask.
*/
@property (readonly) IBInspectable NSEventModifierFlags allowedModifierFlags;
/*!
Returns an integer bit field indicating required modifier flags.
@discussion Defaults to 0.
*/
@property (readonly) IBInspectable NSEventModifierFlags requiredModifierFlags;
/*!
Determines whether shortcuts without modifier flags are allowed.
@discussion Defaults to NO.
*/
@property (readonly) IBInspectable BOOL allowsEmptyModifierFlags;
/*!
Determines whether the control reinterpret key code and modifier flags
using ASCII capable input source.
@discussion Defaults to YES.
If not set, the same key code may be draw differently depending on current input source.
E.g. with US English input source key code 0x0 is interpreted as "a",
however with Russian input source, it's interpreted as "ф".
*/
@property IBInspectable BOOL drawsASCIIEquivalentOfShortcut;
/*!
Determines whether Escape is used to cancel recording.
@discussion Defaults to YES.
If set, Escape without modifier flags cannot be recorded as shortcut.
*/
@property IBInspectable BOOL allowsEscapeToCancelRecording;
/*!
Determines whether delete (or forward delete) is used to remove current shortcut and end recording.
@discussion Defaults to YES.
If set, neither Delete nor Forward Delete without modifier flags can be recorded as shortcut.
*/
@property IBInspectable BOOL allowsDeleteToClearShortcutAndEndRecording;
/*!
Determines whether control enabled and can be edited or not.
@discussion Defaults to YES.
*/
@property (nonatomic, getter=isEnabled) IBInspectable BOOL enabled;
/*!
Determines whether recording is in process.
*/
@property (nonatomic, readonly) BOOL isRecording;
/*!
Returns dictionary representation of receiver's shortcut.
*/
@property (nonatomic, copy) NSDictionary *objectValue;
/*!
Configures recording behavior of the control.
@param newAllowedModifierFlags New allowed modifier flags.
@param newRequiredModifierFlags New required modifier flags.
@param newAllowsEmptyModifierFlags Determines whether empty modifier flags are allowed.
@discussion Flags are filtered using SRCocoaModifierFlagsMask. Flags does not affect object values set manually.
These restrictions can be ignored if delegate implements shortcutRecorder:shouldUnconditionallyAllowModifierFlags:forKeyCode: and returns YES for given modifier flags and key code.
Throws NSInvalidArgumentException if either required flags are not allowed
or required flags are not empty and no modifier flags are allowed.
@see SRRecorderControlDelegate
*/
- (void)setAllowedModifierFlags:(NSEventModifierFlags)newAllowedModifierFlags
requiredModifierFlags:(NSEventModifierFlags)newRequiredModifierFlags
allowsEmptyModifierFlags:(BOOL)newAllowsEmptyModifierFlags;
/*!
Called to initialize internal state after either initWithFrame or awakeFromNib is called.
*/
- (void)_initInternalState;
/*!
Turns on the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (BOOL)beginRecording;
/*!
Turns off the recording mode. Current object value is preserved.
@discussion You SHOULD not call this method directly.
*/
- (void)endRecording;
/*!
Clears object value and turns off the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (void)clearAndEndRecording;
/*!
Designated method to end recording. Sets a given object value, updates bindings and turns off the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (void)endRecordingWithObjectValue:(NSDictionary *)anObjectValue;
/*!
Returns shape of the control.
@discussion Primarily used to draw appropriate focus ring.
*/
- (NSBezierPath *)controlShape;
/*!
Returns rect for label with given attributes.
@param aLabel Label for drawing.
@param anAttributes A dictionary of NSAttributedString text attributes to be applied to the string.
*/
- (NSRect)rectForLabel:(NSString *)aLabel withAttributes:(NSDictionary *)anAttributes;
/*!
Returns rect of the snap back button in the receiver coordinates.
*/
- (NSRect)snapBackButtonRect;
/*!
Returns rect of the clear button in the receiver coordinates.
@discussion Returned rect will have empty width (other values will be valid) if button should not be drawn.
*/
- (NSRect)clearButtonRect;
/*!
Returns label to be displayed by the receiver.
@discussion Returned value depends on isRecording state objectValue and currenlty pressed keys and modifier flags.
*/
- (NSString *)label;
/*!
Returns label for accessibility.
@discussion Returned value depends on isRecording state objectValue and currenlty pressed keys and modifier flags.
*/
- (NSString *)accessibilityLabel;
/*!
Returns string representation of object value.
*/
- (NSString *)stringValue;
/*!
Returns string representation of object value for accessibility.
*/
- (NSString *)accessibilityStringValue;
/*!
Returns attirbutes of label to be displayed by the receiver according to current state.
@see normalLabelAttributes
@see recordingLabelAttributes
@see disabledLabelAttributes
*/
- (NSDictionary *)labelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in normal mode.
*/
- (NSDictionary *)normalLabelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in recording mode.
*/
- (NSDictionary *)recordingLabelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in disabled mode.
*/
- (NSDictionary *)disabledLabelAttributes;
/*!
Draws background of the receiver into current graphics context.
*/
- (void)drawBackground:(NSRect)aDirtyRect;
/*!
Draws interior of the receiver into current graphics context.
*/
- (void)drawInterior:(NSRect)aDirtyRect;
/*!
Draws label of the receiver into current graphics context.
*/
- (void)drawLabel:(NSRect)aDirtyRect;
/*!
Draws snap back button of the receiver into current graphics context.
*/
- (void)drawSnapBackButton:(NSRect)aDirtyRect;
/*!
Draws clear button of the receiver into current graphics context.
*/
- (void)drawClearButton:(NSRect)aDirtyRect;
/*!
Determines whether main button (representation of the receiver in normal mode) is highlighted.
*/
- (BOOL)isMainButtonHighlighted;
/*!
Determines whether snap back button is highlighted.
*/
- (BOOL)isSnapBackButtonHighlighted;
/*!
Determines whetehr clear button is highlighted.
*/
- (BOOL)isClearButtonHighlighted;
/*!
Determines whether modifier flags are valid for key code according to the receiver settings.
@param aModifierFlags Proposed modifier flags.
@param aKeyCode Code of the pressed key.
@see allowedModifierFlags
@see allowsEmptyModifierFlags
@see requiredModifierFlags
*/
- (BOOL)areModifierFlagsValid:(NSEventModifierFlags)aModifierFlags forKeyCode:(unsigned short)aKeyCode;
/*!
A helper method to propagate view-driven changes back to model.
@discussion This method makes it easier to propagate changes from a view
back to the model without overriding bind:toObject:withKeyPath:options:
@see http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/
*/
- (void)propagateValue:(id)aValue forBinding:(NSString *)aBinding;
@end
@protocol SRRecorderControlDelegate
@optional
/*!
Asks the delegate if editing should begin in the specified shortcut recorder.
@param aRecorder The shortcut recorder which editing is about to begin.
@result YES if an editing session should be initiated; otherwise, NO to disallow editing.
@discussion Implementation of this method by the delegate is optional. If it is not present, editing proceeds as if this method had returned YES.
*/
- (BOOL)shortcutRecorderShouldBeginRecording:(SRRecorderControl *)aRecorder;
/*!
Gives a delegate opportunity to bypass rules specified by allowed and required modifier flags.
@param aRecorder The shortcut recorder for which editing ended.
@param aModifierFlags Proposed modifier flags.
@param aKeyCode Code of the pressed key.
@result YES if recorder should bypass key code with given modifier flags despite settings like required modifier flags, allowed modifier flags.
@discussion Implementation of this method by the delegate is optional.
Normally, you wouldn't allow a user to record shourcut without modifier flags set: disallow 'a', but allow cmd-'a'.
However, some keys were designed to be key shortcuts by itself. E.g. Functional keys. By implementing this method a delegate can allow
these special keys to be set without modifier flags even when the control is configured to disallow empty modifier flags.
@see allowedModifierFlags
@see allowsEmptyModifierFlags
@see requiredModifierFlags
*/
- (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder shouldUnconditionallyAllowModifierFlags:(NSEventModifierFlags)aModifierFlags forKeyCode:(unsigned short)aKeyCode;
/*!
Asks the delegate if the shortcut can be set by the specified shortcut recorder.
@param aRecorder The shortcut recorder which shortcut is beign to be recordered.
@param aShortcut The Shortcut user typed.
@result YES if shortcut can be recordered. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, shortcut is recordered as if this method had returned YES.
You may implement this method to filter shortcuts that were already set by other recorders.
@see SRValidator
*/
- (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder canRecordShortcut:(NSDictionary *)aShortcut;
/*!
Tells the delegate that editing stopped for the specified shortcut recorder.
@param aRecorder The shortcut recorder for which editing ended.
@discussion Implementation of this method by the delegate is optional.
*/
- (void)shortcutRecorderDidEndRecording:(SRRecorderControl *)aRecorder;
@end
FOUNDATION_STATIC_INLINE BOOL SRShortcutEqualToShortcut(NSDictionary *a, NSDictionary *b)
{
if (a == b)
return YES;
else if (a && !b)
return NO;
else if (!a && b)
return NO;
else
return ([a[SRShortcutKeyCode] isEqual:b[SRShortcutKeyCode]] && [a[SRShortcutModifierFlagsKey] isEqual:b[SRShortcutModifierFlagsKey]]);
}
FOUNDATION_STATIC_INLINE NSDictionary *SRShortcutWithCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
return @{SRShortcutKeyCode: @(aKeyCode), SRShortcutModifierFlagsKey: @(aModifierFlags)};
}
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.m
================================================
//
// SRRecorderControl.m
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
#include
#import "SRRecorderControl.h"
#import "SRKeyCodeTransformer.h"
#import "SRModifierFlagsTransformer.h"
NSString *const SRShortcutKeyCode = @"keyCode";
NSString *const SRShortcutModifierFlagsKey = @"modifierFlags";
NSString *const SRShortcutCharacters = @"characters";
NSString *const SRShortcutCharactersIgnoringModifiers = @"charactersIgnoringModifiers";
// Control Layout Constants
static const CGFloat _SRRecorderControlYosemiteShapeXRadius = 2.0;
static const CGFloat _SRRecorderControlYosemiteShapeYRadius = 2.0;
static const CGFloat _SRRecorderControlShapeXRadius = 11.0;
static const CGFloat _SRRecorderControlShapeYRadius = 12.0;
static const CGFloat _SRRecorderControlHeight = 25.0;
static const CGFloat _SRRecorderControlBottomShadowHeightInPixels = 1.0;
// TODO: see baselineOffsetFromBottom
// static const CGFloat _SRRecorderControlBaselineOffset = 5.0;
// Clear Button Layout Constants
static const CGFloat _SRRecorderControlClearButtonWidth = 14.0;
static const CGFloat _SRRecorderControlClearButtonHeight = 14.0;
static const CGFloat _SRRecorderControlClearButtonRightOffset = 4.0;
static const CGFloat _SRRecorderControlClearButtonLeftOffset = 1.0;
static const NSSize _SRRecorderControlClearButtonSize = {.width = _SRRecorderControlClearButtonWidth, .height = _SRRecorderControlClearButtonHeight};
// SanpBack Button Layout Constants
static const CGFloat _SRRecorderControlSnapBackButtonWidth = 14.0;
static const CGFloat _SRRecorderControlSnapBackButtonHeight = 14.0;
static const CGFloat _SRRecorderControlSnapBackButtonRightOffset = 1.0;
static const CGFloat _SRRecorderControlSnapBackButtonLeftOffset = 3.0;
static const NSSize _SRRecorderControlSnapBackButtonSize = {.width = _SRRecorderControlSnapBackButtonWidth, .height = _SRRecorderControlSnapBackButtonHeight};
static NSImage *_SRImages[19];
typedef NS_ENUM(NSUInteger, _SRRecorderControlButtonTag)
{
_SRRecorderControlInvalidButtonTag = -1,
_SRRecorderControlSnapBackButtonTag = 0,
_SRRecorderControlClearButtonTag = 1,
_SRRecorderControlMainButtonTag = 2
};
@implementation SRRecorderControl
{
NSTrackingArea *_mainButtonTrackingArea;
NSTrackingArea *_snapBackButtonTrackingArea;
NSTrackingArea *_clearButtonTrackingArea;
_SRRecorderControlButtonTag _mouseTrackingButtonTag;
NSToolTipTag _snapBackButtonToolTipTag;
CGFloat _shapeXRadius;
CGFloat _shapeYRadious;
}
- (instancetype)initWithFrame:(NSRect)aFrameRect
{
self = [super initWithFrame:aFrameRect];
if (self)
{
[self _initInternalState];
}
return self;
}
- (void)_initInternalState
{
_allowsEmptyModifierFlags = NO;
_drawsASCIIEquivalentOfShortcut = YES;
_allowsEscapeToCancelRecording = YES;
_allowsDeleteToClearShortcutAndEndRecording = YES;
_enabled = YES;
_allowedModifierFlags = SRCocoaModifierFlagsMask;
_requiredModifierFlags = 0;
_mouseTrackingButtonTag = _SRRecorderControlInvalidButtonTag;
_snapBackButtonToolTipTag = NSIntegerMax;
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
{
self.translatesAutoresizingMaskIntoConstraints = NO;
[self setContentHuggingPriority:NSLayoutPriorityDefaultLow
forOrientation:NSLayoutConstraintOrientationHorizontal];
[self setContentHuggingPriority:NSLayoutPriorityRequired
forOrientation:NSLayoutConstraintOrientationVertical];
[self setContentCompressionResistancePriority:NSLayoutPriorityDefaultLow
forOrientation:NSLayoutConstraintOrientationHorizontal];
[self setContentCompressionResistancePriority:NSLayoutPriorityRequired
forOrientation:NSLayoutConstraintOrientationVertical];
}
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
{
_shapeXRadius = _SRRecorderControlShapeXRadius;
_shapeYRadious = _SRRecorderControlShapeYRadius;
}
else
{
_shapeXRadius = _SRRecorderControlYosemiteShapeXRadius;
_shapeYRadious = _SRRecorderControlYosemiteShapeYRadius;
}
[self setToolTip:SRLoc(@"Click to record shortcut")];
[self updateTrackingAreas];
}
#pragma mark Properties
- (void)setAllowedModifierFlags:(NSEventModifierFlags)newAllowedModifierFlags
requiredModifierFlags:(NSEventModifierFlags)newRequiredModifierFlags
allowsEmptyModifierFlags:(BOOL)newAllowsEmptyModifierFlags
{
newAllowedModifierFlags &= SRCocoaModifierFlagsMask;
newRequiredModifierFlags &= SRCocoaModifierFlagsMask;
if ((newAllowedModifierFlags & newRequiredModifierFlags) != newRequiredModifierFlags)
{
[NSException raise:NSInvalidArgumentException
format:@"Required flags (%lu) MUST be allowed (%lu)", newAllowedModifierFlags, newRequiredModifierFlags];
}
if (newAllowsEmptyModifierFlags && newRequiredModifierFlags != 0)
{
[NSException raise:NSInvalidArgumentException
format:@"Empty modifier flags MUST be disallowed if required modifier flags are not empty."];
}
_allowedModifierFlags = newAllowedModifierFlags;
_requiredModifierFlags = newRequiredModifierFlags;
_allowsEmptyModifierFlags = newAllowsEmptyModifierFlags;
}
- (void)setEnabled:(BOOL)newEnabled
{
_enabled = newEnabled;
[self setNeedsDisplay:YES];
if (!_enabled)
[self endRecording];
// Focus ring is only drawn when view is enabled
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
[self noteFocusRingMaskChanged];
}
- (void)setObjectValue:(NSDictionary *)newObjectValue
{
// Cocoa KVO and KVC frequently uses NSNull as object substituation of nil.
// SRRecorderControl expects either nil or valid object value, it's convenient
// to handle NSNull here and convert it into nil.
if ((NSNull *)newObjectValue == [NSNull null])
newObjectValue = nil;
_objectValue = [newObjectValue copy];
[self propagateValue:_objectValue forBinding:NSValueBinding];
if (!self.isRecording)
{
NSAccessibilityPostNotification(self, NSAccessibilityTitleChangedNotification);
[self setNeedsDisplay:YES];
}
}
#pragma mark Methods
- (BOOL)beginRecording
{
if (!self.enabled)
return NO;
if (self.isRecording)
return YES;
[self setNeedsDisplay:YES];
if ([self.delegate respondsToSelector:@selector(shortcutRecorderShouldBeginRecording:)])
{
if (![self.delegate shortcutRecorderShouldBeginRecording:self])
{
NSBeep();
return NO;
}
}
[self willChangeValueForKey:@"isRecording"];
_isRecording = YES;
[self didChangeValueForKey:@"isRecording"];
[self updateTrackingAreas];
[self setToolTip:SRLoc(@"Type shortcut")];
NSAccessibilityPostNotification(self, NSAccessibilityTitleChangedNotification);
return YES;
}
- (void)endRecording
{
[self endRecordingWithObjectValue:self.objectValue];
}
- (void)clearAndEndRecording
{
[self endRecordingWithObjectValue:nil];
}
- (void)endRecordingWithObjectValue:(NSDictionary *)anObjectValue
{
if (!self.isRecording)
return;
[self willChangeValueForKey:@"isRecording"];
_isRecording = NO;
[self didChangeValueForKey:@"isRecording"];
self.objectValue = anObjectValue;
[self updateTrackingAreas];
[self setToolTip:SRLoc(@"Click to record shortcut")];
[self setNeedsDisplay:YES];
NSAccessibilityPostNotification(self, NSAccessibilityTitleChangedNotification);
if (self.window.firstResponder == self && ![self canBecomeKeyView])
[self.window makeFirstResponder:nil];
if ([self.delegate respondsToSelector:@selector(shortcutRecorderDidEndRecording:)])
[self.delegate shortcutRecorderDidEndRecording:self];
}
#pragma mark -
- (NSBezierPath *)controlShape
{
NSRect shapeBounds = self.bounds;
shapeBounds.size.height = _SRRecorderControlHeight - self.alignmentRectInsets.bottom;
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
{
shapeBounds = NSInsetRect(shapeBounds, 1.0, 1.0);
}
return [NSBezierPath bezierPathWithRoundedRect:shapeBounds
xRadius:_shapeXRadius
yRadius:_shapeYRadious];
}
- (NSRect)rectForLabel:(NSString *)aLabel withAttributes:(NSDictionary *)anAttributes
{
NSSize labelSize = [aLabel sizeWithAttributes:anAttributes];
NSRect enclosingRect = NSInsetRect(self.bounds, _shapeXRadius, 0.0);
labelSize.width = fmin(ceil(labelSize.width), NSWidth(enclosingRect));
labelSize.height = ceil(labelSize.height);
CGFloat fontBaselineOffsetFromTop = labelSize.height + [anAttributes[NSFontAttributeName] descender];
CGFloat baselineOffsetFromTop = _SRRecorderControlHeight - self.baselineOffsetFromBottom;
NSRect labelRect = {
.origin = NSMakePoint(NSMidX(enclosingRect) - labelSize.width / 2.0, baselineOffsetFromTop - fontBaselineOffsetFromTop),
.size = labelSize
};
labelRect = [self centerScanRect:labelRect];
// Ensure label and buttons do not overlap.
if (self.isRecording)
{
CGFloat rightOffsetFromButtons = NSMinX(self.snapBackButtonRect) - NSMaxX(labelRect);
if (rightOffsetFromButtons < 0.0)
{
labelRect = NSOffsetRect(labelRect, rightOffsetFromButtons, 0.0);
if (NSMinX(labelRect) < NSMinX(enclosingRect))
{
labelRect.size.width -= NSMinX(enclosingRect) - NSMinX(labelRect);
labelRect.origin.x = NSMinX(enclosingRect);
}
}
}
#ifdef DEBUG
if (labelRect.size.width < labelSize.width || labelRect.size.height < labelSize.height)
NSLog(@"WARNING: label rect (%@) is smaller than label size (%@). You may want to adjust size of the control.", NSStringFromRect(labelRect), NSStringFromSize(labelSize));
#endif
return labelRect;
}
- (NSRect)snapBackButtonRect
{
NSRect clearButtonRect = self.clearButtonRect;
NSRect bounds = self.bounds;
NSRect snapBackButtonRect = NSZeroRect;
snapBackButtonRect.origin.x = NSMinX(clearButtonRect) - _SRRecorderControlSnapBackButtonRightOffset - _SRRecorderControlSnapBackButtonSize.width - _SRRecorderControlSnapBackButtonLeftOffset;
snapBackButtonRect.origin.y = NSMinY(bounds);
snapBackButtonRect.size.width = fdim(NSMinX(clearButtonRect), NSMinX(snapBackButtonRect));
snapBackButtonRect.size.height = _SRRecorderControlHeight;
return snapBackButtonRect;
}
- (NSRect)clearButtonRect
{
NSRect bounds = self.bounds;
if ([self.objectValue count])
{
NSRect clearButtonRect = NSZeroRect;
clearButtonRect.origin.x = NSMaxX(bounds) - _SRRecorderControlClearButtonRightOffset - _SRRecorderControlClearButtonSize.width - _SRRecorderControlClearButtonLeftOffset;
clearButtonRect.origin.y = NSMinY(bounds);
clearButtonRect.size.width = fdim(NSMaxX(bounds), NSMinX(clearButtonRect));
clearButtonRect.size.height = _SRRecorderControlHeight;
return clearButtonRect;
}
else
{
return NSMakeRect(NSMaxX(bounds) - _SRRecorderControlClearButtonRightOffset - _SRRecorderControlClearButtonLeftOffset,
NSMinY(bounds),
0.0,
_SRRecorderControlHeight);
}
}
#pragma mark -
- (NSString *)label
{
NSString *label = nil;
if (self.isRecording)
{
NSEventModifierFlags modifierFlags = [NSEvent modifierFlags] & self.allowedModifierFlags;
if (modifierFlags)
label = [[SRModifierFlagsTransformer sharedTransformer] transformedValue:@(modifierFlags)];
else
label = self.stringValue;
if (![label length])
label = SRLoc(@"Type shortcut");
}
else
{
label = self.stringValue;
if (![label length])
label = SRLoc(@"Click to record shortcut");
}
return label;
}
- (NSString *)accessibilityLabel
{
NSString *label = nil;
if (self.isRecording)
{
NSEventModifierFlags modifierFlags = [NSEvent modifierFlags] & self.allowedModifierFlags;
label = [[SRModifierFlagsTransformer sharedPlainTransformer] transformedValue:@(modifierFlags)];
if (![label length])
label = SRLoc(@"Type shortcut");
}
else
{
label = self.accessibilityStringValue;
if (![label length])
label = SRLoc(@"Click to record shortcut");
}
return label;
}
- (NSString *)stringValue
{
if (![self.objectValue count])
return nil;
NSString *f = [[SRModifierFlagsTransformer sharedTransformer] transformedValue:self.objectValue[SRShortcutModifierFlagsKey]];
SRKeyCodeTransformer *transformer = nil;
if (self.drawsASCIIEquivalentOfShortcut)
transformer = [SRKeyCodeTransformer sharedPlainASCIITransformer];
else
transformer = [SRKeyCodeTransformer sharedPlainTransformer];
NSString *c = [transformer transformedValue:self.objectValue[SRShortcutKeyCode]
withImplicitModifierFlags:nil
explicitModifierFlags:self.objectValue[SRShortcutModifierFlagsKey]];
return [NSString stringWithFormat:@"%@%@", f, c];
}
- (NSString *)accessibilityStringValue
{
if (![self.objectValue count])
return nil;
NSString *f = [[SRModifierFlagsTransformer sharedPlainTransformer] transformedValue:self.objectValue[SRShortcutModifierFlagsKey]];
NSString *c = nil;
if (self.drawsASCIIEquivalentOfShortcut)
c = [[SRKeyCodeTransformer sharedPlainASCIITransformer] transformedValue:self.objectValue[SRShortcutKeyCode]];
else
c = [[SRKeyCodeTransformer sharedPlainTransformer] transformedValue:self.objectValue[SRShortcutKeyCode]];
if ([f length] > 0)
return [NSString stringWithFormat:@"%@-%@", f, c];
else
return [NSString stringWithFormat:@"%@", c];
}
- (NSDictionary *)labelAttributes
{
if (self.enabled)
{
if (self.isRecording)
return [self recordingLabelAttributes];
else
return [self normalLabelAttributes];
}
else
return [self disabledLabelAttributes];
}
- (NSDictionary *)normalLabelAttributes
{
static dispatch_once_t OnceToken;
static NSDictionary *NormalAttributes = nil;
dispatch_once(&OnceToken, ^{
NSMutableParagraphStyle *p = [[NSMutableParagraphStyle alloc] init];
p.alignment = NSTextAlignmentCenter;
p.lineBreakMode = NSLineBreakByTruncatingTail;
p.baseWritingDirection = NSWritingDirectionLeftToRight;
NormalAttributes = @{
NSParagraphStyleAttributeName: [p copy],
NSFontAttributeName: [NSFont fontWithName:@"Avenir" size:[NSFont systemFontSize]],
NSForegroundColorAttributeName: [NSColor controlTextColor]
};
});
return NormalAttributes;
}
- (NSDictionary *)recordingLabelAttributes
{
static dispatch_once_t OnceToken;
static NSDictionary *RecordingAttributes = nil;
dispatch_once(&OnceToken, ^{
NSMutableParagraphStyle *p = [[NSMutableParagraphStyle alloc] init];
p.alignment = NSTextAlignmentCenter;
p.lineBreakMode = NSLineBreakByTruncatingTail;
p.baseWritingDirection = NSWritingDirectionLeftToRight;
RecordingAttributes = @{
NSParagraphStyleAttributeName: [p copy],
NSFontAttributeName: [NSFont fontWithName:@"Avenir" size:[NSFont systemFontSize]],
NSForegroundColorAttributeName: [NSColor disabledControlTextColor]
};
});
return RecordingAttributes;
}
- (NSDictionary *)disabledLabelAttributes
{
static dispatch_once_t OnceToken;
static NSDictionary *DisabledAttributes = nil;
dispatch_once(&OnceToken, ^{
NSMutableParagraphStyle *p = [[NSMutableParagraphStyle alloc] init];
p.alignment = NSTextAlignmentCenter;
p.lineBreakMode = NSLineBreakByTruncatingTail;
p.baseWritingDirection = NSWritingDirectionLeftToRight;
DisabledAttributes = @{
NSParagraphStyleAttributeName: [p copy],
NSFontAttributeName: [NSFont labelFontOfSize:[NSFont systemFontSize]],
NSForegroundColorAttributeName: [NSColor disabledControlTextColor]
};
});
return DisabledAttributes;
}
#pragma mark -
- (void)drawBackground:(NSRect)aDirtyRect
{
NSRect frame = self.bounds;
frame.size.height = _SRRecorderControlHeight;
if (![self needsToDrawRect:frame])
return;
[NSGraphicsContext saveGraphicsState];
if (self.isRecording)
{
NSDrawThreePartImage(frame,
_SRImages[3],
_SRImages[4],
_SRImages[5],
NO,
NSCompositingOperationSourceOver,
1.0,
self.isFlipped);
}
else
{
if (self.isMainButtonHighlighted)
{
if ([NSColor currentControlTint] == NSBlueControlTint)
{
NSDrawThreePartImage(frame,
_SRImages[0],
_SRImages[1],
_SRImages[2],
NO,
NSCompositingOperationSourceOver,
1.0,
self.isFlipped);
}
else
{
NSDrawThreePartImage(frame,
_SRImages[6],
_SRImages[7],
_SRImages[8],
NO,
NSCompositingOperationSourceOver,
1.0,
self.isFlipped);
}
}
else if (self.enabled)
{
NSDrawThreePartImage(frame,
_SRImages[9],
_SRImages[10],
_SRImages[11],
NO,
NSCompositingOperationSourceOver,
1.0,
self.isFlipped);
}
else
{
NSDrawThreePartImage(frame,
_SRImages[16],
_SRImages[17],
_SRImages[18],
NO,
NSCompositingOperationSourceOver,
1.0,
self.isFlipped);
}
}
[NSGraphicsContext restoreGraphicsState];
}
- (void)drawInterior:(NSRect)aDirtyRect
{
[self drawLabel:aDirtyRect];
if (self.isRecording)
{
[self drawSnapBackButton:aDirtyRect];
[self drawClearButton:aDirtyRect];
}
}
- (void)drawLabel:(NSRect)aDirtyRect
{
NSString *label = self.label;
NSDictionary *labelAttributes = self.labelAttributes;
NSRect labelRect = [self rectForLabel:label withAttributes:labelAttributes];
if (![self needsToDrawRect:labelRect])
return;
[NSGraphicsContext saveGraphicsState];
[label drawInRect:labelRect withAttributes:labelAttributes];
[NSGraphicsContext restoreGraphicsState];
}
- (void)drawSnapBackButton:(NSRect)aDirtyRect
{
NSRect imageRect = self.snapBackButtonRect;
imageRect.origin.x += _SRRecorderControlSnapBackButtonLeftOffset;
imageRect.origin.y += floor(self.alignmentRectInsets.top + (NSHeight(imageRect) - _SRRecorderControlSnapBackButtonSize.height) / 2.0);
imageRect.size = _SRRecorderControlSnapBackButtonSize;
imageRect = [self centerScanRect:imageRect];
if (![self needsToDrawRect:imageRect])
return;
[NSGraphicsContext saveGraphicsState];
if (self.isSnapBackButtonHighlighted)
{
[_SRImages[14] drawInRect:imageRect
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0];
}
else
{
[_SRImages[15] drawInRect:imageRect
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0];
}
[NSGraphicsContext restoreGraphicsState];
}
- (void)drawClearButton:(NSRect)aDirtyRect
{
NSRect imageRect = self.clearButtonRect;
// If there is no reason to draw clear button (e.g. no shortcut was set)
// rect will have empty width.
if (NSWidth(imageRect) == 0.0)
return;
imageRect.origin.x += _SRRecorderControlClearButtonLeftOffset;
imageRect.origin.y += floor(self.alignmentRectInsets.top + (NSHeight(imageRect) - _SRRecorderControlClearButtonSize.height) / 2.0);
imageRect.size = _SRRecorderControlClearButtonSize;
imageRect = [self centerScanRect:imageRect];
if (![self needsToDrawRect:imageRect])
return;
[NSGraphicsContext saveGraphicsState];
if (self.isClearButtonHighlighted)
{
[_SRImages[12] drawInRect:imageRect
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0];
}
else
{
[_SRImages[13] drawInRect:imageRect
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0];
}
[NSGraphicsContext restoreGraphicsState];
}
- (CGFloat)backingScaleFactor
{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6 || self.window == nil)
return 1.0;
else
return self.window.backingScaleFactor;
}
#pragma mark -
- (BOOL)isMainButtonHighlighted
{
if (_mouseTrackingButtonTag == _SRRecorderControlMainButtonTag)
{
NSPoint locationInView = [self convertPoint:self.window.mouseLocationOutsideOfEventStream
fromView:nil];
return [self mouse:locationInView inRect:self.bounds];
}
else
return NO;
}
- (BOOL)isSnapBackButtonHighlighted
{
if (_mouseTrackingButtonTag == _SRRecorderControlSnapBackButtonTag)
{
NSPoint locationInView = [self convertPoint:self.window.mouseLocationOutsideOfEventStream
fromView:nil];
return [self mouse:locationInView inRect:self.snapBackButtonRect];
}
else
return NO;
}
- (BOOL)isClearButtonHighlighted
{
if (_mouseTrackingButtonTag == _SRRecorderControlClearButtonTag)
{
NSPoint locationInView = [self convertPoint:self.window.mouseLocationOutsideOfEventStream
fromView:nil];
return [self mouse:locationInView inRect:self.clearButtonRect];
}
else
return NO;
}
- (BOOL)areModifierFlagsValid:(NSEventModifierFlags)aModifierFlags forKeyCode:(unsigned short)aKeyCode
{
aModifierFlags &= SRCocoaModifierFlagsMask;
if ([self.delegate respondsToSelector:@selector(shortcutRecorder:shouldUnconditionallyAllowModifierFlags:forKeyCode:)] &&
[self.delegate shortcutRecorder:self shouldUnconditionallyAllowModifierFlags:aModifierFlags forKeyCode:aKeyCode])
{
return YES;
}
else if (aModifierFlags == 0 && !self.allowsEmptyModifierFlags)
return NO;
else if ((aModifierFlags & self.requiredModifierFlags) != self.requiredModifierFlags)
return NO;
else if ((aModifierFlags & self.allowedModifierFlags) != aModifierFlags)
return NO;
else
return YES;
}
#pragma mark -
- (void)propagateValue:(id)aValue forBinding:(NSString *)aBinding
{
NSParameterAssert(aBinding != nil);
NSDictionary* bindingInfo = [self infoForBinding:aBinding];
if(!bindingInfo || (id)bindingInfo == [NSNull null])
return;
NSObject *boundObject = bindingInfo[NSObservedObjectKey];
if(!boundObject || (id)boundObject == [NSNull null])
[NSException raise:NSInternalInconsistencyException format:@"NSObservedObjectKey MUST NOT be nil for binding \"%@\"", aBinding];
NSString* boundKeyPath = bindingInfo[NSObservedKeyPathKey];
if(!boundKeyPath || (id)boundKeyPath == [NSNull null])
[NSException raise:NSInternalInconsistencyException format:@"NSObservedKeyPathKey MUST NOT be nil for binding \"%@\"", aBinding];
NSDictionary* bindingOptions = bindingInfo[NSOptionsKey];
if(bindingOptions)
{
NSValueTransformer* transformer = [bindingOptions valueForKey:NSValueTransformerBindingOption];
if(!transformer || (id)transformer == [NSNull null])
{
NSString* transformerName = [bindingOptions valueForKey:NSValueTransformerNameBindingOption];
if(transformerName && (id)transformerName != [NSNull null])
transformer = [NSValueTransformer valueTransformerForName:transformerName];
}
if(transformer && (id)transformer != [NSNull null])
{
if([[transformer class] allowsReverseTransformation])
aValue = [transformer reverseTransformedValue:aValue];
#ifdef DEBUG
else
NSLog(@"WARNING: binding \"%@\" has value transformer, but it doesn't allow reverse transformations in %s", aBinding, __PRETTY_FUNCTION__);
#endif
}
}
[boundObject setValue:aValue forKeyPath:boundKeyPath];
}
+ (BOOL)automaticallyNotifiesObserversOfValue
{
return NO;
}
- (void)setValue:(id)newValue
{
if (NSIsControllerMarker(newValue))
[NSException raise:NSInternalInconsistencyException format:@"SRRecorderControl's NSValueBinding does not support controller value markers."];
self.objectValue = newValue;
}
- (id)value
{
return self.objectValue;
}
#pragma mark NSToolTipOwner
- (NSString *)view:(NSView *)aView stringForToolTip:(NSToolTipTag)aTag point:(NSPoint)aPoint userData:(void *)aData
{
if (aTag == _snapBackButtonToolTipTag)
return SRLoc(@"Use old shortcut");
else
return [super view:aView stringForToolTip:aTag point:aPoint userData:aData];
}
#pragma mark NSCoding
- (instancetype)initWithCoder:(NSCoder *)aCoder
{
// Since Xcode 6.x, user can configure xib to Prefer Coder.
// In that case view will be instantiated with initWithCoder.
//
// awakeFromNib cannot be used to set up defaults for IBDesignable,
// because at the time it's called, it's impossible to know whether properties
// were set by a user in xib or they are compilation-time defaults.
self = [super initWithCoder:aCoder];
if (self)
{
[self _initInternalState];
}
return self;
}
#pragma mark NSView
- (BOOL)isOpaque
{
return NO;
}
- (BOOL)isFlipped
{
return YES;
}
- (void)viewWillDraw
{
[super viewWillDraw];
static dispatch_once_t OnceToken;
dispatch_once(&OnceToken, ^{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
{
_SRImages[0] = SRImage(@"shortcut-recorder-bezel-blue-highlighted-left");
_SRImages[1] = SRImage(@"shortcut-recorder-bezel-blue-highlighted-middle");
_SRImages[2] = SRImage(@"shortcut-recorder-bezel-blue-highlighted-right");
_SRImages[3] = SRImage(@"shortcut-recorder-bezel-editing-left");
_SRImages[4] = SRImage(@"shortcut-recorder-bezel-editing-middle");
_SRImages[5] = SRImage(@"shortcut-recorder-bezel-editing-right");
_SRImages[6] = SRImage(@"shortcut-recorder-bezel-graphite-highlight-mask-left");
_SRImages[7] = SRImage(@"shortcut-recorder-bezel-graphite-highlight-mask-middle");
_SRImages[8] = SRImage(@"shortcut-recorder-bezel-graphite-highlight-mask-right");
_SRImages[9] = SRImage(@"shortcut-recorder-bezel-left");
_SRImages[10] = SRImage(@"shortcut-recorder-bezel-middle");
_SRImages[11] = SRImage(@"shortcut-recorder-bezel-right");
_SRImages[12] = SRImage(@"shortcut-recorder-clear-highlighted");
_SRImages[13] = SRImage(@"shortcut-recorder-clear");
_SRImages[14] = SRImage(@"shortcut-recorder-snapback-highlighted");
_SRImages[15] = SRImage(@"shortcut-recorder-snapback");
_SRImages[16] = SRImage(@"shortcut-recorder-bezel-disabled-left");
_SRImages[17] = SRImage(@"shortcut-recorder-bezel-disabled-middle");
_SRImages[18] = SRImage(@"shortcut-recorder-bezel-disabled-right");
}
else
{
_SRImages[0] = SRImage(@"shortcut-recorder-yosemite-bezel-blue-highlighted-left");
_SRImages[1] = SRImage(@"shortcut-recorder-yosemite-bezel-blue-highlighted-middle");
_SRImages[2] = SRImage(@"shortcut-recorder-yosemite-bezel-blue-highlighted-right");
_SRImages[3] = SRImage(@"shortcut-recorder-yosemite-bezel-editing-left");
_SRImages[4] = SRImage(@"shortcut-recorder-yosemite-bezel-editing-middle");
_SRImages[5] = SRImage(@"shortcut-recorder-yosemite-bezel-editing-right");
_SRImages[6] = SRImage(@"shortcut-recorder-yosemite-bezel-graphite-highlight-mask-left");
_SRImages[7] = SRImage(@"shortcut-recorder-yosemite-bezel-graphite-highlight-mask-middle");
_SRImages[8] = SRImage(@"shortcut-recorder-yosemite-bezel-graphite-highlight-mask-right");
_SRImages[9] = SRImage(@"shortcut-recorder-yosemite-bezel-left");
_SRImages[10] = SRImage(@"shortcut-recorder-yosemite-bezel-middle");
_SRImages[11] = SRImage(@"shortcut-recorder-yosemite-bezel-right");
_SRImages[12] = SRImage(@"shortcut-recorder-yosemite-clear-highlighted");
_SRImages[13] = SRImage(@"shortcut-recorder-yosemite-clear");
_SRImages[14] = SRImage(@"shortcut-recorder-yosemite-snapback-highlighted");
_SRImages[15] = SRImage(@"shortcut-recorder-yosemite-snapback");
_SRImages[16] = SRImage(@"shortcut-recorder-yosemite-bezel-disabled-left");
_SRImages[17] = SRImage(@"shortcut-recorder-yosemite-bezel-disabled-middle");
_SRImages[18] = SRImage(@"shortcut-recorder-yosemite-bezel-disabled-right");
}
});
}
- (void)drawRect:(NSRect)aDirtyRect
{
[self drawBackground:aDirtyRect];
[self drawInterior:aDirtyRect];
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
{
if (self.enabled && self.window.firstResponder == self)
{
[NSGraphicsContext saveGraphicsState];
NSSetFocusRingStyle(NSFocusRingOnly);
[self.controlShape fill];
[NSGraphicsContext restoreGraphicsState];
}
}
}
- (void)drawFocusRingMask
{
if (self.enabled && self.window.firstResponder == self)
[self.controlShape fill];
}
- (NSRect)focusRingMaskBounds
{
if (self.enabled && self.window.firstResponder == self)
return self.controlShape.bounds;
else
return NSZeroRect;
}
- (NSEdgeInsets)alignmentRectInsets
{
return NSEdgeInsetsMake(0.0, 0.0, _SRRecorderControlBottomShadowHeightInPixels / self.backingScaleFactor, 0.0);
}
- (CGFloat)baselineOffsetFromBottom
{
// True method to calculate is presented below. Unfortunately Cocoa implementation of Mac OS X 10.8.2 expects this value to be persistant.
// If baselineOffsetFromBottom depends on some other properties and may return different values for different calls,
// NSLayoutFormatAlignAllBaseline may not work. For this reason we return the constant.
// If you're going to change layout of the view, uncomment the line below, look what it typically returns and update the constant.
// TODO: Hopefully it will be fixed some day in Cocoa and therefore in SRRecorderControl.
// CGFloat baseline = fdim(NSHeight(self.bounds), _SRRecorderControlHeight) + floor(_SRRecorderControlBaselineOffset - [self.labelAttributes[NSFontAttributeName] descender]);
return 8.0;
}
- (NSSize)intrinsicContentSize
{
return NSMakeSize(NSWidth([self rectForLabel:SRLoc(@"Click to record shortcut") withAttributes:self.normalLabelAttributes]) + _shapeXRadius + _shapeXRadius,
_SRRecorderControlHeight);
}
- (void)updateTrackingAreas
{
static const NSTrackingAreaOptions TrackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveWhenFirstResponder | NSTrackingEnabledDuringMouseDrag;
if (_mainButtonTrackingArea)
[self removeTrackingArea:_mainButtonTrackingArea];
_mainButtonTrackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds
options:TrackingOptions
owner:self
userInfo:nil];
[self addTrackingArea:_mainButtonTrackingArea];
if (_snapBackButtonTrackingArea)
{
[self removeTrackingArea:_snapBackButtonTrackingArea];
_snapBackButtonTrackingArea = nil;
}
if (_clearButtonTrackingArea)
{
[self removeTrackingArea:_clearButtonTrackingArea];
_clearButtonTrackingArea = nil;
}
if (_snapBackButtonToolTipTag != NSIntegerMax)
{
[self removeToolTip:_snapBackButtonToolTipTag];
_snapBackButtonToolTipTag = NSIntegerMax;
}
if (self.isRecording)
{
_snapBackButtonTrackingArea = [[NSTrackingArea alloc] initWithRect:self.snapBackButtonRect
options:TrackingOptions
owner:self
userInfo:nil];
[self addTrackingArea:_snapBackButtonTrackingArea];
_clearButtonTrackingArea = [[NSTrackingArea alloc] initWithRect:self.clearButtonRect
options:TrackingOptions
owner:self
userInfo:nil];
[self addTrackingArea:_clearButtonTrackingArea];
// Since this method is used to set up tracking rects of aux buttons, the rest of the code is aware
// it should be called whenever geometry or apperance changes. Therefore it's a good place to set up tooltip rects.
_snapBackButtonToolTipTag = [self addToolTipRect:[_snapBackButtonTrackingArea rect] owner:self userData:NULL];
}
}
- (void)viewWillMoveToWindow:(NSWindow *)aWindow
{
// We want control to end recording whenever window resigns first responder status.
// Otherwise we could end up with "dangling" recording.
if (self.window)
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSWindowDidResignKeyNotification
object:self.window];
}
if (aWindow)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(endRecording)
name:NSWindowDidResignKeyNotification
object:aWindow];
}
[super viewWillMoveToWindow:aWindow];
}
#pragma mark NSResponder
- (BOOL)acceptsFirstResponder
{
return self.enabled;
}
- (BOOL)becomeFirstResponder
{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
[self setKeyboardFocusRingNeedsDisplayInRect:self.bounds];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
[self setKeyboardFocusRingNeedsDisplayInRect:self.bounds];
[self endRecording];
_mouseTrackingButtonTag = _SRRecorderControlInvalidButtonTag;
return [super resignFirstResponder];
}
- (BOOL)acceptsFirstMouse:(NSEvent *)anEvent
{
return YES;
}
- (BOOL)canBecomeKeyView
{
// SRRecorderControl uses the button metaphor, but buttons cannot become key unless
// Full Keyboard Access is enabled. Respect this.
return [super canBecomeKeyView] && [NSApp isFullKeyboardAccessEnabled];
}
- (BOOL)needsPanelToBecomeKey
{
return YES;
}
- (void)mouseDown:(NSEvent *)anEvent
{
if (!self.enabled)
{
[super mouseDown:anEvent];
return;
}
NSPoint locationInView = [self convertPoint:anEvent.locationInWindow fromView:nil];
if (self.isRecording)
{
if ([self mouse:locationInView inRect:self.snapBackButtonRect])
{
_mouseTrackingButtonTag = _SRRecorderControlSnapBackButtonTag;
[self setNeedsDisplayInRect:self.snapBackButtonRect];
}
else if ([self mouse:locationInView inRect:self.clearButtonRect])
{
_mouseTrackingButtonTag = _SRRecorderControlClearButtonTag;
[self setNeedsDisplayInRect:self.clearButtonRect];
}
else
[super mouseDown:anEvent];
}
else if ([self mouse:locationInView inRect:self.bounds])
{
_mouseTrackingButtonTag = _SRRecorderControlMainButtonTag;
[self setNeedsDisplay:YES];
}
else
[super mouseDown:anEvent];
}
- (void)mouseUp:(NSEvent *)anEvent
{
if (!self.enabled)
{
[super mouseUp:anEvent];
return;
}
if (_mouseTrackingButtonTag != _SRRecorderControlInvalidButtonTag)
{
if (!self.window.isKeyWindow)
{
// It's possible to receive this event after window resigned its key status
// e.g. when shortcut brings new window and makes it key.
[self setNeedsDisplay:YES];
}
else
{
NSPoint locationInView = [self convertPoint:anEvent.locationInWindow fromView:nil];
if (_mouseTrackingButtonTag == _SRRecorderControlMainButtonTag &&
[self mouse:locationInView inRect:self.bounds])
{
[self beginRecording];
}
else if (_mouseTrackingButtonTag == _SRRecorderControlSnapBackButtonTag &&
[self mouse:locationInView inRect:self.snapBackButtonRect])
{
[self endRecording];
}
else if (_mouseTrackingButtonTag == _SRRecorderControlClearButtonTag &&
[self mouse:locationInView inRect:self.clearButtonRect])
{
[self clearAndEndRecording];
}
}
_mouseTrackingButtonTag = _SRRecorderControlInvalidButtonTag;
}
else
[super mouseUp:anEvent];
}
- (void)mouseEntered:(NSEvent *)anEvent
{
if (!self.enabled)
{
[super mouseEntered:anEvent];
return;
}
if ((_mouseTrackingButtonTag == _SRRecorderControlMainButtonTag && anEvent.trackingArea == _mainButtonTrackingArea) ||
(_mouseTrackingButtonTag == _SRRecorderControlSnapBackButtonTag && anEvent.trackingArea == _snapBackButtonTrackingArea) ||
(_mouseTrackingButtonTag == _SRRecorderControlClearButtonTag && anEvent.trackingArea == _clearButtonTrackingArea))
{
[self setNeedsDisplayInRect:anEvent.trackingArea.rect];
}
[super mouseEntered:anEvent];
}
- (void)mouseExited:(NSEvent *)anEvent
{
if (!self.enabled)
{
[super mouseExited:anEvent];
return;
}
if ((_mouseTrackingButtonTag == _SRRecorderControlMainButtonTag && anEvent.trackingArea == _mainButtonTrackingArea) ||
(_mouseTrackingButtonTag == _SRRecorderControlSnapBackButtonTag && anEvent.trackingArea == _snapBackButtonTrackingArea) ||
(_mouseTrackingButtonTag == _SRRecorderControlClearButtonTag && anEvent.trackingArea == _clearButtonTrackingArea))
{
[self setNeedsDisplayInRect:anEvent.trackingArea.rect];
}
[super mouseExited:anEvent];
}
- (void)keyDown:(NSEvent *)anEvent
{
if (![self performKeyEquivalent:anEvent])
[super keyDown:anEvent];
}
- (BOOL)performKeyEquivalent:(NSEvent *)anEvent
{
if (!self.enabled)
return NO;
if (self.window.firstResponder != self)
return NO;
if (_mouseTrackingButtonTag != _SRRecorderControlInvalidButtonTag)
return NO;
if (self.isRecording)
{
if (anEvent.keyCode == USHRT_MAX)
{
// This shouldn't really happen ever, but was rarely observed.
// See https://github.com/Kentzo/ShortcutRecorder/issues/40
return NO;
}
else if (self.allowsEscapeToCancelRecording &&
anEvent.keyCode == kVK_Escape &&
(anEvent.modifierFlags & SRCocoaModifierFlagsMask) == 0)
{
[self endRecording];
return YES;
}
else if (self.allowsDeleteToClearShortcutAndEndRecording &&
(anEvent.keyCode == kVK_Delete || anEvent.keyCode == kVK_ForwardDelete) &&
(anEvent.modifierFlags & SRCocoaModifierFlagsMask) == 0)
{
[self clearAndEndRecording];
return YES;
}
else if ([self areModifierFlagsValid:anEvent.modifierFlags forKeyCode:anEvent.keyCode])
{
NSDictionary *newObjectValue = @{
SRShortcutKeyCode: @(anEvent.keyCode),
SRShortcutModifierFlagsKey: @(anEvent.modifierFlags & SRCocoaModifierFlagsMask),
SRShortcutCharacters: anEvent.characters,
SRShortcutCharactersIgnoringModifiers: anEvent.charactersIgnoringModifiers
};
if ([self.delegate respondsToSelector:@selector(shortcutRecorder:canRecordShortcut:)])
{
if (![self.delegate shortcutRecorder:self canRecordShortcut:newObjectValue])
{
// We acutally handled key equivalent, because client likely performs some action
// to represent an error (e.g. beep and error dialog).
// Do not end editing, because if client do not use additional window to show an error
// first responder will not change. Allow a user to make another attempt.
return YES;
}
}
[self endRecordingWithObjectValue:newObjectValue];
return YES;
}
}
else if (anEvent.keyCode == kVK_Space)
return [self beginRecording];
return NO;
}
- (void)flagsChanged:(NSEvent *)anEvent
{
if (self.isRecording)
{
NSEventModifierFlags modifierFlags = anEvent.modifierFlags & SRCocoaModifierFlagsMask;
if (modifierFlags != 0 && ![self areModifierFlagsValid:modifierFlags forKeyCode:anEvent.keyCode])
NSBeep();
[self setNeedsDisplay:YES];
}
[super flagsChanged:anEvent];
}
#pragma mark NSObject
+ (void)initialize
{
if (self == [SRRecorderControl class])
{
[self exposeBinding:NSValueBinding];
[self exposeBinding:NSEnabledBinding];
}
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.h
================================================
//
// SRValidator.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Silvio Rizzi
// Ilya Kulakov
#import
@protocol SRValidatorDelegate;
/*!
Implements logic to check whether shortcut is taken by other parts of the application and system.
*/
@interface SRValidator : NSObject
@property (assign) NSObject *delegate;
- (instancetype)initWithDelegate:(NSObject *)aDelegate;
/*!
Determines whether shortcut is taken.
@discussion Key is checked in the following order:
1. If delegate implements shortcutValidator:isKeyCode:andFlagsTaken:reason:
2. If delegate allows system-wide shortcuts are checked
3. If delegate allows application menu it checked
@see SRValidatorDelegate
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken in delegate.
@discussion If delegate does not implement appropriate method, returns immediately.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagTakenInDelegate:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken by system-wide shortcuts.
@discussion Does not check whether delegate allows or disallows checking in system shortcuts.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTakenInSystemShortcuts:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken by application menu item.
@discussion Does not check whether delegate allows or disallows checking in application menu.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlags:(NSEventModifierFlags)aFlags takenInMenu:(NSMenu *)aMenu error:(NSError **)outError;
@end
@protocol SRValidatorDelegate
@optional
/*!
Asks the delegate if aKeyCode and aFlags are valid.
@param aValidator The validator that validates key code and flags.
@param aKeyCode Key code to validate.
@param aFlags Flags to validate.
@param outReason If delegate decides that shortcut is invalid, it may pass here an error message.
@result YES if shortcut is valid. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidator:(SRValidator *)aValidator isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags reason:(NSString **)outReason;
/*!
Asks the delegate whether validator should check key equivalents of app's menu items.
@param aValidator The validator that going to check app's menu items.
@result YES if validator should check key equivalents of app's menu items. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidatorShouldCheckMenu:(SRValidator *)aValidator;
/*!
Asks the delegate whether it should check system shortcuts.
@param aValidator The validator that going to check system shortcuts.
@result YES if validator should check system shortcuts. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidatorShouldCheckSystemShortcuts:(SRValidator *)aValidator;
/*!
Asks the delegate whether it should use ASCII representation of key code when making error messages.
@param aValidator The validator that is about to make an error message.
@result YES if validator should use ASCII representation. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, ASCII representation of key code is used.
*/
- (BOOL)shortcutValidatorShouldUseASCIIStringForKeyCodes:(SRValidator *)aValidator;
@end
@interface NSMenuItem (SRValidator)
/*!
Returns full path to the menu item. E.g. "Window ➝ Zoom"
*/
- (NSString *)SR_path;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.m
================================================
//
// SRValidator.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Silvio Rizzi
// Ilya Kulakov
#import "SRValidator.h"
#import "SRCommon.h"
#import "SRKeyCodeTransformer.h"
@implementation SRValidator
- (instancetype)initWithDelegate:(NSObject *)aDelegate;
{
self = [super init];
if (self)
{
_delegate = aDelegate;
}
return self;
}
- (instancetype)init
{
return [self initWithDelegate:nil];
}
#pragma mark Methods
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags error:(NSError **)outError;
{
if ([self isKeyCode:aKeyCode andFlagTakenInDelegate:aFlags error:outError])
return YES;
if ((![self.delegate respondsToSelector:@selector(shortcutValidatorShouldCheckSystemShortcuts:)] ||
[self.delegate shortcutValidatorShouldCheckSystemShortcuts:self]) &&
[self isKeyCode:aKeyCode andFlagsTakenInSystemShortcuts:aFlags error:outError])
{
return YES;
}
if ((![self.delegate respondsToSelector:@selector(shortcutValidatorShouldCheckMenu:)] ||
[self.delegate shortcutValidatorShouldCheckMenu:self]) &&
[self isKeyCode:aKeyCode andFlags:aFlags takenInMenu:[NSApp mainMenu] error:outError])
{
return YES;
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagTakenInDelegate:(NSEventModifierFlags)aFlags error:(NSError **)outError
{
if (self.delegate)
{
NSString *delegateReason = nil;
if ([self.delegate respondsToSelector:@selector(shortcutValidator:isKeyCode:andFlagsTaken:reason:)] &&
[self.delegate shortcutValidator:self
isKeyCode:aKeyCode
andFlagsTaken:aFlags
reason:&delegateReason])
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used!"),
shortcut];
NSString *description = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used because %@."),
shortcut,
[delegateReason length] ? delegateReason : @"it's already used"];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey : failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTakenInSystemShortcuts:(NSEventModifierFlags)aFlags error:(NSError **)outError
{
CFArrayRef s = NULL;
OSStatus err = CopySymbolicHotKeys(&s);
if (err != noErr)
return YES;
NSArray *symbolicHotKeys = (NSArray *)CFBridgingRelease(s);
aFlags &= SRCocoaModifierFlagsMask;
for (NSDictionary *symbolicHotKey in symbolicHotKeys)
{
if ((__bridge CFBooleanRef)symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyEnabled] != kCFBooleanTrue)
continue;
unsigned short symbolicHotKeyCode = [symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyCode] integerValue];
if (symbolicHotKeyCode == aKeyCode)
{
UInt32 symbolicHotKeyFlags = [symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyModifiers] unsignedIntValue];
symbolicHotKeyFlags &= SRCarbonModifierFlagsMask;
if (SRCarbonToCocoaFlags(symbolicHotKeyFlags) == aFlags)
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used!"),
shortcut];
NSString *description = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used because it's already used by a system-wide keyboard shortcut. If you really want to use this key combination, most shortcuts can be changed in the Keyboard panel in System Preferences."),
shortcut];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey: failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlags:(NSEventModifierFlags)aFlags takenInMenu:(NSMenu *)aMenu error:(NSError **)outError
{
aFlags &= SRCocoaModifierFlagsMask;
for (NSMenuItem *menuItem in [aMenu itemArray])
{
if (menuItem.hasSubmenu && [self isKeyCode:aKeyCode andFlags:aFlags takenInMenu:menuItem.submenu error:outError])
return YES;
NSString *keyEquivalent = menuItem.keyEquivalent;
if (![keyEquivalent length])
continue;
NSEventModifierFlags keyEquivalentModifierMask = menuItem.keyEquivalentModifierMask;
if (SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode, aFlags, keyEquivalent, keyEquivalentModifierMask))
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:SRLoc(@"The key combination \"%@\" can't be used!"), shortcut];
NSString *description = [NSString stringWithFormat:SRLoc(@"The key combination \"%@\" can't be used because it's already used by the menu item \"%@\"."), shortcut, menuItem.SR_path];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey: failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
return NO;
}
@end
@implementation NSMenuItem (SRValidator)
- (NSString *)SR_path
{
NSMutableArray *items = [NSMutableArray array];
static const NSUInteger Limit = 1000;
NSMenuItem *currentMenuItem = self;
NSUInteger i = 0;
do
{
[items insertObject:currentMenuItem atIndex:0];
currentMenuItem = currentMenuItem.parentItem;
++i;
}
while (currentMenuItem && i < Limit);
NSMutableString *path = [NSMutableString string];
for (NSMenuItem *menuItem in items)
[path appendFormat:@"%@➝", menuItem.title];
if ([path length] > 1)
[path deleteCharactersInRange:NSMakeRange([path length] - 1, 1)];
return path;
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Library/ShortcutRecorder.h
================================================
//
// ShortcutRecorder.h
// ShortcutRecorder
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Jesper
// Ilya Kulakov
#import
#import
#import
#import
#import
#import
#import
#import
#ifndef IBInspectable
#define IBInspectable
#endif
#ifndef IB_DESIGNABLE
#define IB_DESIGNABLE
#endif
#ifndef NSAppKitVersionNumber10_6
#define NSAppKitVersionNumber10_6 1038
#endif
#ifndef NSAppKitVersionNumber10_9
#define NSAppKitVersionNumber10_9 1265
#endif
#ifndef NSEDGEINSETS_DEFINED
typedef struct NSEdgeInsets {
CGFloat top;
CGFloat left;
CGFloat bottom;
CGFloat right;
} NSEdgeInsets;
NS_INLINE NSEdgeInsets NSEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) {
NSEdgeInsets e;
e.top = top;
e.left = left;
e.bottom = bottom;
e.right = right;
return e;
}
#endif
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/Info.plist
================================================
CFBundleDevelopmentRegion
English
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
FMWK
CFBundleShortVersionString
1.5
CFBundleSignature
????
CFBundleVersion
1.5
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.h
================================================
//
// PTHotKey+ShortcutRecorder.h
// ShortcutRecorder
//
// Created by Ilya Kulakov on 27.02.11.
// Copyright 2011 Wireload. All rights reserved.
//
#import
#import "PTHotKey.h"
@interface PTHotKey (ShortcutRecorder)
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction;
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
keyUpAction:(SEL)aKeyUpAction;
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
withObject:(id)anObject;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.m
================================================
//
// PTHotKey+ShortcutRecorder.m
// ShortcutRecorder
//
// Created by Ilya Kulakov on 27.02.11.
// Copyright 2011 Wireload. All rights reserved.
//
#import "PTHotKey+ShortcutRecorder.h"
#import "SRRecorderControl.h"
@implementation PTHotKey (ShortcutRecorder)
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
{
return [PTHotKey hotKeyWithIdentifier:anIdentifier keyCombo:aKeyCombo target:aTarget action:anAction withObject:nil];
}
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
withObject:(id)anObject
{
NSInteger keyCode = [[aKeyCombo objectForKey:@"keyCode"] integerValue];
NSUInteger modifiers = SRCocoaToCarbonFlags([[aKeyCombo objectForKey:@"modifierFlags"] unsignedIntegerValue]);
PTKeyCombo *newKeyCombo = [[PTKeyCombo alloc] initWithKeyCode:keyCode modifiers:modifiers];
PTHotKey *newHotKey = [[PTHotKey alloc] initWithIdentifier:anIdentifier keyCombo:newKeyCombo];
[newHotKey setTarget:aTarget];
[newHotKey setAction:anAction];
[newHotKey setObject:anObject];
return newHotKey;
}
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
keyUpAction:(SEL)aKeyUpAction
{
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:anIdentifier
keyCombo:aKeyCombo
target:aTarget
action:anAction];
[newHotKey setKeyUpAction:aKeyUpAction];
return newHotKey;
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.h
================================================
//
// PTHotKey.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
// Contributors:
// Andy Kim
#import
#import
#import "PTKeyCombo.h"
@interface PTHotKey : NSObject
{
NSString* mIdentifier;
NSString* mName;
PTKeyCombo* mKeyCombo;
id mTarget;
id mObject;
SEL mAction;
SEL mKeyUpAction;
UInt32 mCarbonHotKeyID;
EventHotKeyRef mCarbonEventHotKeyRef;
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo;
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo withObject: (id)object;
- (id)init;
- (void)setIdentifier: (id)ident;
- (id)identifier;
- (void)setName: (NSString*)name;
- (NSString*)name;
- (void)setKeyCombo: (PTKeyCombo*)combo;
- (PTKeyCombo*)keyCombo;
- (void)setTarget: (id)target;
- (id)target;
- (void)setObject: (id)object;
- (id)object;
- (void)setAction: (SEL)action;
- (SEL)action;
- (void)setKeyUpAction: (SEL)action;
- (SEL)keyUpAction;
- (UInt32)carbonHotKeyID;
- (void)setCarbonHotKeyID: (UInt32)hotKeyID;
- (EventHotKeyRef)carbonEventHotKeyRef;
- (void)setCarbonEventHotKeyRef:(EventHotKeyRef)hotKeyRef;
- (void)invoke;
- (void)uninvoke;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.m
================================================
//
// PTHotKey.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTHotKey.h"
#import "PTHotKeyCenter.h"
#import "PTKeyCombo.h"
@implementation PTHotKey
- (id)init
{
return [self initWithIdentifier: nil keyCombo: nil withObject:nil];
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo
{
return [self initWithIdentifier: identifier keyCombo: combo withObject:nil];
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo withObject: (id)object
{
self = [super init];
if( self )
{
[self setIdentifier: identifier];
[self setKeyCombo: combo];
[self setObject: object];
}
return self;
}
- (NSString*)description
{
return [NSString stringWithFormat: @"<%@: %@, %@>", NSStringFromClass( [self class] ), [self identifier], [self keyCombo]];
}
#pragma mark -
- (void)setIdentifier: (id)ident
{
mIdentifier = ident;
}
- (id)identifier
{
return mIdentifier;
}
- (void)setKeyCombo: (PTKeyCombo*)combo
{
if( combo == nil )
combo = [PTKeyCombo clearKeyCombo];
mKeyCombo = combo;
}
- (PTKeyCombo*)keyCombo
{
return mKeyCombo;
}
- (void)setName: (NSString*)name
{
mName = name;
}
- (NSString*)name
{
return mName;
}
- (void)setTarget: (id)target
{
mTarget = target;
}
- (id)target
{
return mTarget;
}
- (void)setObject:(id)object
{
mObject = object;
}
- (id)object
{
return mObject;
}
- (void)setAction: (SEL)action
{
mAction = action;
}
- (SEL)action
{
return mAction;
}
- (void)setKeyUpAction: (SEL)action
{
mKeyUpAction = action;
}
- (SEL)keyUpAction
{
return mKeyUpAction;
}
- (UInt32)carbonHotKeyID
{
return mCarbonHotKeyID;
}
- (void)setCarbonHotKeyID: (UInt32)hotKeyID;
{
mCarbonHotKeyID = hotKeyID;
}
- (EventHotKeyRef)carbonEventHotKeyRef
{
return mCarbonEventHotKeyRef;
}
- (void)setCarbonEventHotKeyRef: (EventHotKeyRef)hotKeyRef
{
mCarbonEventHotKeyRef = hotKeyRef;
}
#pragma mark -
- (void)invoke
{
if(mAction)
[NSApp sendAction:mAction to:mTarget from:self];
}
- (void)uninvoke
{
if(mKeyUpAction)
[NSApp sendAction:mKeyUpAction to:mTarget from:self];
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.h
================================================
//
// PTHotKeyCenter.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
// Contributors:
// Quentin D. Carnicelli
// Finlay Dobbie
// Vincent Pottier
// Andy Kim
#import
#import
@class PTHotKey;
@interface PTHotKeyCenter : NSObject
{
NSMutableDictionary* mHotKeys; //Keys are carbon hot key IDs
BOOL mEventHandlerInstalled;
UInt32 mHotKeyCount; // Used to assign new hot key ID
BOOL mIsPaused;
EventHandlerRef mEventHandler;
}
+ (PTHotKeyCenter *)sharedCenter;
- (BOOL)registerHotKey: (PTHotKey*)hotKey;
- (void)unregisterHotKey: (PTHotKey*)hotKey;
- (NSArray*)allHotKeys;
- (PTHotKey*)hotKeyWithIdentifier: (id)ident;
- (void)sendEvent: (NSEvent*)event;
- (void)pause;
- (void)resume;
- (BOOL)isPaused;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.m
================================================
//
// PTHotKeyCenter.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTHotKeyCenter.h"
#import "PTHotKey.h"
#import "PTKeyCombo.h"
@interface PTHotKeyCenter (Private)
- (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKey;
- (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID;
- (void)_updateEventHandler;
- (void)_hotKeyDown: (PTHotKey*)hotKey;
- (void)_hotKeyUp: (PTHotKey*)hotKey;
static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon );
@end
@implementation PTHotKeyCenter
static PTHotKeyCenter *_sharedHotKeyCenter = nil;
+ (PTHotKeyCenter*)sharedCenter
{
if( _sharedHotKeyCenter == nil )
{
_sharedHotKeyCenter = [[self alloc] init];
}
return _sharedHotKeyCenter;
}
- (id)init
{
self = [super init];
if( self )
{
mHotKeys = [[NSMutableDictionary alloc] init];
}
return self;
}
#pragma mark -
- (BOOL)registerHotKey: (PTHotKey*)hotKey
{
if ( mIsPaused == NO )
{
OSStatus err;
EventHotKeyID hotKeyID;
EventHotKeyRef carbonHotKey;
if( [[self allHotKeys] containsObject: hotKey] == YES )
[self unregisterHotKey: hotKey];
if( [[hotKey keyCombo] isValidHotKeyCombo] == NO )
return YES;
hotKeyID.signature = 'PTHk';
hotKeyID.id = ++mHotKeyCount;
err = RegisterEventHotKey( (SInt32)[[hotKey keyCombo] keyCode],
(UInt32)[[hotKey keyCombo] modifiers],
hotKeyID,
GetEventDispatcherTarget(),
0,
&carbonHotKey );
if( err )
return NO;
[hotKey setCarbonHotKeyID:hotKeyID.id];
[hotKey setCarbonEventHotKeyRef:carbonHotKey];
if( hotKey )
[mHotKeys setObject: hotKey forKey: [NSNumber numberWithInteger:hotKeyID.id]];
[self _updateEventHandler];
}
else
{
EventHotKeyID hotKeyID = {'PTHk', ++mHotKeyCount};
[hotKey setCarbonHotKeyID:hotKeyID.id];
if( hotKey )
[mHotKeys setObject: hotKey forKey: [NSNumber numberWithInteger:hotKeyID.id]];
}
return YES;
}
- (void)unregisterHotKey: (PTHotKey*)hotKey
{
if ( mIsPaused == NO )
{
EventHotKeyRef carbonHotKey;
if( [[self allHotKeys] containsObject: hotKey] == NO )
return;
carbonHotKey = [hotKey carbonEventHotKeyRef];
if( carbonHotKey )
{
UnregisterEventHotKey( carbonHotKey );
//Watch as we ignore 'err':
[mHotKeys removeObjectForKey: [NSNumber numberWithInteger:[hotKey carbonHotKeyID]]];
[hotKey setCarbonHotKeyID:0];
[hotKey setCarbonEventHotKeyRef:NULL];
[self _updateEventHandler];
//See that? Completely ignored
}
}
else
{
[mHotKeys removeObjectForKey: [NSNumber numberWithInteger:[hotKey carbonHotKeyID]]];
[hotKey setCarbonHotKeyID:0];
[hotKey setCarbonEventHotKeyRef:NULL];
}
}
- (NSArray*)allHotKeys
{
return [mHotKeys allValues];
}
- (PTHotKey*)hotKeyWithIdentifier: (id)ident
{
NSEnumerator* hotKeysEnum = [[self allHotKeys] objectEnumerator];
PTHotKey* hotKey;
if( !ident )
return nil;
while( (hotKey = [hotKeysEnum nextObject]) != nil )
{
if( [[hotKey identifier] isEqual: ident] )
return hotKey;
}
return nil;
}
#pragma mark -
- (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKeyRef
{
NSEnumerator *e = [mHotKeys objectEnumerator];
PTHotKey *hotkey = nil;
while( (hotkey = [e nextObject]) )
{
if( [hotkey carbonEventHotKeyRef] == carbonHotKeyRef )
return hotkey;
}
return nil;
}
- (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID
{
return [mHotKeys objectForKey:[NSNumber numberWithInteger:hotKeyID.id]];
}
- (void)_updateEventHandler
{
if( [mHotKeys count] && mEventHandlerInstalled == NO )
{
EventTypeSpec eventSpec[2] = {
{ kEventClassKeyboard, kEventHotKeyPressed },
{ kEventClassKeyboard, kEventHotKeyReleased }
};
InstallEventHandler( GetEventDispatcherTarget(),
(EventHandlerProcPtr)hotKeyEventHandler,
2, eventSpec, nil, &mEventHandler);
mEventHandlerInstalled = YES;
}
}
- (void)_hotKeyDown: (PTHotKey*)hotKey
{
[hotKey invoke];
}
- (void)_hotKeyUp: (PTHotKey*)hotKey
{
[hotKey uninvoke];
}
- (void)sendEvent: (NSEvent*)event
{
// Not sure why this is needed? - Andy Kim (Aug 23, 2009)
short subType;
EventHotKeyRef carbonHotKey;
if( [event type] == NSEventTypeSystemDefined )
{
subType = [event subtype];
if( subType == 6 ) //6 is hot key down
{
carbonHotKey= (EventHotKeyRef)[event data1]; //data1 is our hot key ref
if( carbonHotKey != nil )
{
PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey];
[self _hotKeyDown: hotKey];
}
}
else if( subType == 9 ) //9 is hot key up
{
carbonHotKey= (EventHotKeyRef)[event data1];
if( carbonHotKey != nil )
{
PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey];
[self _hotKeyUp: hotKey];
}
}
}
}
- (OSStatus)sendCarbonEvent: (EventRef)event
{
OSStatus err;
EventHotKeyID hotKeyID;
PTHotKey* hotKey;
NSAssert( GetEventClass( event ) == kEventClassKeyboard, @"Unknown event class" );
err = GetEventParameter( event,
kEventParamDirectObject,
typeEventHotKeyID,
nil,
sizeof(EventHotKeyID),
nil,
&hotKeyID );
if( err )
return err;
if( hotKeyID.signature != 'PTHk' )
return eventNotHandledErr;
if (hotKeyID.id == 0)
return eventNotHandledErr;
hotKey = [self _hotKeyForCarbonHotKeyID:hotKeyID];
switch( GetEventKind( event ) )
{
case kEventHotKeyPressed:
[self _hotKeyDown: hotKey];
break;
case kEventHotKeyReleased:
[self _hotKeyUp: hotKey];
break;
default:
return eventNotHandledErr;
break;
}
return noErr;
}
- (void)pause
{
if ( mIsPaused )
return;
mIsPaused = YES;
for (NSNumber *hotKeyID in mHotKeys)
{
PTHotKey *hotKey = [mHotKeys objectForKey:hotKeyID];
EventHotKeyRef carbonHotKey = [hotKey carbonEventHotKeyRef];
UnregisterEventHotKey( carbonHotKey );
[hotKey setCarbonEventHotKeyRef:NULL];
}
if (mEventHandler != NULL)
{
RemoveEventHandler(mEventHandler);
mEventHandler = NULL;
mEventHandlerInstalled = NO;
}
}
- (void)resume
{
if ( mIsPaused == NO)
return;
mIsPaused = NO;
for (NSNumber *hotKeyIDNumber in mHotKeys)
{
PTHotKey *hotKey = [mHotKeys objectForKey:hotKeyIDNumber];
EventHotKeyRef carbonHotKey = NULL;
EventHotKeyID hotKeyID;
hotKeyID.signature = 'PTHk';
hotKeyID.id = [hotKey carbonHotKeyID];
RegisterEventHotKey( (SInt32)[[hotKey keyCombo] keyCode],
(UInt32)[[hotKey keyCombo] modifiers],
hotKeyID,
GetEventDispatcherTarget(),
0,
&carbonHotKey );
[hotKey setCarbonEventHotKeyRef:carbonHotKey];
}
[self _updateEventHandler];
}
- (BOOL)isPaused
{
return mIsPaused;
}
static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon )
{
return [[PTHotKeyCenter sharedCenter] sendCarbonEvent: inEvent];
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.h
================================================
//
// PTKeyCodeTranslator.h
// Chercher
//
// Created by Finlay Dobbie on Sat Oct 11 2003.
// Copyright (c) 2003 Cliché Software. All rights reserved.
//
#import
@interface PTKeyCodeTranslator : NSObject
{
TISInputSourceRef keyboardLayout;
const UCKeyboardLayout *uchrData;
UInt32 keyTranslateState;
UInt32 deadKeyState;
}
+ (id)currentTranslator;
- (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout;
- (NSString *)translateKeyCode:(short)keyCode;
- (TISInputSourceRef)keyboardLayout;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.m
================================================
//
// PTKeyCodeTranslator.m
// Chercher
//
// Created by Finlay Dobbie on Sat Oct 11 2003.
// Copyright (c) 2003 Cliché Software. All rights reserved.
//
#import "PTKeyCodeTranslator.h"
@implementation PTKeyCodeTranslator
+ (id)currentTranslator
{
static PTKeyCodeTranslator *current = nil;
TISInputSourceRef currentLayout = TISCopyCurrentKeyboardLayoutInputSource();
if (current == nil) {
current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout];
} else if ([current keyboardLayout] != currentLayout) {
current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout];
}
CFRelease(currentLayout);
return current;
}
- (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout
{
if ((self = [super init]) != nil) {
keyboardLayout = aLayout;
CFRetain(keyboardLayout);
CFDataRef uchr = TISGetInputSourceProperty( keyboardLayout , kTISPropertyUnicodeKeyLayoutData );
uchrData = ( const UCKeyboardLayout* )CFDataGetBytePtr(uchr);
}
return self;
}
- (void)dealloc
{
CFRelease(keyboardLayout);
}
- (NSString *)translateKeyCode:(short)keyCode {
UniCharCount maxStringLength = 4, actualStringLength;
UniChar unicodeString[4];
UCKeyTranslate( uchrData, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStringLength, &actualStringLength, unicodeString );
return [NSString stringWithCharacters:unicodeString length:1];
}
- (TISInputSourceRef)keyboardLayout {
return keyboardLayout;
}
- (NSString *)description {
NSString *kind;
kind = @"uchr";
NSString *layoutName;
layoutName = (__bridge NSString *)(TISGetInputSourceProperty( keyboardLayout, kTISPropertyLocalizedName ));
return [NSString stringWithFormat:@"PTKeyCodeTranslator layout=%@ (%@)", layoutName, kind];
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.h
================================================
//
// PTKeyCombo.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import
@interface PTKeyCombo : NSObject
{
NSInteger mKeyCode;
NSUInteger mModifiers;
}
+ (id)clearKeyCombo;
+ (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers;
- (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers;
- (id)initWithPlistRepresentation: (id)plist;
- (id)plistRepresentation;
- (BOOL)isEqual: (PTKeyCombo*)combo;
- (NSInteger)keyCode;
- (NSUInteger)modifiers;
- (BOOL)isClearCombo;
- (BOOL)isValidHotKeyCombo;
@end
@interface PTKeyCombo (UserDisplayAdditions)
- (NSString*)keyCodeString;
- (NSUInteger)modifierMask;
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.m
================================================
//
// PTKeyCombo.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTKeyCombo.h"
#import "PTKeyCodeTranslator.h"
@implementation PTKeyCombo
+ (id)clearKeyCombo
{
return [self keyComboWithKeyCode: -1 modifiers: -1];
}
+ (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers
{
return [[self alloc] initWithKeyCode: keyCode modifiers: modifiers];
}
- (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers
{
self = [super init];
if( self )
{
switch ( keyCode )
{
case kVK_F1:
case kVK_F2:
case kVK_F3:
case kVK_F4:
case kVK_F5:
case kVK_F6:
case kVK_F7:
case kVK_F8:
case kVK_F9:
case kVK_F10:
case kVK_F11:
case kVK_F12:
case kVK_F13:
case kVK_F14:
case kVK_F15:
case kVK_F16:
case kVK_F17:
case kVK_F18:
case kVK_F19:
case kVK_F20:
mModifiers = modifiers | NSEventModifierFlagFunction;
break;
default:
mModifiers = modifiers;
break;
}
mKeyCode = keyCode;
}
return self;
}
- (id)initWithPlistRepresentation: (id)plist
{
int keyCode, modifiers;
if( !plist || ![plist count] )
{
keyCode = -1;
modifiers = -1;
}
else
{
keyCode = [[plist objectForKey: @"keyCode"] intValue];
if( keyCode < 0 ) keyCode = -1;
modifiers = [[plist objectForKey: @"modifiers"] intValue];
if( modifiers <= 0 ) modifiers = -1;
}
return [self initWithKeyCode: keyCode modifiers: modifiers];
}
- (id)plistRepresentation
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger: [self keyCode]], @"keyCode",
[NSNumber numberWithInteger: [self modifiers]], @"modifiers",
nil];
}
- (id)copyWithZone:(NSZone*)zone;
{
return self;
}
- (BOOL)isEqual: (PTKeyCombo*)combo
{
return [self keyCode] == [combo keyCode] &&
[self modifiers] == [combo modifiers];
}
#pragma mark -
- (NSInteger)keyCode
{
return mKeyCode;
}
- (NSUInteger)modifiers
{
return mModifiers;
}
- (BOOL)isValidHotKeyCombo
{
return mKeyCode >= 0 && mModifiers > 0;
}
- (BOOL)isClearCombo
{
return mKeyCode == -1 && mModifiers == 0;
}
@end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/README.md
================================================
ShortcutRecorder 2
====================


The only user interface control to record shortcuts. For Mac OS X 10.6+, 64bit.
- :microscope: Support for Xcode 6 Quick Help
- :microscope: Support for Xcode 6 Interface Builder integration
- Fresh Look & Feel (brought to you by [Wireload](http://wireload.net) and [John Wells](https://github.com/jwells89))
- With Retina support
- Auto Layout ready
- Correct drawing on Layer-backed and Layer-hosted views
- Accessibility for people with disabilities
- Revised codebase with Automatic Reference Counting support
- Translated into 24 languages
Includes framework to set global shortcuts (PTHotKey).
Get Sources
-----------
The preferred way to add the ShortcutRecorder to your project is to use git submodules:
`git submodule add git://github.com/Kentzo/ShortcutRecorder.git`
You can download sources from the site as well.
Integrate into your project
---------------------------
First, add ShortcutRecorder.xcodeproj to your workspace via Xcode ([Apple docs](https://developer.apple.com/library/mac/recipes/xcode_help-structure_navigator/articles/Adding_an_Existing_Project_to_a_Workspace.html)). Don't have a workspace? No problem, just add ShortcutRecorder.xcodeproj via the "Add Files to" dialog.
Next step is to ensure your target is linked against the ShortcutRecorder or/and PTHotKey frameworks ([Apple docs](http://developer.apple.com/library/ios/#recipes/xcode_help-project_editor/Articles/AddingaLibrarytoaTarget.html#//apple_ref/doc/uid/TP40010155-CH17)). Desired frameworks will be listed under *Workspace*.
Now it's time to make frameworks part of your app. To do this, you need to add custom Build Phase ([Apple docs](http://developer.apple.com/library/ios/#recipes/xcode_help-project_editor/Articles/CreatingaCopyFilesBuildPhase.html)). Remember to set *Destination* to *Frameworks* and clean up *Subpath*.
Finally, ensure your app will find frameworks upon start. Open Build Settings of your target, look up *Runtime Search Paths*. Add `@executable_path/../Frameworks` to the list of paths.
Add control in Interface Builder
--------------------------------
Since Xcode 4 Apple removed Interface Builder Plugins. You can only use it to add and position/resize ShortcutRecorder control. To do this, add Custom View and set its class to SRRecorderControl.
SRRecorderControl has fixed height of 25 points so ensure you do not use autoresizing masks/layout rules which allows vertical resizing. I recommend you to pin height in case you're using Auto Layout.
Usage
-----
First, we want to keep value of the control across relaunches of the app. We can simply achieve this by using NSUserDefaultsController and bindings:
[self.pingShortcutRecorder bind:NSValueBinding
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:@"values.ping"
options:nil];
The value can be used to set key equivalent of NSMenuItem or NSButton. It can also be used to register a global shortcut.
Setting key equivalent of NSMenuItem using bindings:
[self.pingItem bind:@"keyEquivalent"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentTransformer new]}];
[self.pingItem bind:@"keyEquivalentModifierMask"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentModifierMaskTransformer new]}];
Setting key equivalent of NSButton using bindings:
[self.pingButton bind:@"keyEquivalent"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentTransformer new]}];
[self.pingButton bind:@"keyEquivalentModifierMask"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentModifierMaskTransformer new]}];
Setting global shortcut using PTHotKeyCenter:
PTHotKeyCenter *hotKeyCenter = [PTHotKeyCenter sharedCenter];
PTHotKey *oldHotKey = [hotKeyCenter hotKeyWithIdentifier:aKeyPath];
[hotKeyCenter unregisterHotKey:oldHotKey];
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:aKeyPath
keyCombo:newShortcut
target:self
action:@selector(ping:)];
[hotKeyCenter registerHotKey:newHotKey];
Key Equivalents and Keyboard Layout
----------------------------------------------------
While ShortcutRecorder keeps your shortcuts as combination of *key code* and modifier masks, key equivalents are expressed using *key character* and modifier mask. The difference is that position of key code on keyboard does not depend on current keyboard layout while position of key character does.
ShortcutRecorder includes two special transformers to simplify binding to the key equivalents of NSMenuItem and NSButton:
- SRKeyEquivalentTransformer
- SRKeyEquivalentModifierMaskTransformer
SRKeyEquivalentTransformer uses ASCII keyboard layout to convert key code into character, therefore resulting character does not depend on keyboard layout.
The drawback is that position of the character on keyboard may change depending on layout and used modifier keys (primarly Option and Shift).
NSButton
--------
If you're going to bind ShortcutRecorder to key equivalent of NSButton, I encourage you to require `NSCommandKeyMask`.
This is because NSButton handles key equivalents very strange. Rather than investigating full information of the keyboard event, it just asks for `charactersIgnoringModifiers`
and compares returned value with its `keyEquivalent`. Unfortunately, Cocoa returns layout-independent (ASCII) representation of characters only when NSCommandKeyMask is set.
If it's not set, assigned shortcut likely won't work with other layouts.
Questions
---------
Still have questions? [Create an issue](https://github.com/Kentzo/ShortcutRecorder/issues/new) immediately and feel free to ping me.
Paid Support
------------
If functional you need is missing but you're ready to pay for it, feel free to contact me. If not, create an issue anyway, I'll take a look as soon as I can.
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/Resources/LICENSE.txt
================================================
Copyright (c) 2006, contributors to ShortcutRecorder. (See the contributors listed in detail later in the file, or see .)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of the contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=====================================================================
Contributors to Shortcut Recorder, in no order in particular:
Jesper, waffle software, . Initial idea and concept, first shot at implementation using NSView.
David Dauer, . Refinement, cleaner reimplementation, documentation, IB Palette.
Jamie Kirkpatrick, Kirk Consulting Ltd, . Further modularisation and re-factoring, and general bug fixes.
Ilya Kulakov, . ShortcutRecorder 2.0 and further support.
Alexander Ljungberg, . Graphics for ShortcutRecorder 2.0
=====================================================================
Some rights reserved:
For more information, visit
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.podspec
================================================
Pod::Spec.new do |s|
s.name = 'ShortcutRecorder'
s.homepage = 'https://github.com/Kentzo/ShortcutRecorder'
s.summary = ''
s.version = '2.17'
s.source = { :git => 'git://github.com/Kentzo/ShortcutRecorder.git', :branch => 'master' }
s.author = { 'Ilya Kulakov' => 'kulakov.ilya@gmail.com' }
s.frameworks = 'Carbon', 'Cocoa'
s.platform = :osx, "10.6"
s.subspec 'Core' do |core|
core.source_files = 'Library/*.{h,m}'
core.resource_bundles = { "ShortcutRecorder" => ['Resources/*.lproj', 'Resources/*.png'] }
core.requires_arc = true
core.prefix_header_file = 'Library/Prefix.pch'
end
s.subspec 'PTHotKey' do |hotkey|
hotkey.source_files = 'PTHotKey/*.{h,m}'
hotkey.requires_arc = false
hotkey.dependency 'ShortcutRecorder/Core'
end
end
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
939837950DA429EC007F53F3 /* SRRecorderControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B8E29C109CDB9360085E9ED /* SRRecorderControl.m */; };
939837980DA429EC007F53F3 /* SRKeyCodeTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 74C3670D0A246B4900B69171 /* SRKeyCodeTransformer.m */; };
939837990DA429EC007F53F3 /* SRValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 74C3670F0A246B4900B69171 /* SRValidator.m */; };
9398379A0DA429EC007F53F3 /* SRCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 74C367110A246B4900B69171 /* SRCommon.m */; };
939839390DA4350B007F53F3 /* ShortcutRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 939837B50DA42DFB007F53F3 /* ShortcutRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; };
9398393B0DA4350B007F53F3 /* SRRecorderControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B8E29C009CDB9360085E9ED /* SRRecorderControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
9398393E0DA4350B007F53F3 /* SRKeyCodeTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 74C3670C0A246B4900B69171 /* SRKeyCodeTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };
9398393F0DA4350B007F53F3 /* SRValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = 74C3670E0A246B4900B69171 /* SRValidator.h */; settings = {ATTRIBUTES = (Public, ); }; };
939839400DA4350B007F53F3 /* SRCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 74C367100A246B4900B69171 /* SRCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
BA547C271A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C011A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left.png */; };
BA547C281A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C021A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png */; };
BA547C291A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C031A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png */; };
BA547C2A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C041A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png */; };
BA547C2B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C051A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right.png */; };
BA547C2C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C061A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png */; };
BA547C2D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C071A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left.png */; };
BA547C2E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C081A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left@2x.png */; };
BA547C2F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C091A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle.png */; };
BA547C301A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle@2x.png */; };
BA547C311A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right.png */; };
BA547C321A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right@2x.png */; };
BA547C331A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left.png */; };
BA547C341A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left@2x.png */; };
BA547C351A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C0F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle.png */; };
BA547C361A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C101A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle@2x.png */; };
BA547C371A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C111A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right.png */; };
BA547C381A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C121A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right@2x.png */; };
BA547C391A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C131A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png */; };
BA547C3A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C141A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png */; };
BA547C3B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C151A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png */; };
BA547C3C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C161A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png */; };
BA547C3D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C171A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png */; };
BA547C3E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C181A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png */; };
BA547C3F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C191A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left.png */; };
BA547C401A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left@2x.png */; };
BA547C411A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle.png */; };
BA547C421A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle@2x.png */; };
BA547C431A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right.png */; };
BA547C441A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right@2x.png */; };
BA547C451A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C1F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted.png */; };
BA547C461A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C201A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted@2x.png */; };
BA547C471A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C211A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear.png */; };
BA547C481A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C221A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear@2x.png */; };
BA547C491A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C231A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted.png */; };
BA547C4A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C241A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted@2x.png */; };
BA547C4B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C251A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback.png */; };
BA547C4C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BA547C261A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback@2x.png */; };
E20A897917F3322300502E33 /* shortcut-recorder-bezel-disabled-left.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897317F3322300502E33 /* shortcut-recorder-bezel-disabled-left.png */; };
E20A897A17F3322300502E33 /* shortcut-recorder-bezel-disabled-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897417F3322300502E33 /* shortcut-recorder-bezel-disabled-left@2x.png */; };
E20A897B17F3322300502E33 /* shortcut-recorder-bezel-disabled-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897517F3322300502E33 /* shortcut-recorder-bezel-disabled-middle.png */; };
E20A897C17F3322300502E33 /* shortcut-recorder-bezel-disabled-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897617F3322300502E33 /* shortcut-recorder-bezel-disabled-middle@2x.png */; };
E20A897D17F3322300502E33 /* shortcut-recorder-bezel-disabled-right.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897717F3322300502E33 /* shortcut-recorder-bezel-disabled-right.png */; };
E20A897E17F3322300502E33 /* shortcut-recorder-bezel-disabled-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E20A897817F3322300502E33 /* shortcut-recorder-bezel-disabled-right@2x.png */; };
E225E4671679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4471679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left.png */; };
E225E4681679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4481679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left@2x.png */; };
E225E4691679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4491679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle.png */; };
E225E46A1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44A1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle@2x.png */; };
E225E46B1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44B1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right.png */; };
E225E46C1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44C1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right@2x.png */; };
E225E46D1679E30E00A00529 /* shortcut-recorder-bezel-editing-left.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44D1679E30E00A00529 /* shortcut-recorder-bezel-editing-left.png */; };
E225E46E1679E30E00A00529 /* shortcut-recorder-bezel-editing-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44E1679E30E00A00529 /* shortcut-recorder-bezel-editing-left@2x.png */; };
E225E46F1679E30E00A00529 /* shortcut-recorder-bezel-editing-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E44F1679E30E00A00529 /* shortcut-recorder-bezel-editing-middle.png */; };
E225E4701679E30E00A00529 /* shortcut-recorder-bezel-editing-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4501679E30E00A00529 /* shortcut-recorder-bezel-editing-middle@2x.png */; };
E225E4711679E30E00A00529 /* shortcut-recorder-bezel-editing-right.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4511679E30E00A00529 /* shortcut-recorder-bezel-editing-right.png */; };
E225E4721679E30E00A00529 /* shortcut-recorder-bezel-editing-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4521679E30E00A00529 /* shortcut-recorder-bezel-editing-right@2x.png */; };
E225E4731679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4531679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left.png */; };
E225E4741679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4541679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left@2x.png */; };
E225E4751679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4551679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle.png */; };
E225E4761679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4561679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle@2x.png */; };
E225E4771679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4571679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right.png */; };
E225E4781679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4581679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right@2x.png */; };
E225E4791679E30E00A00529 /* shortcut-recorder-bezel-left.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4591679E30E00A00529 /* shortcut-recorder-bezel-left.png */; };
E225E47A1679E30E00A00529 /* shortcut-recorder-bezel-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45A1679E30E00A00529 /* shortcut-recorder-bezel-left@2x.png */; };
E225E47B1679E30E00A00529 /* shortcut-recorder-bezel-middle.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45B1679E30E00A00529 /* shortcut-recorder-bezel-middle.png */; };
E225E47C1679E30E00A00529 /* shortcut-recorder-bezel-middle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45C1679E30E00A00529 /* shortcut-recorder-bezel-middle@2x.png */; };
E225E47D1679E30E00A00529 /* shortcut-recorder-bezel-right.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45D1679E30E00A00529 /* shortcut-recorder-bezel-right.png */; };
E225E47E1679E30E00A00529 /* shortcut-recorder-bezel-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45E1679E30E00A00529 /* shortcut-recorder-bezel-right@2x.png */; };
E225E47F1679E30E00A00529 /* shortcut-recorder-clear-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E45F1679E30E00A00529 /* shortcut-recorder-clear-highlighted.png */; };
E225E4801679E30E00A00529 /* shortcut-recorder-clear-highlighted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4601679E30E00A00529 /* shortcut-recorder-clear-highlighted@2x.png */; };
E225E4811679E30E00A00529 /* shortcut-recorder-clear.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4611679E30E00A00529 /* shortcut-recorder-clear.png */; };
E225E4821679E30E00A00529 /* shortcut-recorder-clear@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4621679E30E00A00529 /* shortcut-recorder-clear@2x.png */; };
E225E4831679E30E00A00529 /* shortcut-recorder-snapback-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4631679E30E00A00529 /* shortcut-recorder-snapback-highlighted.png */; };
E225E4841679E30E00A00529 /* shortcut-recorder-snapback-highlighted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4641679E30E00A00529 /* shortcut-recorder-snapback-highlighted@2x.png */; };
E225E4851679E30E00A00529 /* shortcut-recorder-snapback.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4651679E30E00A00529 /* shortcut-recorder-snapback.png */; };
E225E4861679E30E00A00529 /* shortcut-recorder-snapback@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E225E4661679E30E00A00529 /* shortcut-recorder-snapback@2x.png */; };
E273123A1349EDB500A84433 /* PTHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B8E2A0309CDBADE0085E9ED /* PTHotKey.h */; settings = {ATTRIBUTES = (Public, ); }; };
E273123B1349EDB500A84433 /* PTHotKeyCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B8E2A0509CDBADE0085E9ED /* PTHotKeyCenter.h */; settings = {ATTRIBUTES = (Public, ); }; };
E273123C1349EDB500A84433 /* PTKeyCodeTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = A1125B75104C8AF3005C6F7B /* PTKeyCodeTranslator.h */; settings = {ATTRIBUTES = (Public, ); }; };
E273123D1349EDB500A84433 /* PTKeyCombo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B8E2A0709CDBADE0085E9ED /* PTKeyCombo.h */; settings = {ATTRIBUTES = (Public, ); }; };
E27312401349EDCA00A84433 /* PTHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B8E2A0409CDBADE0085E9ED /* PTHotKey.m */; };
E27312411349EDCA00A84433 /* PTHotKeyCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B8E2A0609CDBADE0085E9ED /* PTHotKeyCenter.m */; };
E27312421349EDCA00A84433 /* PTKeyCodeTranslator.m in Sources */ = {isa = PBXBuildFile; fileRef = A1125B76104C8AF3005C6F7B /* PTKeyCodeTranslator.m */; };
E27312431349EDCA00A84433 /* PTKeyCombo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B8E2A0809CDBADE0085E9ED /* PTKeyCombo.m */; };
E273124C1349EE6500A84433 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E273124B1349EE6500A84433 /* Carbon.framework */; };
E2741AC51673C79F00A139BD /* ShortcutRecorder.strings in Resources */ = {isa = PBXBuildFile; fileRef = E2741AC31673C79F00A139BD /* ShortcutRecorder.strings */; };
E2741ADF1673C83800A139BD /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = E2741ADE1673C83800A139BD /* LICENSE.txt */; };
E2741AE11673C90B00A139BD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2741AE01673C90B00A139BD /* Cocoa.framework */; };
E28113AD167B8A9D001E118E /* SRModifierFlagsTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = E28113AB167B8A9D001E118E /* SRModifierFlagsTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };
E28113AE167B8A9D001E118E /* SRModifierFlagsTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = E28113AC167B8A9D001E118E /* SRModifierFlagsTransformer.m */; };
E2BE924D16ABEFE400827E8C /* SRKeyEquivalentTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = E2BE924B16ABEFE400827E8C /* SRKeyEquivalentTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };
E2BE924E16ABEFE400827E8C /* SRKeyEquivalentTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE924C16ABEFE400827E8C /* SRKeyEquivalentTransformer.m */; };
E2BE925216ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = E2BE925016ABF84100827E8C /* SRKeyEquivalentModifierMaskTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };
E2BE925316ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE925116ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.m */; };
E2BE927C16AC052000827E8C /* PTHotKey+ShortcutRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = E279508E131A7498008AE1DA /* PTHotKey+ShortcutRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; };
E2BE927D16AC052600827E8C /* PTHotKey+ShortcutRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = E279508F131A7498008AE1DA /* PTHotKey+ShortcutRecorder.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0B8E29C009CDB9360085E9ED /* SRRecorderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRRecorderControl.h; path = Library/SRRecorderControl.h; sourceTree = ""; };
0B8E29C109CDB9360085E9ED /* SRRecorderControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRRecorderControl.m; path = Library/SRRecorderControl.m; sourceTree = ""; };
0B8E2A0309CDBADE0085E9ED /* PTHotKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTHotKey.h; sourceTree = ""; };
0B8E2A0409CDBADE0085E9ED /* PTHotKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PTHotKey.m; sourceTree = ""; };
0B8E2A0509CDBADE0085E9ED /* PTHotKeyCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTHotKeyCenter.h; sourceTree = ""; };
0B8E2A0609CDBADE0085E9ED /* PTHotKeyCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PTHotKeyCenter.m; sourceTree = ""; };
0B8E2A0709CDBADE0085E9ED /* PTKeyCombo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTKeyCombo.h; sourceTree = ""; };
0B8E2A0809CDBADE0085E9ED /* PTKeyCombo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PTKeyCombo.m; sourceTree = ""; };
0D6B246B180304DE00CE1142 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
0D6B246C180304DE00CE1142 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
0D6B246D180304DE00CE1142 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
0D6B2487180304DE00CE1142 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Prefix.pch; path = Library/Prefix.pch; sourceTree = ""; };
3552066127AF63DC000EF08F /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ShortcutRecorder.strings; sourceTree = ""; };
74C3670C0A246B4900B69171 /* SRKeyCodeTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRKeyCodeTransformer.h; path = Library/SRKeyCodeTransformer.h; sourceTree = ""; };
74C3670D0A246B4900B69171 /* SRKeyCodeTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRKeyCodeTransformer.m; path = Library/SRKeyCodeTransformer.m; sourceTree = ""; };
74C3670E0A246B4900B69171 /* SRValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRValidator.h; path = Library/SRValidator.h; sourceTree = ""; };
74C3670F0A246B4900B69171 /* SRValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRValidator.m; path = Library/SRValidator.m; sourceTree = ""; };
74C367100A246B4900B69171 /* SRCommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SRCommon.h; path = Library/SRCommon.h; sourceTree = ""; };
74C367110A246B4900B69171 /* SRCommon.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = SRCommon.m; path = Library/SRCommon.m; sourceTree = ""; };
939837800DA42965007F53F3 /* ShortcutRecorder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ShortcutRecorder.framework; sourceTree = BUILT_PRODUCTS_DIR; };
939837B50DA42DFB007F53F3 /* ShortcutRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ShortcutRecorder.h; path = Library/ShortcutRecorder.h; sourceTree = SOURCE_ROOT; };
9AA522D823416E6A00C9E005 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/ShortcutRecorder.strings; sourceTree = ""; };
A1125B75104C8AF3005C6F7B /* PTKeyCodeTranslator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTKeyCodeTranslator.h; sourceTree = ""; };
A1125B76104C8AF3005C6F7B /* PTKeyCodeTranslator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PTKeyCodeTranslator.m; sourceTree = ""; };
BA547C011A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-left.png"; sourceTree = ""; };
BA547C021A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png"; sourceTree = ""; };
BA547C031A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png"; sourceTree = ""; };
BA547C041A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png"; sourceTree = ""; };
BA547C051A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-right.png"; sourceTree = ""; };
BA547C061A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png"; sourceTree = ""; };
BA547C071A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-left.png"; sourceTree = ""; };
BA547C081A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-left@2x.png"; sourceTree = ""; };
BA547C091A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-middle.png"; sourceTree = ""; };
BA547C0A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-middle@2x.png"; sourceTree = ""; };
BA547C0B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-right.png"; sourceTree = ""; };
BA547C0C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-disabled-right@2x.png"; sourceTree = ""; };
BA547C0D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-left.png"; sourceTree = ""; };
BA547C0E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-left@2x.png"; sourceTree = ""; };
BA547C0F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-middle.png"; sourceTree = ""; };
BA547C101A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-middle@2x.png"; sourceTree = ""; };
BA547C111A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-right.png"; sourceTree = ""; };
BA547C121A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-editing-right@2x.png"; sourceTree = ""; };
BA547C131A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png"; sourceTree = ""; };
BA547C141A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png"; sourceTree = ""; };
BA547C151A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png"; sourceTree = ""; };
BA547C161A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png"; sourceTree = ""; };
BA547C171A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png"; sourceTree = ""; };
BA547C181A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png"; sourceTree = ""; };
BA547C191A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-left.png"; sourceTree = ""; };
BA547C1A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-left@2x.png"; sourceTree = ""; };
BA547C1B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-middle.png"; sourceTree = ""; };
BA547C1C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-middle@2x.png"; sourceTree = ""; };
BA547C1D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-right.png"; sourceTree = ""; };
BA547C1E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-bezel-right@2x.png"; sourceTree = ""; };
BA547C1F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-clear-highlighted.png"; sourceTree = ""; };
BA547C201A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-clear-highlighted@2x.png"; sourceTree = ""; };
BA547C211A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-clear.png"; sourceTree = ""; };
BA547C221A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-clear@2x.png"; sourceTree = ""; };
BA547C231A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-snapback-highlighted.png"; sourceTree = ""; };
BA547C241A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-snapback-highlighted@2x.png"; sourceTree = ""; };
BA547C251A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-snapback.png"; sourceTree = ""; };
BA547C261A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-yosemite-snapback@2x.png"; sourceTree = ""; };
E20A897317F3322300502E33 /* shortcut-recorder-bezel-disabled-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-left.png"; sourceTree = ""; };
E20A897417F3322300502E33 /* shortcut-recorder-bezel-disabled-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-left@2x.png"; sourceTree = ""; };
E20A897517F3322300502E33 /* shortcut-recorder-bezel-disabled-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-middle.png"; sourceTree = ""; };
E20A897617F3322300502E33 /* shortcut-recorder-bezel-disabled-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-middle@2x.png"; sourceTree = ""; };
E20A897717F3322300502E33 /* shortcut-recorder-bezel-disabled-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-right.png"; sourceTree = ""; };
E20A897817F3322300502E33 /* shortcut-recorder-bezel-disabled-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-disabled-right@2x.png"; sourceTree = ""; };
E225E4471679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-left.png"; sourceTree = ""; };
E225E4481679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-left@2x.png"; sourceTree = ""; };
E225E4491679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-middle.png"; sourceTree = ""; };
E225E44A1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-middle@2x.png"; sourceTree = ""; };
E225E44B1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-right.png"; sourceTree = ""; };
E225E44C1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-blue-highlighted-right@2x.png"; sourceTree = ""; };
E225E44D1679E30E00A00529 /* shortcut-recorder-bezel-editing-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-left.png"; sourceTree = ""; };
E225E44E1679E30E00A00529 /* shortcut-recorder-bezel-editing-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-left@2x.png"; sourceTree = ""; };
E225E44F1679E30E00A00529 /* shortcut-recorder-bezel-editing-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-middle.png"; sourceTree = ""; };
E225E4501679E30E00A00529 /* shortcut-recorder-bezel-editing-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-middle@2x.png"; sourceTree = ""; };
E225E4511679E30E00A00529 /* shortcut-recorder-bezel-editing-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-right.png"; sourceTree = ""; };
E225E4521679E30E00A00529 /* shortcut-recorder-bezel-editing-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-editing-right@2x.png"; sourceTree = ""; };
E225E4531679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-left.png"; sourceTree = ""; };
E225E4541679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-left@2x.png"; sourceTree = ""; };
E225E4551679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-middle.png"; sourceTree = ""; };
E225E4561679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-middle@2x.png"; sourceTree = ""; };
E225E4571679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-right.png"; sourceTree = ""; };
E225E4581679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-graphite-highlighted-right@2x.png"; sourceTree = ""; };
E225E4591679E30E00A00529 /* shortcut-recorder-bezel-left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-left.png"; sourceTree = ""; };
E225E45A1679E30E00A00529 /* shortcut-recorder-bezel-left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-left@2x.png"; sourceTree = ""; };
E225E45B1679E30E00A00529 /* shortcut-recorder-bezel-middle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-middle.png"; sourceTree = ""; };
E225E45C1679E30E00A00529 /* shortcut-recorder-bezel-middle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-middle@2x.png"; sourceTree = ""; };
E225E45D1679E30E00A00529 /* shortcut-recorder-bezel-right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-right.png"; sourceTree = ""; };
E225E45E1679E30E00A00529 /* shortcut-recorder-bezel-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-bezel-right@2x.png"; sourceTree = ""; };
E225E45F1679E30E00A00529 /* shortcut-recorder-clear-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-clear-highlighted.png"; sourceTree = ""; };
E225E4601679E30E00A00529 /* shortcut-recorder-clear-highlighted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-clear-highlighted@2x.png"; sourceTree = ""; };
E225E4611679E30E00A00529 /* shortcut-recorder-clear.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-clear.png"; sourceTree = ""; };
E225E4621679E30E00A00529 /* shortcut-recorder-clear@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-clear@2x.png"; sourceTree = ""; };
E225E4631679E30E00A00529 /* shortcut-recorder-snapback-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-snapback-highlighted.png"; sourceTree = ""; };
E225E4641679E30E00A00529 /* shortcut-recorder-snapback-highlighted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-snapback-highlighted@2x.png"; sourceTree = ""; };
E225E4651679E30E00A00529 /* shortcut-recorder-snapback.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-snapback.png"; sourceTree = ""; };
E225E4661679E30E00A00529 /* shortcut-recorder-snapback@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut-recorder-snapback@2x.png"; sourceTree = ""; };
E273122E1349EC9000A84433 /* PTHotKey.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PTHotKey.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E273122F1349EC9000A84433 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = PTHotKey/Info.plist; sourceTree = SOURCE_ROOT; };
E273124B1349EE6500A84433 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
E2741AC41673C79F00A139BD /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AC61673C7A400A139BD /* de */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AC71673C7A600A139BD /* el */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AC81673C7A800A139BD /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AC91673C7AA00A139BD /* it */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ACB1673C7AD00A139BD /* ko */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ACC1673C7AF00A139BD /* nb */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ACD1673C7B200A139BD /* nl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ACE1673C7B300A139BD /* pl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ACF1673C7B500A139BD /* pt-BR */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/ShortcutRecorder.strings"; sourceTree = ""; };
E2741AD01673C7B600A139BD /* ro */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD11673C7B800A139BD /* ru */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD21673C7BB00A139BD /* sk */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD31673C7BC00A139BD /* sv */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD41673C7BD00A139BD /* th */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD61673C7C000A139BD /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD71673C7C200A139BD /* es-MX */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/ShortcutRecorder.strings"; sourceTree = ""; };
E2741AD81673C7C300A139BD /* ca */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741AD91673C7C600A139BD /* cs */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ADA1673C7C800A139BD /* pt */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/ShortcutRecorder.strings; sourceTree = ""; };
E2741ADE1673C83800A139BD /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; };
E2741AE01673C90B00A139BD /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
E2741AE81673CCBA00A139BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Library/Info.plist; sourceTree = ""; };
E279508E131A7498008AE1DA /* PTHotKey+ShortcutRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PTHotKey+ShortcutRecorder.h"; sourceTree = ""; };
E279508F131A7498008AE1DA /* PTHotKey+ShortcutRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PTHotKey+ShortcutRecorder.m"; sourceTree = ""; };
E28113AB167B8A9D001E118E /* SRModifierFlagsTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRModifierFlagsTransformer.h; path = Library/SRModifierFlagsTransformer.h; sourceTree = ""; };
E28113AC167B8A9D001E118E /* SRModifierFlagsTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRModifierFlagsTransformer.m; path = Library/SRModifierFlagsTransformer.m; sourceTree = ""; };
E2BE924B16ABEFE400827E8C /* SRKeyEquivalentTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRKeyEquivalentTransformer.h; path = Library/SRKeyEquivalentTransformer.h; sourceTree = ""; };
E2BE924C16ABEFE400827E8C /* SRKeyEquivalentTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRKeyEquivalentTransformer.m; path = Library/SRKeyEquivalentTransformer.m; sourceTree = ""; };
E2BE925016ABF84100827E8C /* SRKeyEquivalentModifierMaskTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRKeyEquivalentModifierMaskTransformer.h; path = Library/SRKeyEquivalentModifierMaskTransformer.h; sourceTree = ""; };
E2BE925116ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRKeyEquivalentModifierMaskTransformer.m; path = Library/SRKeyEquivalentModifierMaskTransformer.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
9398377E0DA42965007F53F3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E2741AE11673C90B00A139BD /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E273122C1349EC9000A84433 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E273124C1349EE6500A84433 /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* ShortcutRecorder */ = {
isa = PBXGroup;
children = (
29B97317FDCFA39411CA2CEA /* Resources */,
BA10595B1689CEB000A3DDF5 /* Supporting Files */,
939837B50DA42DFB007F53F3 /* ShortcutRecorder.h */,
74C3670C0A246B4900B69171 /* SRKeyCodeTransformer.h */,
74C3670D0A246B4900B69171 /* SRKeyCodeTransformer.m */,
E28113AB167B8A9D001E118E /* SRModifierFlagsTransformer.h */,
E28113AC167B8A9D001E118E /* SRModifierFlagsTransformer.m */,
E2BE924B16ABEFE400827E8C /* SRKeyEquivalentTransformer.h */,
E2BE924C16ABEFE400827E8C /* SRKeyEquivalentTransformer.m */,
E2BE925016ABF84100827E8C /* SRKeyEquivalentModifierMaskTransformer.h */,
E2BE925116ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.m */,
0B8E29C009CDB9360085E9ED /* SRRecorderControl.h */,
0B8E29C109CDB9360085E9ED /* SRRecorderControl.m */,
74C3670E0A246B4900B69171 /* SRValidator.h */,
74C3670F0A246B4900B69171 /* SRValidator.m */,
74C367100A246B4900B69171 /* SRCommon.h */,
74C367110A246B4900B69171 /* SRCommon.m */,
);
name = ShortcutRecorder;
sourceTree = "";
};
0D6B246A180304DE00CE1142 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
0D6B246B180304DE00CE1142 /* AppKit.framework */,
0D6B246C180304DE00CE1142 /* CoreData.framework */,
0D6B246D180304DE00CE1142 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "";
};
0DB3F54B1802EE0B00576055 /* Frameworks */ = {
isa = PBXGroup;
children = (
E2741AE01673C90B00A139BD /* Cocoa.framework */,
E273124B1349EE6500A84433 /* Carbon.framework */,
0D6B2487180304DE00CE1142 /* XCTest.framework */,
0D6B246A180304DE00CE1142 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
939837800DA42965007F53F3 /* ShortcutRecorder.framework */,
E273122E1349EC9000A84433 /* PTHotKey.framework */,
);
name = Products;
sourceTree = "";
};
29B97314FDCFA39411CA2CEA /* ShortcutRecorder */ = {
isa = PBXGroup;
children = (
E2741AE71673CC3D00A139BD /* PTHotKey */,
080E96DDFE201D6D7F000001 /* ShortcutRecorder */,
0DB3F54B1802EE0B00576055 /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = ShortcutRecorder;
sourceTree = "";
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
BA547C011A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left.png */,
BA547C021A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png */,
BA547C031A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png */,
BA547C041A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png */,
BA547C051A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right.png */,
BA547C061A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png */,
BA547C071A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left.png */,
BA547C081A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left@2x.png */,
BA547C091A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle.png */,
BA547C0A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle@2x.png */,
BA547C0B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right.png */,
BA547C0C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right@2x.png */,
BA547C0D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left.png */,
BA547C0E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left@2x.png */,
BA547C0F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle.png */,
BA547C101A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle@2x.png */,
BA547C111A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right.png */,
BA547C121A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right@2x.png */,
BA547C131A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png */,
BA547C141A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png */,
BA547C151A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png */,
BA547C161A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png */,
BA547C171A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png */,
BA547C181A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png */,
BA547C191A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left.png */,
BA547C1A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left@2x.png */,
BA547C1B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle.png */,
BA547C1C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle@2x.png */,
BA547C1D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right.png */,
BA547C1E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right@2x.png */,
BA547C1F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted.png */,
BA547C201A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted@2x.png */,
BA547C211A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear.png */,
BA547C221A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear@2x.png */,
BA547C231A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted.png */,
BA547C241A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted@2x.png */,
BA547C251A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback.png */,
BA547C261A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback@2x.png */,
E20A897317F3322300502E33 /* shortcut-recorder-bezel-disabled-left.png */,
E20A897417F3322300502E33 /* shortcut-recorder-bezel-disabled-left@2x.png */,
E20A897517F3322300502E33 /* shortcut-recorder-bezel-disabled-middle.png */,
E20A897617F3322300502E33 /* shortcut-recorder-bezel-disabled-middle@2x.png */,
E20A897717F3322300502E33 /* shortcut-recorder-bezel-disabled-right.png */,
E20A897817F3322300502E33 /* shortcut-recorder-bezel-disabled-right@2x.png */,
E225E4471679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left.png */,
E225E4481679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left@2x.png */,
E225E4491679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle.png */,
E225E44A1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle@2x.png */,
E225E44B1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right.png */,
E225E44C1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right@2x.png */,
E225E44D1679E30E00A00529 /* shortcut-recorder-bezel-editing-left.png */,
E225E44E1679E30E00A00529 /* shortcut-recorder-bezel-editing-left@2x.png */,
E225E44F1679E30E00A00529 /* shortcut-recorder-bezel-editing-middle.png */,
E225E4501679E30E00A00529 /* shortcut-recorder-bezel-editing-middle@2x.png */,
E225E4511679E30E00A00529 /* shortcut-recorder-bezel-editing-right.png */,
E225E4521679E30E00A00529 /* shortcut-recorder-bezel-editing-right@2x.png */,
E225E4531679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left.png */,
E225E4541679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left@2x.png */,
E225E4551679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle.png */,
E225E4561679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle@2x.png */,
E225E4571679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right.png */,
E225E4581679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right@2x.png */,
E225E4591679E30E00A00529 /* shortcut-recorder-bezel-left.png */,
E225E45A1679E30E00A00529 /* shortcut-recorder-bezel-left@2x.png */,
E225E45B1679E30E00A00529 /* shortcut-recorder-bezel-middle.png */,
E225E45C1679E30E00A00529 /* shortcut-recorder-bezel-middle@2x.png */,
E225E45D1679E30E00A00529 /* shortcut-recorder-bezel-right.png */,
E225E45E1679E30E00A00529 /* shortcut-recorder-bezel-right@2x.png */,
E225E45F1679E30E00A00529 /* shortcut-recorder-clear-highlighted.png */,
E225E4601679E30E00A00529 /* shortcut-recorder-clear-highlighted@2x.png */,
E225E4611679E30E00A00529 /* shortcut-recorder-clear.png */,
E225E4621679E30E00A00529 /* shortcut-recorder-clear@2x.png */,
E225E4631679E30E00A00529 /* shortcut-recorder-snapback-highlighted.png */,
E225E4641679E30E00A00529 /* shortcut-recorder-snapback-highlighted@2x.png */,
E225E4651679E30E00A00529 /* shortcut-recorder-snapback.png */,
E225E4661679E30E00A00529 /* shortcut-recorder-snapback@2x.png */,
E2741ADE1673C83800A139BD /* LICENSE.txt */,
E2741AC31673C79F00A139BD /* ShortcutRecorder.strings */,
);
path = Resources;
sourceTree = SOURCE_ROOT;
};
BA10595B1689CEB000A3DDF5 /* Supporting Files */ = {
isa = PBXGroup;
children = (
32CA4F630368D1EE00C91783 /* Prefix.pch */,
E2741AE81673CCBA00A139BD /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "";
};
BA10595C1689CEBF00A3DDF5 /* Supporting Files */ = {
isa = PBXGroup;
children = (
E273122F1349EC9000A84433 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "";
};
E2741AE71673CC3D00A139BD /* PTHotKey */ = {
isa = PBXGroup;
children = (
BA10595C1689CEBF00A3DDF5 /* Supporting Files */,
0B8E2A0309CDBADE0085E9ED /* PTHotKey.h */,
0B8E2A0409CDBADE0085E9ED /* PTHotKey.m */,
0B8E2A0509CDBADE0085E9ED /* PTHotKeyCenter.h */,
0B8E2A0609CDBADE0085E9ED /* PTHotKeyCenter.m */,
A1125B75104C8AF3005C6F7B /* PTKeyCodeTranslator.h */,
A1125B76104C8AF3005C6F7B /* PTKeyCodeTranslator.m */,
0B8E2A0709CDBADE0085E9ED /* PTKeyCombo.h */,
0B8E2A0809CDBADE0085E9ED /* PTKeyCombo.m */,
E279508E131A7498008AE1DA /* PTHotKey+ShortcutRecorder.h */,
E279508F131A7498008AE1DA /* PTHotKey+ShortcutRecorder.m */,
);
path = PTHotKey;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
9398394A0DA4351C007F53F3 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
939839390DA4350B007F53F3 /* ShortcutRecorder.h in Headers */,
9398393B0DA4350B007F53F3 /* SRRecorderControl.h in Headers */,
E28113AD167B8A9D001E118E /* SRModifierFlagsTransformer.h in Headers */,
E2BE924D16ABEFE400827E8C /* SRKeyEquivalentTransformer.h in Headers */,
E2BE925216ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.h in Headers */,
9398393E0DA4350B007F53F3 /* SRKeyCodeTransformer.h in Headers */,
9398393F0DA4350B007F53F3 /* SRValidator.h in Headers */,
939839400DA4350B007F53F3 /* SRCommon.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E27312291349EC9000A84433 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
E273123A1349EDB500A84433 /* PTHotKey.h in Headers */,
E273123B1349EDB500A84433 /* PTHotKeyCenter.h in Headers */,
E273123C1349EDB500A84433 /* PTKeyCodeTranslator.h in Headers */,
E273123D1349EDB500A84433 /* PTKeyCombo.h in Headers */,
E2BE927C16AC052000827E8C /* PTHotKey+ShortcutRecorder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
9398377F0DA42965007F53F3 /* ShortcutRecorder.framework */ = {
isa = PBXNativeTarget;
buildConfigurationList = 939837840DA42965007F53F3 /* Build configuration list for PBXNativeTarget "ShortcutRecorder.framework" */;
buildPhases = (
E2BADF0A134F13CD00F65E14 /* Resources */,
9398377D0DA42965007F53F3 /* Sources */,
9398377E0DA42965007F53F3 /* Frameworks */,
9398394A0DA4351C007F53F3 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = ShortcutRecorder.framework;
productName = ShortcutRecorder.framework;
productReference = 939837800DA42965007F53F3 /* ShortcutRecorder.framework */;
productType = "com.apple.product-type.framework";
};
E273122D1349EC9000A84433 /* PTHotKey.framework */ = {
isa = PBXNativeTarget;
buildConfigurationList = E27312381349EC9000A84433 /* Build configuration list for PBXNativeTarget "PTHotKey.framework" */;
buildPhases = (
E273122B1349EC9000A84433 /* Sources */,
E273122C1349EC9000A84433 /* Frameworks */,
E27312291349EC9000A84433 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = PTHotKey.framework;
productName = PTHotKey;
productReference = E273122E1349EC9000A84433 /* PTHotKey.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1250;
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShortcutRecorder" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
sv,
Dutch,
ru,
de,
el,
en,
fr,
it,
ja,
ko,
nb,
nl,
pl,
"pt-BR",
ro,
sk,
th,
"zh-Hans",
es,
"es-MX",
ca,
cs,
pt,
"zh-Hant",
Base,
tr,
ar,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* ShortcutRecorder */;
projectDirPath = "";
projectRoot = "";
targets = (
9398377F0DA42965007F53F3 /* ShortcutRecorder.framework */,
E273122D1349EC9000A84433 /* PTHotKey.framework */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
E2BADF0A134F13CD00F65E14 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BA547C3C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle@2x.png in Resources */,
E20A897E17F3322300502E33 /* shortcut-recorder-bezel-disabled-right@2x.png in Resources */,
BA547C371A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right.png in Resources */,
E2741AC51673C79F00A139BD /* ShortcutRecorder.strings in Resources */,
BA547C351A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle.png in Resources */,
E2741ADF1673C83800A139BD /* LICENSE.txt in Resources */,
BA547C3E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right@2x.png in Resources */,
BA547C481A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear@2x.png in Resources */,
E20A897C17F3322300502E33 /* shortcut-recorder-bezel-disabled-middle@2x.png in Resources */,
E225E4671679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left.png in Resources */,
BA547C441A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right@2x.png in Resources */,
E225E4681679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-left@2x.png in Resources */,
BA547C291A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle.png in Resources */,
BA547C451A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted.png in Resources */,
BA547C3B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-middle.png in Resources */,
E225E4691679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle.png in Resources */,
E225E46A1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-middle@2x.png in Resources */,
E225E46B1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right.png in Resources */,
E20A897B17F3322300502E33 /* shortcut-recorder-bezel-disabled-middle.png in Resources */,
E225E46C1679E30E00A00529 /* shortcut-recorder-bezel-blue-highlighted-right@2x.png in Resources */,
E225E46D1679E30E00A00529 /* shortcut-recorder-bezel-editing-left.png in Resources */,
E225E46E1679E30E00A00529 /* shortcut-recorder-bezel-editing-left@2x.png in Resources */,
E225E46F1679E30E00A00529 /* shortcut-recorder-bezel-editing-middle.png in Resources */,
E225E4701679E30E00A00529 /* shortcut-recorder-bezel-editing-middle@2x.png in Resources */,
BA547C421A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle@2x.png in Resources */,
E225E4711679E30E00A00529 /* shortcut-recorder-bezel-editing-right.png in Resources */,
BA547C361A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-middle@2x.png in Resources */,
BA547C321A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right@2x.png in Resources */,
BA547C4A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted@2x.png in Resources */,
E225E4721679E30E00A00529 /* shortcut-recorder-bezel-editing-right@2x.png in Resources */,
E225E4731679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left.png in Resources */,
BA547C2F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle.png in Resources */,
E225E4741679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-left@2x.png in Resources */,
E225E4751679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle.png in Resources */,
E225E4761679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-middle@2x.png in Resources */,
BA547C341A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left@2x.png in Resources */,
E225E4771679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right.png in Resources */,
BA547C431A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-right.png in Resources */,
BA547C2B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right.png in Resources */,
BA547C461A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear-highlighted@2x.png in Resources */,
BA547C381A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-right@2x.png in Resources */,
E225E4781679E30E00A00529 /* shortcut-recorder-bezel-graphite-highlighted-right@2x.png in Resources */,
BA547C281A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left@2x.png in Resources */,
BA547C301A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-middle@2x.png in Resources */,
BA547C3D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-right.png in Resources */,
E225E4791679E30E00A00529 /* shortcut-recorder-bezel-left.png in Resources */,
E225E47A1679E30E00A00529 /* shortcut-recorder-bezel-left@2x.png in Resources */,
BA547C391A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left.png in Resources */,
BA547C471A5FD45B00C45C31 /* shortcut-recorder-yosemite-clear.png in Resources */,
E225E47B1679E30E00A00529 /* shortcut-recorder-bezel-middle.png in Resources */,
BA547C2C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-right@2x.png in Resources */,
E225E47C1679E30E00A00529 /* shortcut-recorder-bezel-middle@2x.png in Resources */,
BA547C2A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-middle@2x.png in Resources */,
E225E47D1679E30E00A00529 /* shortcut-recorder-bezel-right.png in Resources */,
BA547C3A1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-graphite-highlighted-left@2x.png in Resources */,
E225E47E1679E30E00A00529 /* shortcut-recorder-bezel-right@2x.png in Resources */,
BA547C271A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-blue-highlighted-left.png in Resources */,
BA547C311A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-right.png in Resources */,
E225E47F1679E30E00A00529 /* shortcut-recorder-clear-highlighted.png in Resources */,
E225E4801679E30E00A00529 /* shortcut-recorder-clear-highlighted@2x.png in Resources */,
E20A897A17F3322300502E33 /* shortcut-recorder-bezel-disabled-left@2x.png in Resources */,
BA547C3F1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left.png in Resources */,
BA547C331A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-editing-left.png in Resources */,
BA547C401A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-left@2x.png in Resources */,
E20A897D17F3322300502E33 /* shortcut-recorder-bezel-disabled-right.png in Resources */,
E225E4811679E30E00A00529 /* shortcut-recorder-clear.png in Resources */,
BA547C2D1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left.png in Resources */,
BA547C491A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback-highlighted.png in Resources */,
BA547C2E1A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-disabled-left@2x.png in Resources */,
E225E4821679E30E00A00529 /* shortcut-recorder-clear@2x.png in Resources */,
E225E4831679E30E00A00529 /* shortcut-recorder-snapback-highlighted.png in Resources */,
E225E4841679E30E00A00529 /* shortcut-recorder-snapback-highlighted@2x.png in Resources */,
E225E4851679E30E00A00529 /* shortcut-recorder-snapback.png in Resources */,
E225E4861679E30E00A00529 /* shortcut-recorder-snapback@2x.png in Resources */,
BA547C4C1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback@2x.png in Resources */,
BA547C411A5FD45B00C45C31 /* shortcut-recorder-yosemite-bezel-middle.png in Resources */,
BA547C4B1A5FD45B00C45C31 /* shortcut-recorder-yosemite-snapback.png in Resources */,
E20A897917F3322300502E33 /* shortcut-recorder-bezel-disabled-left.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
9398377D0DA42965007F53F3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
939837950DA429EC007F53F3 /* SRRecorderControl.m in Sources */,
939837980DA429EC007F53F3 /* SRKeyCodeTransformer.m in Sources */,
939837990DA429EC007F53F3 /* SRValidator.m in Sources */,
9398379A0DA429EC007F53F3 /* SRCommon.m in Sources */,
E28113AE167B8A9D001E118E /* SRModifierFlagsTransformer.m in Sources */,
E2BE924E16ABEFE400827E8C /* SRKeyEquivalentTransformer.m in Sources */,
E2BE925316ABF84200827E8C /* SRKeyEquivalentModifierMaskTransformer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E273122B1349EC9000A84433 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E27312401349EDCA00A84433 /* PTHotKey.m in Sources */,
E27312411349EDCA00A84433 /* PTHotKeyCenter.m in Sources */,
E27312421349EDCA00A84433 /* PTKeyCodeTranslator.m in Sources */,
E27312431349EDCA00A84433 /* PTKeyCombo.m in Sources */,
E2BE927D16AC052600827E8C /* PTHotKey+ShortcutRecorder.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
E2741AC31673C79F00A139BD /* ShortcutRecorder.strings */ = {
isa = PBXVariantGroup;
children = (
E2741AC41673C79F00A139BD /* en */,
E2741AC61673C7A400A139BD /* de */,
E2741AC71673C7A600A139BD /* el */,
E2741AC81673C7A800A139BD /* fr */,
E2741AC91673C7AA00A139BD /* it */,
E2741ACB1673C7AD00A139BD /* ko */,
E2741ACC1673C7AF00A139BD /* nb */,
E2741ACD1673C7B200A139BD /* nl */,
E2741ACE1673C7B300A139BD /* pl */,
E2741ACF1673C7B500A139BD /* pt-BR */,
E2741AD01673C7B600A139BD /* ro */,
E2741AD11673C7B800A139BD /* ru */,
E2741AD21673C7BB00A139BD /* sk */,
E2741AD31673C7BC00A139BD /* sv */,
E2741AD41673C7BD00A139BD /* th */,
E2741AD61673C7C000A139BD /* es */,
E2741AD71673C7C200A139BD /* es-MX */,
E2741AD81673C7C300A139BD /* ca */,
E2741AD91673C7C600A139BD /* cs */,
E2741ADA1673C7C800A139BD /* pt */,
9AA522D823416E6A00C9E005 /* tr */,
3552066127AF63DC000EF08F /* ar */,
);
name = ShortcutRecorder.strings;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
939837820DA42965007F53F3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 2.6;
DYLIB_CURRENT_VERSION = 2.17;
FRAMEWORK_VERSION = A;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Library/Prefix.pch;
INFOPLIST_FILE = Library/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = com.kulakov.ShortcutRecorder;
PRODUCT_NAME = ShortcutRecorder;
PROVISIONING_PROFILE = "";
};
name = Debug;
};
939837830DA42965007F53F3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 2.6;
DYLIB_CURRENT_VERSION = 2.17;
FRAMEWORK_VERSION = A;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Library/Prefix.pch;
INFOPLIST_FILE = Library/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = com.kulakov.ShortcutRecorder;
PRODUCT_NAME = ShortcutRecorder;
PROVISIONING_PROFILE = "";
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CLANG_X86_VECTOR_INSTRUCTIONS = ssse3;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = macosx;
SKIP_INSTALL = YES;
WARNING_CFLAGS = "-Wall";
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CLANG_X86_VECTOR_INSTRUCTIONS = ssse3;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = macosx;
SKIP_INSTALL = YES;
WARNING_CFLAGS = "-Wall";
};
name = Release;
};
E27312361349EC9000A84433 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1.5;
FRAMEWORK_VERSION = A;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
INFOPLIST_FILE = PTHotKey/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.13;
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
AppKit,
);
PRODUCT_BUNDLE_IDENTIFIER = com.kulakov.PTHotKey;
PRODUCT_NAME = PTHotKey;
};
name = Debug;
};
E27312371349EC9000A84433 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1.5;
FRAMEWORK_VERSION = A;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
INFOPLIST_FILE = PTHotKey/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.13;
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
AppKit,
);
PRODUCT_BUNDLE_IDENTIFIER = com.kulakov.PTHotKey;
PRODUCT_NAME = PTHotKey;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
939837840DA42965007F53F3 /* Build configuration list for PBXNativeTarget "ShortcutRecorder.framework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
939837820DA42965007F53F3 /* Debug */,
939837830DA42965007F53F3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShortcutRecorder" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E27312381349EC9000A84433 /* Build configuration list for PBXNativeTarget "PTHotKey.framework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E27312361349EC9000A84433 /* Debug */,
E27312371349EC9000A84433 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/PTHotKey.framework.xcscheme
================================================
================================================
FILE: Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/ShortcutRecorder.framework.xcscheme
================================================
================================================
FILE: Clocker/Clocker/ar.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/ar.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "كلوكر";
"Thank you for helping make Clocker even better!" = "شكرا للمساعدة في جعل Clocker افضل!";
"iRateMessageTitle" = "قيّم %@";
"iRateAppMessage" = "اذا ما اعجبك استخدام %@، فهل من الممكن ان نأخذ دقيقة من وقتك لتقييمه ؟ لن يأخذ أكثر من دقيقة من وقتك. نشكرك لدعمك!";
"iRateGameMessage" = "إذا أعجبك %@، فهل من الممكن أن نأخذ دقيقة من وقتك لتقييمه؟ لن تأخذ عملية التقييم أكثر من دقيقة من وقتك. نشكرك لدعمك!";
"iRateCancelButton" = "لا، شكراً";
"iRateRateButton" = "قيّم الآن";
"iRateRemindButton" = "ذكرني لاحقاً";
"iRateUpdateMessage" = "التحديث الان؟";
"ClockerVersion" = "الإصدار %@";
"CLFeedbackAlertTitle" = "شكرا للمساعدة في جعل Clocker افضل!";
"app-name" = "Clocker";
"start-at-login" = "بدء عند تسجيل الدخول";
"setup-steps" = "يتطلب الأمر فقط 3 خطوات لضبط Clocker";
"Permissions-Header" = "الصلاحيات";
"See your next Calendar event here." = "تابع حدثك القادم هنا.";
"Click here to start." = "أضغط هنا لتبدأ.";
"Reminders Access" = "صلاحيات الوصول إلى التذكيرات";
"Calendar Access" = "صلاحيات الوصول إلى التقويم";
"Permissions" = "الصلاحيات";
"Calendar Detail" = "الأحداث القادمة من تقويماتك الشخصية والمشتركة يمكن أن تظهر في شريط القائمة ولوحة التحكم.";
"Reminders Detail" = "عين تذكيرات في المنطقة الزمني للموقع الذي تريده. يتم تخزين تذكيراتك في تطبيق التذكير بشكل افتراضي.";
"Privacy Text" = "يمكنك تغيير هذا لاحقًا في قسم اعدادات الخصوصية المتواجد بتفضيلات النظام.";
"Granted Button Text" = "مسموح";
"Denied Button Text" = "مرفوض";
"Grant Button Text" = "منح";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "يتطلب الأمر فقط 3 خطوات لتفعيل Clocker.";
"Get Started" = "ابدأ الاستخدام";
// Tab Item Titles
"Preferences Tab" = "التفضيلات";
"Appearance Tab" = "إعدادات المظهر";
"Calendar Tab" = "التقويم";
"About Tab" = "حول";
"Permissions Tab" = "الصلاحيات";
// General Preferences Screen
"Start at Login" = "بدأ Clocker عند تسجيل الدخول";
"Sort by Time Difference" = "الترتيب حسب الفارق الزمني";
"Sort by Name" = "الترتيب حسب الاسم";
"Sort by Label" = "الترتيب حسب العلامة";
"Search Field Placeholder" = "أدخل اسم المدينة أو الولاية أو البلد";
"No Timezone Selected" = "رجاء اختر منطقتك الزمنية!";
"Max Timezones Selected" = "الحد الأقصى المسموح به 100 منطقة زمنية!";
"Max Search Characters" = "الحد الأقصى 50 حرفًا!";
"Add Button Title" = "إضافة";
"Close Button Title" = "إغلاق";
// Onboarding
"Open Clocker At Login" = "بدأ \"كلوكر\" عند تسجيل الدخول";
"Launch Clocker" = "تشغيل Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "يتطلب الأمر فقط 3 خطوات لتفعيل Clocker.";
"Get Started" = "ابدأ الاستخدام";
// Permissions
"Calendar Access Title" = "صلاحيات الوصول إلى التقويم";
"Reminders Access Title" = "صلاحيات الوصول إلى التذكيرات";
"Later Config Description" = "يمكن إعداد هذا لاحقًا في تفضيلات النظام.";
"Back" = "عودة";
"Continue" = "متابعة";
"Clocker is more useful when it can display events from your calendars." = "يكون Clocker مفيدًا أكثر عندما يكون لديه صلاحيات عرض أحداث من تقويمك.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "يكون Clocker أكثر فائدةُ عندما يكون لديه صلاحيات عرض أحداث من تقويمك. يمكنك تغير هذا في تفضيلات النظام > اعدادات الأمان والخصوصية > أعدادات الخصوصية.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "الانتقال إلى تفضيلات النظام";
"Grant Access" = "منح صلاحية الوصول";
"Upcoming events from your calendars can be shown in the menubar + panel." = "الأحداث القادمة من تقويماتك الشخصية والمشتركة يمكن أن تظهر في شريط القائمة ولوحة التحكم.";
"Granted" = "سماح";
"Denied" = "رفض";
"Grant" = "منح";
"Unexpected" = "غير متوقع";
// Onboarding Search
"Quick Add Locations" = "إضافة سريعة للمواقع";
"More search options in Clocker Preferences." = "المزيد من خيارات البحث في إعدادات تفضيلات Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "أدخل على الأقل ثلاثة أحرف من الموقع الذي ترغب بإضافته";
// Start at Login
"Launch at Login" = "تشغيل عند تسجيل الدخول";
"This can be configured later in Clocker Preferences." = "يمكن إعداد هذا لاحقًا في تفضيلات النظام.";
"Should Clocker open automatically on startup?" = "هل تريد أن يبدأ Clocker عند بدأ التشغيل؟";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
/* Appears in Preferences -> Appearance which allows the user to switch between the compact and standard menubar mode. It doesn't lead anywhere. */
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/ca.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/ca.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Rate %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "No, Thanks";
"iRateRateButton" = "Rate It Now";
"iRateRemindButton" = "Remind Me Later";
"iRateUpdateMessage" = "Update now?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Thank you for helping make Clocker even better!";
"app-name" = "Clocker";
"start-at-login" = "Start At Login";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "Permissions";
"See your next Calendar event here." = "See your next Calendar event here.";
"Click here to start." = "Click here to start.";
"Reminders Access" = "Reminders Access";
"Calendar Access" = "Calendar Access";
"Permissions" = "Permissions";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Granted";
"Denied Button Text" = "Denied";
"Grant Button Text" = "Grant";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Preferences";
"Appearance Tab" = "Appearance";
"Calendar Tab" = "Calendar";
"About Tab" = "About";
"Permissions Tab" = "Permissions";
// General Preferences Screen
"Start at Login" = "Start Clocker at Login";
"Sort by Time Difference" = "Sort by Time Difference";
"Sort by Name" = "Sort by Name";
"Sort by Label" = "Sort by Label";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "Add";
"Close Button Title" = "Close";
// Onboarding
"Open Clocker At Login" = "Open Clocker At Login";
"Launch Clocker" = "Launch Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Permissions
"Calendar Access Title" = "Calendar Access";
"Reminders Access Title" = "Reminders Access";
"Later Config Description" = "These can be configured later in System Preferences.";
"Back" = "Back";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/com.abhishek.ClockerHelper.plist
================================================
Program
/Applications/Clocker.app/Contents/MacOS/Clocker
Label
com.abhishek.ClockerHelper
RunAtLoad
KeepAlive
================================================
FILE: Clocker/Clocker/de.lproj/InfoPlist.strings
================================================
/* InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16. */
"CFBundleDisplayName" = "Clocker";
/* (No Comment) */
"CFBundleName" = "Clocker";
/* Privacy - Calendars Usage Description */
"NSCalendarsUsageDescription" = "Clocker kann nützlicher sein, wenn es kommende Termine von Ihren Kalender anzeigen kann. Sie können diese Einstellung in Systemeinstellungen › Sicherheit Privatsphäre › Privatsphäre ändern";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Copyright © 2016, Abhishek Banthia";
/* Privacy - Location Always and When In Use Usage Description */
"NSLocationAlwaysAndWhenInUseUsageDescription" = "Clocker kann nützlicher sein, wenn es Ihren Standort zur Bestimmung Ihrer aktuellen Zeitzone verwenden kann.";
/* Privacy - Location Usage Description */
"NSLocationUsageDescription" = "Clocker kann nützlicher sein, wenn es Ihren Standort zur Bestimmung Ihrer aktuellen Zeitzone verwenden kann.";
/* Privacy - Reminders Usage Description */
"NSRemindersUsageDescription" = "Clocker kann nützlicher sein, wenn es Erinnerungen für Ihre ausgewählte Zeitzone(n) setzen kann. Sie können diese Einstellung in Systemeinstellungen › Sicherheit und Privatsphäre › Privatsphäre ändern.";
================================================
FILE: Clocker/Clocker/de.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Danke, dass du dabei geholfen hast, Clocker noch besser zu machen!";
"iRateMessageTitle" = "%@ bewerten";
"iRateAppMessage" = "Wenn dir %@ gefällt, dann bewerte uns doch im App Store. Das dauert kaum eine Minute und hilft uns sehr. Vielen Dank für deine Unterstützung!";
"iRateGameMessage" = "Wenn du Spaß an %@ hast, dann bewerte uns doch im App Store. Das dauert kaum eine Minute und hilft uns sehr. Vielen Dank, für deine Unterstützung!";
"iRateCancelButton" = "Nein, danke";
"iRateRateButton" = "Jetzt bewerten";
"iRateRemindButton" = "Später erinnern";
"iRateUpdateMessage" = "Jetzt aktualisieren?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Danke, dass Du hilfst Clocker noch besser zu machen!";
"app-name" = "Clocker";
"start-at-login" = "Bei der Anmeldung starten";
"setup-steps" = "In nur drei Schritten ist Clocker fertig eingerichtet";
"Permissions-Header" = "Berechtigungen";
"See your next Calendar event here." = "Siehe bevorstehendes Kalenderereignis?";
"Click here to start." = "Bevorstehendes Kalenderereignis hier anzeigen";
"Reminders Access" = "Erinnerungszugriff";
"Calendar Access" = "Kalenderzugriff";
"Permissions" = "Berechtigungen";
"Calendar Detail" = "Anstehende Termine aus Deinem persönlichen und geteilten Kalendern können in der Menüleiste und im Fenster angezeigt werden.";
"Reminders Detail" = "Erinnerungen in der Zeitzone Deiner Wahl festlegen. Deine Erinnerungen werden in der Standard-Erinnerungs-App gespeichert.";
"Privacy Text" = "Du kannst das später im Bereich Datenschutz in den Systemeinstellungen ändern.";
"Granted Button Text" = "Gewährt";
"Denied Button Text" = "Verweigert";
"Grant Button Text" = "Gewähren";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "In nur drei Schritten ist Clocker fertig eingerichtet.";
"Get Started" = "Erste Schritte";
// Tab Item Titles
"Preferences Tab" = "Einstellungen";
"Appearance Tab" = "Erscheinungsbild";
"Calendar Tab" = "Kalender";
"About Tab" = "Über";
"Permissions Tab" = "Berechtigungen";
// General Preferences Screen
"Start at Login" = "Clocker bei der Anmeldung starten";
"Sort by Time Difference" = "Nach Zeitdifferenz sortieren";
"Sort by Name" = "Nach Namen sortieren";
"Sort by Label" = "Nach Bezeichnung sortieren";
"Search Field Placeholder" = "Gebe eine Stadt, ein Bundesland oder Land ein";
"No Timezone Selected" = "Bitte wähle eine Zeitzone!";
"Max Timezones Selected" = "Es werden maximal 100 Zeitzonen unterstützt!";
"Max Search Characters" = "Es sind nur 50 Zeichen erlaubt!";
"Add Button Title" = "Hinzufügen";
"Close Button Title" = "Schließen";
// Onboarding
"Open Clocker At Login" = "Clocker bei der Anmeldung starten";
"Launch Clocker" = "Clocker starten";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "In nur drei Schritten ist Clocker fertig eingerichtet.";
"Get Started" = "Erste Schritte";
// Permissions
"Calendar Access Title" = "Kalender-Zugriff";
"Reminders Access Title" = "Zugriff auf Erinnerungen";
"Later Config Description" = "Dies kann später in den Clocker Einstellungen konfiguriert werden.";
"Back" = "Zurück";
"Continue" = "Fortfahren";
"Clocker is more useful when it can display events from your calendars." = "Clocker ist nützlicher, wenn es Ereignisse aus Deinem Kalendern anzeigen kann.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker ist nützlicher, wenn es Ereignisse aus Deinem Kalendern anzeigen kann. Du kannst diese Einstellung in Systemeinstellungen › Sicherheit Privatsphäre › Privatsphäre ändern.";
"Launch Preferences" = "Einstellungen öffnen";
"Grant Access" = "Zugriff erlauben";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Anstehende Termine aus deinem persönlichen und geteilten Kalendern können in der Menüleiste und im Fenster angezeigt werden.";
"Granted" = "Gewährt";
"Denied" = "Abgelehnt";
"Grant" = "Gewähren";
"Unexpected" = "Unerwartet";
// Onboarding Search
"Quick Add Locations" = "Orte schnell hinzufügen";
"More search options in Clocker Preferences." = "Weitere Suchoptionen in den Clocker Einstellungen.";
"Enter 3 or more characters for locations you'll like to add" = "Gebe 3 oder mehr Zeichen für den Orte ein, die Du hinzufügen möchtest";
// Start at Login
"Launch at Login" = "Bei der Anmelden starten";
"This can be configured later in Clocker Preferences." = "Dies kann später in den Clocker Einstellungen konfiguriert werden.";
"Should Clocker open automatically on startup?" = "Soll Clocker beim Start automatisch geöffnet werden?";
// Final Onboarding Screen
"You're all set!" = "Du bist startklar!";
"Thank you for the details." = "Vielen Dank für die Details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Du wirst ein Uhr-Symbol in Ihrer Menüleiste sehen, wenn Du die App startest. Wenn Du ein Dock-Symbol sehen möchtest, gehe in die Einstellungen.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Wenn Du uns helfen möchtest die App in Deine Sprache zu übersetzen oder von Zeit zu Zeit Informationen zur App erhalten möchtest, gibt bitte hier Deine E-Mail ein!";
// Appearance Tab
"Panel Theme" = "Erscheinungsbild";
"Favourite a timezone to enable menubar display options." = "Favorisiere eine Zeitzone, um diese in der Menüleiste zu zeigen.";
"Main Panel Options" = "Optionen für Programmfenster";
"Time Format" = "Zeitformat";
"Day Display Options" = "Anzeigeoptionen für den Tag";
"Show Future Slider" = "\"Future Slider\" anzeigen";
"Show Sunrise/Sunset" = "Sonnenaufgang/-untergang anzeigen";
"Display the time in seconds" = "Zeit in Sekunden anzeigen";
"Larger Text" = "Größerer Text";
"Future Slider Range" = "Bereich für den \"Future Slider\"";
"Include Date" = "Datum hinzufügen";
"Include Day" = "Tag hinzufügen";
"Include Place Name" = "Ortsname hinzufügen";
"Menubar Display Options" = "Anzeigeoptionen für die Menüleiste";
"Menubar Mode" = "Menüleisten-Modus";
"Preview" = "Vorschau";
"Miscellaneous" = "Verschiedenes";
// Empty View
"No places added" = "Keine Orte hinzugefügt";
// Panel
"No upcoming event." = "Kein anstehendes Ereignis.";
"You have no events scheduled for tomorrow." = "Du hast keine Kalendereinträge für morgen.";
// Review
"Enjoy using Clocker?" = "Gefällt Dir Clocker?";
// App Feedback
"Tell us what you think!" = "Sag uns, was Du denkst!";
"Contact Information (Optional)" = "Kontaktinformationen (optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Kontaktinformationen sind optional! Diese helfen uns jedoch Dich zu erreichen, falls wir weitere Informationen benötigen oder helfen können!";
// About View Screen
"Feedback is always welcome:" = "Feedback ist immer willkommen:";
// Calendars View
"Upcoming Event View Options" = "Zukünftige Ereignisse zeigen";
"Show Upcoming Event View" = "Anzeigeoptionen für zukünftige Ereignisse";
"Show All Day Meetings" = "Ganztägige Ereignisse anzeigen";
"Show Next Meeting Title in Menubar" = "Das nächste Ereignis in der Menüliste zeigen";
"Truncate menubar text longer than" = "Text in der Menüleiste kürzen, der länger ist als";
"characters" = "Zeichen";
"Show events from" = "Zeige Ereignisse aus";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Wenn der Besprechungstitel \"Besprechung mit Neel\" ist und die Kürzungslänge auf 5 eingestellt wurde, dann erscheint der Text in der Menüleiste als \"Bespr...\"";
// Notes Popover
"Reminder Set" = "Erinnerung gespeichert";
"Successfully set." = "Erfolgreich gespeichert.";
// Errors
"You're offline, maybe?" = "Bist Du eventuell offline?";
"Try again, maybe?" = "Versuche es nochmal!";
"The Internet connection appears to be offline." = "Scheinbar besteht keine Verbindung zum Internet.";
// UI Tests
"New Zealand" = "Neuseeland";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/en.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/en.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Rate %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "No, Thanks";
"iRateRateButton" = "Rate It Now";
"iRateRemindButton" = "Remind Me Later";
"iRateUpdateMessage" = "Update now?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Thank you for helping make Clocker even better!";
"app-name" = "Clocker";
"start-at-login" = "Start At Login";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "Permissions";
"See your next Calendar event here." = "See your next Calendar event here.";
"Click here to start." = "Click here to start.";
"Reminders Access" = "Reminders Access";
"Calendar Access" = "Calendar Access";
"Permissions" = "Permissions";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Granted";
"Denied Button Text" = "Denied";
"Grant Button Text" = "Grant";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Preferences";
"Appearance Tab" = "Appearance";
"Calendar Tab" = "Calendar";
"About Tab" = "About";
"Permissions Tab" = "Permissions";
// General Preferences Screen
"Start at Login" = "Start Clocker at Login";
"Sort by Time Difference" = "Sort by Time Difference";
"Sort by Name" = "Sort by Name";
"Sort by Label" = "Sort by Label";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "Add";
"Close Button Title" = "Close";
// Onboarding
"Open Clocker At Login" = "Open Clocker At Login";
"Launch Clocker" = "Launch Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Permissions
"Calendar Access Title" = "Calendar Access";
"Reminders Access Title" = "Reminders Access";
"Later Config Description" = "These can be configured later in System Preferences.";
"Back" = "Back";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar and the panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Time Scroller" = "Time Scroller";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
// Upcoming Event View
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/en.lproj/Panel.xib
================================================
================================================
FILE: Clocker/Clocker/es.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/es.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "¡Gracias por ayudar a mejorar Clocker!";
"iRateMessageTitle" = "Valora %@";
"iRateAppMessage" = "Si te gusta %@, ¿podrías escribirnos una reseña? No te tomará más de un minuto. ¡Gracias por tu apoyo!";
"iRateGameMessage" = "Si te gusta %@, ¿te importaría dedicar un momento para valorarla? No tardarás nada. ¡Gracias por tu apoyo!";
"iRateCancelButton" = "No, gracias";
"iRateRateButton" = "Califícalo ahora";
"iRateRemindButton" = "Recordarme más tarde";
"iRateUpdateMessage" = "¿Actualizar ahora?";
"ClockerVersion" = "Versión %@";
"CLFeedbackAlertTitle" = "¡Gracias por ayudar a mejorar Clocker!";
"app-name" = "Clocker";
"start-at-login" = "Abrir en el inicio de sesión";
"setup-steps" = "Sólo te tomará 3 pasos configurar Clocker";
"Permissions-Header" = "Permisos";
"See your next Calendar event here." = "Vea aquí su próximo evento del calendario.";
"Click here to start." = "Haga clic aquí para comenzar.";
"Reminders Access" = "Acceder a Recordatorios";
"Calendar Access" = "Acceder al calendario";
"Permissions" = "Permisos";
"Calendar Detail" = "Los próximos eventos de sus calendarios personales y compartidos pueden mostrarse en la barra de menú y en el panel.";
"Reminders Detail" = "Establece recordatorios en la zona horaria de la ubicación seleccionada. Los recordatorios serán guardados en la aplicación Recordatorios predeterminada.";
"Privacy Text" = "Puede cambiar esto más tarde en la sección de Privacidad de las Preferencias del Sistema.";
"Granted Button Text" = "Permitido";
"Denied Button Text" = "Denegado";
"Grant Button Text" = "Permitir";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Sólo te tomará 3 pasos configurar Clocker.";
"Get Started" = "Comenzar ahora";
// Tab Item Titles
"Preferences Tab" = "Preferencias";
"Appearance Tab" = "Aspecto";
"Calendar Tab" = "Calendario";
"About Tab" = "Acerca de";
"Permissions Tab" = "Permisos";
// General Preferences Screen
"Start at Login" = "Abrir Clocker al inicio de sesión";
"Sort by Time Difference" = "Ordenar por diferencia horaria";
"Sort by Name" = "Ordenar por nombre";
"Sort by Label" = "Ordenar por etiqueta";
"Search Field Placeholder" = "Introduzca un nombre de ciudad, estado o país";
"No Timezone Selected" = "¡Por favor, selecciona una zona horaria!";
"Max Timezones Selected" = "¡Se permiten maximo 100 zonas horarias!";
"Max Search Characters" = "¡Solo se permiten 50 caracteres!";
"Add Button Title" = "Añadir";
"Close Button Title" = "Cerrar";
// Onboarding
"Open Clocker At Login" = "Abrir Clocker al iniciar sesión";
"Launch Clocker" = "Abrir Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Sólo te tomará 3 pasos configurar Clocker.";
"Get Started" = "Comenzar ahora";
// Permissions
"Calendar Access Title" = "Acceder al calendario";
"Reminders Access Title" = "Acceder a Recordatorios";
"Later Config Description" = "Se puede configurar más tarde en Preferencias del sistema.";
"Back" = "Regresar";
"Continue" = "Continuar";
"Clocker is more useful when it can display events from your calendars." = "Clocker es más útil cuando puede mostrar eventos de tus calendarios.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker es más útil cuando puede mostrar eventos de tus calendarios. Puede cambiar esta configuración en Preferencias del Sistema › Seguridad y privacidad › Privacidad.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Abrir las preferencias";
"Grant Access" = "Permitir acceso";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Los próximos eventos de sus calendarios personales y compartidos pueden mostrarse en la barra de menú y en el panel.";
"Granted" = "Permitido";
"Denied" = "Denegado";
"Grant" = "Permitir";
"Unexpected" = "Inesperado";
// Onboarding Search
"Quick Add Locations" = "Agregar ubicaciones rápidamente";
"More search options in Clocker Preferences." = "Más opciones de búsqueda en las preferencias de Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "Introduce 3 o más caracteres de las ubicaciones que quisiera añadir";
// Start at Login
"Launch at Login" = "Ejecutar cuando inicia la sesión";
"This can be configured later in Clocker Preferences." = "Esto se puede configurar más tarde en las Preferencias de Clocker.";
"Should Clocker open automatically on startup?" = "¿Quieres que Clocker se abra automáticamente al inicio?";
// Final Onboarding Screen
"You're all set!" = "¡Todo listo!";
"Thank you for the details." = "Gracias por informarnos.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Verás un icono de reloj en tu barra de menú cuando inicies la aplicación. Si quieres ver el icono en el Dock, ve a Preferencias.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Si quieres ayudarnos a traducir la aplicación en tu idioma o recibir actualizaciones relacionadas con la aplicación, ¡Por favor escribe tu correo electrónico!";
// Appearance Tab
"Panel Theme" = "Apariencia de la aplicación";
"Favourite a timezone to enable menubar display options." = "Elija una zona horaria como favorita para habilitar las opciones de visualización de la barra de menú.";
"Main Panel Options" = "Opciones del Panel Principal";
"Time Format" = "Formato de hora";
"Day Display Options" = "Formato de visualización del día";
"Show Future Slider" = "Mostrar el deslizador para horas futuras";
"Show Sunrise/Sunset" = "Mostrar salida de sol/puesta de sol";
"Display the time in seconds" = "Mostrar el tiempo en segundos";
"Larger Text" = "Texto más grande";
"Future Slider Range" = "Deslizador de rango de tiempo";
"Include Date" = "Mostrar fecha";
"Include Day" = "Mostrar día";
"Include Place Name" = "Mostrar nombre del lugar";
"Menubar Display Options" = "Opciones de visualización del reloj en la barra de menú";
"Menubar Mode" = "Modo en la barra de menú";
"Preview" = "Vista previa";
"Miscellaneous" = "Varios";
// Empty View
"No places added" = "No hay zonas horarias añadidas";
// Panel
"No upcoming event." = "No hay próximos eventos.";
"You have no events scheduled for tomorrow." = "No tienes eventos programados para mañana.";
// Review
"Enjoy using Clocker?" = "¿Te gusta Clocker?";
// App Feedback
"Tell us what you think!" = "¡Queremos conocer tu opinión!";
"Contact Information (Optional)" = "Información de contacto (opcional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "¡Los campos de contacto son opcionales! ¡Su información de contacto nos permitirá contactarnos con usted en caso de que necesitemos más información o podamos ayudar!";
// About View Screen
"Feedback is always welcome:" = "Tus comentarios son bienvenidos:";
// Calendars View
"Upcoming Event View Options" = "Opciones de visualización de los próximos eventos";
"Show Upcoming Event View" = "Mostrar el próximo evento";
"Show All Day Meetings" = "Mostrar todas las reuniones del día";
"Show Next Meeting Title in Menubar" = "Mostrar el título de la próxima reunión en la barra de menú";
"Truncate menubar text longer than" = "Cortar el texto de la barra de menú si es mayor que";
"characters" = "caracteres";
"Show events from" = "Mostrar eventos de";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Si el título de la reunión es \"Reunión con Neel\" y la longitud de corte está establecida en 5 caracteres, el texto en la barra de menú aparecerá como \"Reuni…\"";
// Notes Popover
"Reminder Set" = "Recordatorio establecido";
"Successfully set." = "Configurado con éxito.";
// Errors
"You're offline, maybe?" = "¿Quizás estás sin conexión a internet?";
"Try again, maybe?" = "¿Podrías intentarlo otra vez?";
"The Internet connection appears to be offline." = "Parece que no hay conexión a internet.";
// UI Tests
"New Zealand" = "Nueva Zelanda";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/fr.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/fr.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Merci d'aider à améliorer Clocker !";
"iRateMessageTitle" = "Noter %@";
"iRateAppMessage" = "Si vous aimez utiliser %@, pourriez-vous prendre un moment pour l'évaluer ? Cela ne prendra pas plus d'une minute. Merci pour votre soutien !";
"iRateGameMessage" = "Si vous aimez utiliser %@, pourriez-vous prendre un moment pour l'évaluer ? Cela ne prendra pas plus d'une minute. Merci pour votre soutien !";
"iRateCancelButton" = "Non Merci";
"iRateRateButton" = "Évaluez-le maintenant";
"iRateRemindButton" = "Me le rappeler ultérieurement";
"iRateUpdateMessage" = "Mettre à jour maintenant ?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Merci pour votre aide à rendre Clocker encore meilleur!";
"app-name" = "Clocker";
"start-at-login" = "Activer avec la session";
"setup-steps" = "Plus que trois marches à gravir et vous aurez ajusté Clocker";
"Permissions-Header" = "Droits d'accès";
"See your next Calendar event here." = "Retrouvez votre prochain événement de calendrier ici.";
"Click here to start." = "Cliquez ici pour commencer.";
"Reminders Access" = "Accès aux rappels";
"Calendar Access" = "Accès au Calendrier";
"Permissions" = "Autorisations";
"Calendar Detail" = "Les événements à venir de vos calendriers personnels et partagés peuvent être affichés dans la barre de menus et dans le panneau.";
"Reminders Detail" = "Placez des rappels dans le fuseau horaire de votre choix. Vos rappels seront enregistrés dans l'application 'Rappels' par défaut.";
"Privacy Text" = "Vous pourrez modifier cela plus tard dans la section Confidentialité des Préférences Système.";
"Granted Button Text" = "Autorisé";
"Denied Button Text" = "Refusée";
"Grant Button Text" = "Autoriser";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Cela ne prend que 3 étapes pour configurer Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Préférences";
"Appearance Tab" = "Apparence";
"Calendar Tab" = "Calendrier";
"About Tab" = "À propos";
"Permissions Tab" = "Autorisations";
// General Preferences Screen
"Start at Login" = "Démarrer Clocker à la connexion";
"Sort by Time Difference" = "Trier par différence de temps";
"Sort by Name" = "Tri par nom";
"Sort by Label" = "Trier par étiquette";
"Search Field Placeholder" = "Saisissez une ville, une région ou un pays";
"No Timezone Selected" = "Veuillez sélectionner un fuseau horaire !";
"Max Timezones Selected" = "100 fuseaux horaires maximum autorisés !";
"Max Search Characters" = "50 caractères maximum autorisés !";
"Add Button Title" = "Ajouter";
"Close Button Title" = "Fermer";
// Onboarding
"Open Clocker At Login" = "Ouvrir Clocker à la connexion";
"Launch Clocker" = "Lancer Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Cela ne prend que 3 étapes pour configurer Clocker.";
"Get Started" = "Commencer";
// Permissions
"Calendar Access Title" = "Accès au calendrier";
"Reminders Access Title" = "Accès aux rappels";
"Later Config Description" = "Ces paramètres peuvent être configurés plus tard dans les Préférences Système.";
"Back" = "Retour";
"Continue" = "Continuer";
"Clocker is more useful when it can display events from your calendars." = "Clocker est plus utile quand il peut afficher des événements de vos calendriers.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker est plus utile quand il peut afficher des événements de vos calendriers. Vous pouvez modifier ce paramètre dans Préférences Système › Sécurité & Confidentialité › Confidentialité.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Préférences de démarrage";
"Grant Access" = "Autoriser l'accès";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Les événements à venir de vos calendriers personnels et partagés peuvent être affichés dans la barre de menus et dans le panneau.";
"Granted" = "Autorisé";
"Denied" = "Refusé";
"Grant" = "Autoriser";
"Unexpected" = "Inattendu";
// Onboarding Search
"Quick Add Locations" = "Ajouter rapidement des emplacements";
"More search options in Clocker Preferences." = "Plus d'options de recherche dans les Préférences de Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "Entrez 3 caractères ou plus pour les emplacements que vous souhaitez ajouter";
// Start at Login
"Launch at Login" = "Démarrer à la connexion";
"This can be configured later in Clocker Preferences." = "Ceci peut être configuré plus tard dans les préférences de Clocker.";
"Should Clocker open automatically on startup?" = "Clocker doit-il s'ouvrir automatiquement au démarrage ?";
// Final Onboarding Screen
"You're all set!" = "Tout est prêt !";
"Thank you for the details." = "Merci pour votre commentaire.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Vous verrez une icône d'horloge dans votre barre de menu lorsque vous lancez l'application. Si vous souhaitez voir une icône de dock, allez dans Préférences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Si vous souhaitez nous aider à localiser l'application dans votre langue ou recevoir des mises à jour peu fréquentes liées à l'application, veuillez entrer votre adresse e-mail !";
// Appearance Tab
"Panel Theme" = "Apparence de la fenêtre";
"Favourite a timezone to enable menubar display options." = "Mettre en favori un fuseau horaire pour activer les options d'affichage de la barre de menus.";
"Main Panel Options" = "Options de la fenêtre principale";
"Time Format" = "Format de l'heure";
"Day Display Options" = "Options d'affichage du jour";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Afficher le lever/coucher du soleil";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Prévisualisation";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "Aucun lieu ajouté";
// Panel
"No upcoming event." = "Aucun événement à venir.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Floride";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/hi.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "विश्व का समय";
"CFBundleName" = "विश्व का समय";
================================================
FILE: Clocker/Clocker/hi.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "विश्व का समय";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Rate %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "No, Thanks";
"iRateRateButton" = "Rate It Now";
"iRateRemindButton" = "Remind Me Later";
"iRateUpdateMessage" = "Update now?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Thank you for helping make Clocker even better!";
"app-name" = "Clocker";
"start-at-login" = "Start At Login";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "अनुमति";
"See your next Calendar event here." = "अपना अगला कैलेंडर कार्यक्रम यहां देखें।";
"Click here to start." = "शुरू करने के लिए यहाँ क्लिक करें।";
"Reminders Access" = "रिमाइंडर अनुमति";
"Calendar Access" = "कैलेंडर अनुमति";
"Permissions" = "अनुमति";
"Reminders Detail" = "अपनी पसंद के स्थान के समय क्षेत्र में रिमाइंडर सेट करें। आपके रिमाइंडर डिफ़ॉल्ट रिमाइंडर ऐप में संग्रहीत किए जाते हैं।";
"Calendar Detail" = "अपने निजी और साझा कैलेंडर से आने वाली घटनाओं मेनूबार और पैनल में दिखाया जा सकता है।";
"Privacy Text" = "आप आपकी पसंद भविष्य में सिस्टम प्रिफ्रेंसेज के प्राइवसी अनुभाग में बदल सकते हैं।";
"Granted Button Text" = "स्वीकृत";
"Denied Button Text" = "इनकार किया";
"Grant Button Text" = "अनुदान";
// Tab Item Titles
"Preferences Tab" = "प्रिफ्रेंसेज";
"Appearance Tab" = "दिखावट";
"Calendar Tab" = "कैलेंडर";
"About Tab" = "अबाउट";
"Permissions Tab" = "अनुमति";
// General Preferencess
"Start at Login" = "लॉगिन पर शुरू करें";
"Sort by Time Difference" = "समय अंतर द्वारा सॉर्ट करें";
"Sort by Name" = "नाम द्वारा सॉर्ट करें";
"Sort by Label" = "लेबल द्वारा सॉर्ट करें";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "ऐड ";
"Close Button Title" = "बंद करे";
// Onboarding
"Open Clocker At Login" = "Open Clocker At Login";
"Launch Clocker" = "Launch Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "बस तीन स्टेप् और एप्लिकेशन तैयार।";
"Get Started" = "शुरु करे";
// Permissions
"Calendar Access Title" = "कैलेंडर एक्सेस";
"Reminders Access Title" = "रिमाइंडर एक्सेस";
"Later Config Description" = "इन्हें बाद में सिस्टम प्राथमिकता में कॉन्फ़िगर किया जा सकता है।";
"Back" = "वापस";
"Continue" = "जारी रखें";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "प्रकटन";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "न्यूज़ीलैंड";
"Florida" = "फ्लोरिडा";
"San Francisco" = "सान फ्रांसिस्को";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/hr.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/hr.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 7/9/21.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Hvala što pomažeš poboljšati Clocker!";
"iRateMessageTitle" = "Ocijeni %@";
"iRateAppMessage" = "Ako voliš koristiti %@, ocijeni program. Postupak ocjenjivanja traje manje od jedne minute. Hvala na podršci!";
"iRateGameMessage" = "Ako voliš igrati %@, ocijeni program. Postupak ocjenjivanja traje manje od jedne minute. Hvala na podršci!";
"iRateCancelButton" = "Ne, hvala";
"iRateRateButton" = "Ocijeni";
"iRateRemindButton" = "Podsjeti me kasnije";
"iRateUpdateMessage" = "Sada aktualizirati?";
"ClockerVersion" = "Verzija %@";
"CLFeedbackAlertTitle" = "Hvala što pomažeš poboljšati Clocker!";
"app-name" = "Clocker";
"start-at-login" = "Pokreni nakon prijave";
"setup-steps" = "Za postavljanje programa Clocker potrebna su samo tri koraka";
"Permissions-Header" = "Dozvole";
"See your next Calendar event here." = "Ovdje pogledaj svoje sljedeće kalendarske događaje.";
"Click here to start." = "Pritisni ovdje za pokretanje.";
"Reminders Access" = "Pristup podsjetnicima";
"Calendar Access" = "Pristup kalendaru";
"Permissions" = "Dozvole";
"Calendar Detail" = "Predstojeći događaji iz tvojih osobnih i zajedničkih kalendara mogu se prikazati u traci izbornika i na ploči.";
"Reminders Detail" = "Postavi podsjetnike u tvoju vremensku zonu mjesta. Tvoji se podsjetnici spremaju u standardni program Podsjetnici.";
"Privacy Text" = "Ovo možeš kasnije promijeniti u odjeljku Privatnost u Postavkama sustava.";
"Granted Button Text" = "Dozvoljeno";
"Denied Button Text" = "Zabranjeno";
"Grant Button Text" = "Dozvoli";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Za postavljanje programa Clocker potrebna su samo tri koraka.";
"Get Started" = "Početak";
// Tab Item Titles
"Preferences Tab" = "Postavke";
"Appearance Tab" = "Izgled";
"Calendar Tab" = "Kalendar";
"About Tab" = "Informacije";
"Permissions Tab" = "Dozvole";
// General Preferences Screen
"Start at Login" = "Pokreni Clocker nakon prijave";
"Sort by Time Difference" = "Razvrstaj po vremenskoj ralzici";
"Sort by Name" = "Razvrstaj po imenu";
"Sort by Label" = "Razvrstaj po oznaci";
"Search Field Placeholder" = "Upiši grad, državu ili zemlju";
"No Timezone Selected" = "Odaberi vremensku zonu!";
"Max Timezones Selected" = "Ograničeno na 100 vremenskih zona!";
"Max Search Characters" = "Ograničeno na 50 znakova!";
"Add Button Title" = "Dodaj";
"Close Button Title" = "Zatvori";
// Onboarding
"Open Clocker At Login" = "Otvori Clocker nakon prijave";
"Launch Clocker" = "Pokreni Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Za postavljanje programa Clocker potrebna su samo tri koraka.";
"Get Started" = "Početak";
// Permissions
"Calendar Access Title" = "Pristup kalendaru";
"Reminders Access Title" = "Pristup podsjetnicima";
"Later Config Description" = "Mogu se kasnije konfigurirati u postavkama sustava.";
"Back" = "Natrag";
"Continue" = "Nastavi";
"Clocker is more useful when it can display events from your calendars." = "Clocker je korisniji kad može prikazivati događaje u tvojim kalendarima.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker je korisniji kad može prikazivati događaje u tvojim kalendarima. Ovu postavku možeš promijeniti u Postavke sustava › Sigurnost i privatnost › Privatnost.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Pokreni postavke";
"Grant Access" = "Dopusti pristup";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Predstojeći događaji iz tvojih osobnih i zajedničkih kalendara mogu se prikazati u traci izbornika i na ploči.";
"Granted" = "Dodijeljeno";
"Denied" = "Odbijeno";
"Grant" = "Odobrenje";
"Unexpected" = "Neočekivano";
// Onboarding Search
"Quick Add Locations" = "Brzo dodavanje mjesta";
"More search options in Clocker Preferences." = "Daljnje opcije pretage u Clocker postavkama.";
"Enter 3 or more characters for locations you'll like to add" = "Upiši tri ili više znakova za mjesta koja želiš dodati";
// Start at Login
"Launch at Login" = "Pokreni nakon prijave";
"This can be configured later in Clocker Preferences." = "Ovo se može kasnije konfigurirati u Clocker postavkama.";
"Should Clocker open automatically on startup?" = "Želiš li automatski pokrenuti Clocker nakon pokretanja računala?";
// Final Onboarding Screen
"You're all set!" = "Sve je spremno!";
"Thank you for the details." = "Hvala ti na detalju.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Kad pokreneš program, u traci izbornika vidjet ćeš ikonu sata. Ako želiš vidjeti ikonu u traci programa, idi na Postavke.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Ako želiš pomoći prevesti program na tvoj jezik ili primati rijetke obavijesti o novim verzijama programa, upiši tvoju e-mail adresu!";
// Appearance Tab
"Panel Theme" = "Tema ploče";
"Favourite a timezone to enable menubar display options." = "Odaberi vremensku zonu za aktiviranje opcija prikaza trake izbornika.";
"Main Panel Options" = "Opcije glavne ploče";
"Time Format" = "Format za vrijeme";
"Day Display Options" = "Opcije za prikaz dana";
"Show Future Slider" = "Prikaži klizač budućnosti";
"Show Sunrise/Sunset" = "Prikaži izlazak/zalazak sunca";
"Display the time in seconds" = "Prikaži vrijeme u sekundama";
"Larger Text" = "Veći tekst";
"Future Slider Range" = "Klizač za raspon budućnosti";
"Include Date" = "Uključi datum";
"Include Day" = "Uključi dan";
"Include Place Name" = "Uključi ime mjesta";
"Menubar Display Options" = "Opcije prikaza izbornika";
/* Appears in Preferences -> Appearance which allows the user to switch between the compact and standard menubar mode. It doesn't lead anywhere. */
"Menubar Mode" = "Modus izbornika";
"Preview" = " Pregled";
"Miscellaneous" = "Razno";
// Empty View
"No places added" = "Nema dodanih mjesta";
// Panel
"No upcoming event." = "Nema predstojećih događaja.";
"You have no events scheduled for tomorrow." = "Za sutra nemaš zakazanih događaja.";
// Review
"Enjoy using Clocker?" = "Voliš Clocker?";
// App Feedback
"Tell us what you think!" = "Javi nam što misliš!";
"Contact Information (Optional)" = "Kontaktni podaci (opcionalno)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Polja za kontakt nisu obavezna! Tvoji kontaktni podaci omogućit će nam da te kontaktiramo u slučaju da trebamo daljnje informacije ili ako možemo pomoći!";
// About View Screen
"Feedback is always welcome:" = "Uvijek se radujemo povratnim informacijama:";
// Calendars View
"Upcoming Event View Options" = "Opcije prikaza predstojećih događaja";
"Show Upcoming Event View" = "Prikaži prikaz predstojećih događaja";
"Show All Day Meetings" = "Prikaži cjelodnevne sastanke";
"Show Next Meeting Title in Menubar" = "Prikaži sljedeći sastanak u traci izbornika";
"Truncate menubar text longer than" = "Skrati tekst u traci izbornika koji je duži od";
"characters" = "znakova";
"Show events from" = "Prikaži događaje od";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Ako je naslov sastanka „Sastanak s Vladimirom”, a kraćenje je postavljeno na 5, tekst na traci pojavit će se kao „Sasta …”";
// Notes Popover
"Reminder Set" = "Postavljanje podsjetnika";
"Successfully set." = "Uspješno postavljeno.";
// Errors
"You're offline, maybe?" = "Možda nemaš vezu s internetom?";
"Try again, maybe?" = "Želiš li ponovo pokušati?";
"The Internet connection appears to be offline." = "Čini se da ne postoji veza s internetom.";
// UI Tests
"New Zealand" = "Novi Zeland";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Prijelaz na ljetno računanje vremena dogodit će se za < 24 sata";
"Copied to Clipboard" = "Kopirano u međuspremnik";
"No upcoming events for today!" = "Za danas nema predstojećih događaja 🎉";
"Great going." = "Super.";
"Happy Weekend." = "Uživaj vikend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/it.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/it.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Rate %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "No, Thanks";
"iRateRateButton" = "Rate It Now";
"iRateRemindButton" = "Remind Me Later";
"iRateUpdateMessage" = "Update now?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Thank you for helping make Clocker even better!";
"app-name" = "Clocker";
"start-at-login" = "Start At Login";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "Permissions";
"See your next Calendar event here." = "See your next Calendar event here.";
"Click here to start." = "Click here to start.";
"Reminders Access" = "Reminders Access";
"Calendar Access" = "Calendar Access";
"Permissions" = "Permissions";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Granted";
"Denied Button Text" = "Denied";
"Grant Button Text" = "Grant";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Preferences";
"Appearance Tab" = "Appearance";
"Calendar Tab" = "Calendar";
"About Tab" = "About";
"Permissions Tab" = "Permissions";
// General Preferences Screen
"Start at Login" = "Start Clocker at Login";
"Selected Timezones" = "Selected Timezones";
"Sort by Time Difference" = "Sort by Time Difference";
"Sort by Name" = "Sort by Name";
"Sort by Label" = "Sort by Label";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "Add";
"Close Button Title" = "Close";
// Onboarding
"Open Clocker At Login" = "Open Clocker At Login";
"Launch Clocker" = "Launch Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Permissions
"Calendar Access Title" = "Calendar Access";
"Reminders Access Title" = "Reminders Access";
"Later Config Description" = "These can be configured later in System Preferences.";
"Back" = "Back";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Search Locations" = "Search Locations";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/ja.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/ja.lproj/Localizable.strings
================================================
"About Tab" = "このプログラムについて";
"Add Button Title" = "追加";
"Appearance Tab" = "外観";
"Back" = "戻る";
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CLFeedbackAlertTitle" = "Clocker の品質向上にご協力いただきありがとうございます!";
"Calendar Access" = "カレンダーアクセス";
/* Permissions */
"Calendar Access Title" = "カレンダーアクセス";
"Calendar Detail" = "個人カレンダーおよび共有カレンダーからの今後のイベントをメニューバーとパネルに表示させることができます。";
"Calendar Tab" = "カレンダー";
"Click here to start." = "ここをクリックして開始します。";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"ClockerVersion" = "バージョン %@";
"Close Button Title" = "閉じる";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
"Continue" = "続ける";
"Copied to Clipboard" = "Copied to Clipboard";
"Day Display Options" = "Day Display Options";
/* DST changes */
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Denied" = "Denied";
"Denied Button Text" = "拒否されています";
"Display the time in seconds" = "Display the time in seconds";
/* Review */
"Enjoy using Clocker?" = "Enjoy using Clocker?";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
"Favourite a timezone to enable menubar display options." = "メニューバーの表示オプションを有効にするには、タイムゾーンをお気に入りとして登録してください。";
/* About View Screen */
"Feedback is always welcome:" = "Feedback is always welcome:";
"Florida" = "Florida";
"Future Slider Range" = "Future Slider Range";
"Get Started" = "はじめに";
"Get Started" = "はじめに";
"Grant" = "Grant";
"Grant Access" = "Grant Access";
"Grant Button Text" = "許可";
"Granted" = "Granted";
"Granted Button Text" = "許可されています";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
/* Welcome Onboarding */
"It only takes 3 steps to set up Clocker." = "Clocker のセットアップは3ステップのみです。";
/* Welcome Onboarding */
"It only takes 3 steps to setup Clocker." = "Clocker のセットアップは3ステップのみです。";
"Larger Text" = "Larger Text";
"Later Config Description" = "これらはシステム環境設定で後から設定できます。";
"Launch Clocker" = "Clocker を起動";
"Launch Preferences" = "Launch Preferences";
/* Start at Login */
"Launch at Login" = "Launch at Login";
"Main Panel Options" = "Main Panel Options";
"Max Search Characters" = "設定可能な文字数は50です!";
"Max Timezones Selected" = "最大で100の時間帯が設定可能です!";
"Menubar Display Options" = "メニューバーの表示オプション";
"Menubar Mode" = "メニューバーモード";
"Miscellaneous" = "その他";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
/* UI Tests */
"New Zealand" = "New Zealand";
"No Timezone Selected" = "時間帯を選択してください!";
/* Empty View */
"No places added" = "No places added";
/* Panel */
"No upcoming event." = "No upcoming event.";
"No upcoming events for today!" = "No upcoming events for today 🎉";
/* Onboarding */
"Open Clocker At Login" = "ログイン時に Clocker を開始";
/* Appearance Tab */
"Panel Theme" = "Panel Theme";
"Permissions" = "アクセス許可";
"Permissions Tab" = "アクセス許可";
"Permissions-Header" = "アクセス許可";
/* Tab Item Titles */
"Preferences Tab" = "設定";
"Preview" = "プレビュー";
"Privacy Text" = "この設定はシステム環境設定のプライバシーセクションであとから変更が可能です。";
/* Onboarding Search */
"Quick Add Locations" = "場所を簡単に追加";
/* Notes Popover */
"Reminder Set" = "Reminder Set";
"Reminders Access" = "リマインダーアクセス";
"Reminders Access Title" = "リマインダーアクセス";
"Reminders Detail" = "選択したロケーションのタイムゾーンでリマインダーを設定します。リマインダーはデフォルトのリマインダーアプリに保存されます。";
"San Francisco" = "San Francisco";
"Search Field Placeholder" = "都市名、州や県、国名を入力してください";
"See your next Calendar event here." = "次回のカレンダーイベントはこちらをご覧ください。";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Future Slider" = "Show Future Slider";
"Show Next Meeting Title in Menubar" = "次のミーティングタイトルをメニューバーに表示する";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show events from" = "Show events from";
"Sort by Label" = "ラベルで並べ替え";
"Sort by Name" = "地名で並べ替え";
"Sort by Time Difference" = "時差で並べ替え";
/* General Preferences Screen */
"Start at Login" = "ログイン時に Clocker を開始";
"Successfully set." = "Successfully set.";
/* App Feedback */
"Tell us what you think!" = "Tell us what you think!";
"Thank you for helping make Clocker even better!" = "Clocker の品質向上にご協力いただきありがとうございます!";
"Thank you for the details." = "Thank you for the details.";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Time Format" = "表示フォーマット";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"Try again, maybe?" = "Try again, maybe?";
"Unexpected" = "Unexpected";
/* Calendars View */
"Upcoming Event View Options" = "Upcoming Event View Options";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "アプリを起動すると、メニューバーに時計のアイコンが表示されます。ドックのアイコンが表示される場合は、format@@0に進みます。";
/* Final Onboarding Screen */
"You're all set!" = "You're all set!";
/* Errors */
"You're offline, maybe?" = "オフラインのようです。";
"app-name" = "Clocker";
"characters" = "characters";
"iRateAppMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateCancelButton" = "いいえ、結構です";
"iRateGameMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateMessageTitle" = "%@ を評価";
"iRateRateButton" = "今すぐ評価します";
"iRateRemindButton" = "後で通知する";
"iRateUpdateMessage" = "今すぐアップデートしますか?";
"setup-steps" = "Clocker のセットアップは3ステップのみです";
"start-at-login" = "ログイン時に開始";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/ko.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/ko.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "시계";
"Thank you for helping make Clocker even better!" = "Clocker가 더 발전할 수 있도록 도와주셔서 정말 감사합니다!";
"iRateMessageTitle" = "비율 %@ ";
"iRateAppMessage" = "%@을 즐기고 계신다면, 잠시 평가를 위해 시간을 내주시겠습니까? 단 1분도 걸리지 않겠습니다. 지원해주셔서 감사합니다!";
"iRateGameMessage" = "%@을 즐기고 계신다면, 잠시 평가를 위해 시간을 내주시겠습니까? 단 1분도 걸리지 않겠습니다. 지원해주셔서 감사합니다!";
"iRateCancelButton" = "나중에 할게요";
"iRateRateButton" = "지금 평가하기";
"iRateRemindButton" = "나중에 다시 알리기";
"iRateUpdateMessage" = "지금 업데이트를 진행할까요?";
"ClockerVersion" = "버전 %@";
"CLFeedbackAlertTitle" = "Clocker가 더 발전할 수 있도록 도와주셔서 정말 감사합니다!";
"app-name" = "시계";
"start-at-login" = "로그인을 해주세요";
"setup-steps" = "시계를 설정하는데 3가지만 하시면 됩니다";
"Permissions-Header" = "권한";
"See your next Calendar event here." = "당신의 다음 일정을 여기서 보세요";
"Click here to start." = "여기를 눌러서 시작합니다.";
"Reminders Access" = "리마인더 권한";
"Calendar Access" = "캘린더 권한";
"Permissions" = "권한";
"Calendar Detail" = "여러분의 개인&공유 캘린더에서 다가오는 이벤트들은 메뉴바와 패널에서 보여질 수 있습니다.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Granted";
"Denied Button Text" = "Denied";
"Grant Button Text" = "Grant";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Preferences";
"Appearance Tab" = "Appearance";
"Calendar Tab" = "Calendar";
"About Tab" = "About";
"Permissions Tab" = "Permissions";
// General Preferences Screen
"Start at Login" = "Start Clocker at Login";
"Sort by Time Difference" = "Sort by Time Difference";
"Sort by Name" = "Sort by Name";
"Sort by Label" = "Sort by Label";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "50 문자까지만 허용됩니다!";
"Add Button Title" = "추가";
"Close Button Title" = "닫기";
// Onboarding
"Open Clocker At Login" = "로그인해서 Clocker 열기";
"Launch Clocker" = "Clocker 실행하기";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Permissions
"Calendar Access Title" = "캘린더 접근";
"Reminders Access Title" = "리마인더 권한";
"Later Config Description" = "이것들은 나중에 설정에서 바꾸실 수 있습니다";
"Back" = "Back";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "글씨를 크게하기";
"Future Slider Range" = "미래 슬라이더 범위";
"Include Date" = "날짜 추가하기";
"Include Day" = "시간 추가하기";
"Include Place Name" = "장소 이름";
"Menubar Display Options" = "메뉴바 화면표시 설정";
"Menubar Mode" = "메뉴바 모드";
"Preview" = "미리보기";
"Miscellaneous" = "기타";
// Empty View
"No places added" = "추가된 장소가 없음";
// Panel
"No upcoming event." = "예정된 이벤트 없음";
"You have no events scheduled for tomorrow." = "내일 일정이 없어요!";
// Review
"Enjoy using Clocker?" = "Clocker 사용에 만족하십니까?";
// App Feedback
"Tell us what you think!" = "여러분의 의견을 들려주세요.";
"Contact Information (Optional)" = "연락처 정보 (선택)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "연락처 필드는 선택 사항입니다! 귀하의 연락처 정보는 추가 정보가 필요하거나 도움이 필요한 경우 연락을 드릴 것입니다!";
// About View Screen
"Feedback is always welcome:" = "피드백은 언제나 환영입니다:";
// Calendars View
"Upcoming Event View Options" = "다가오는 이벤트 보기 옵션";
"Show Upcoming Event View" = "다가오는 일정 보기";
"Show All Day Meetings" = "모든 일정 보기";
"Show Next Meeting Title in Menubar" = "다음 일정을 메뉴바에서 보기";
"Truncate menubar text longer than" = "다음보다 긴 메뉴 표시 줄 텍스트를 자릅니다.
";
"characters" = "글자";
"Show events from" = "오늘부터 이벤트 표시";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "만약 미팅 제목이 \"Meeting with Neel\" 이면 5글자만 보여지기 때문에 주의해주세요. (\"Meeti...\")";
// Notes Popover
"Reminder Set" = "알림 설정";
"Successfully set." = "설정이 완료되었습니다";
// Errors
"You're offline, maybe?" = "당신은 오프라인입니다. 아마도?";
"Try again, maybe?" = "다시 시도 해보세요";
"The Internet connection appears to be offline." = "인터넷 연결이 오프라인 상태입니다.";
// UI Tests
"New Zealand" = "뉴질랜드";
"Florida" = "플로리다";
"San Francisco" = "샌프란시스코";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉!";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/main.m
================================================
// Copyright © 2015 Abhishek Banthia
#import
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}
================================================
FILE: Clocker/Clocker/nl.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/nl.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Rate %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "No, Thanks";
"iRateRateButton" = "Rate It Now";
"iRateRemindButton" = "Remind Me Later";
"iRateUpdateMessage" = "Update now?";
"ClockerVersion" = "Version %@";
"CLFeedbackAlertTitle" = "Thank you for helping make Clocker even better!";
"app-name" = "Clocker";
"start-at-login" = "Start At Login";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "Permissions";
"See your next Calendar event here." = "See your next Calendar event here.";
"Click here to start." = "Click here to start.";
"Reminders Access" = "Reminders Access";
"Calendar Access" = "Calendar Access";
"Permissions" = "Permissions";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Granted";
"Denied Button Text" = "Denied";
"Grant Button Text" = "Grant";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Tab Item Titles
"Preferences Tab" = "Preferences";
"Appearance Tab" = "Appearance";
"Calendar Tab" = "Calendar";
"About Tab" = "About";
"Permissions Tab" = "Permissions";
// General Preferences Screen
"Start at Login" = "Start Clocker at Login";
"Sort by Time Difference" = "Sort by Time Difference";
"Sort by Name" = "Sort by Name";
"Sort by Label" = "Sort by Label";
"Search Field Placeholder" = "Enter a city, state or country name";
"No Timezone Selected" = "Please select a timezone!";
"Max Timezones Selected" = "Maximum 100 timezones allowed!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "Add";
"Close Button Title" = "Close";
// Onboarding
"Open Clocker At Login" = "Open Clocker At Login";
"Launch Clocker" = "Launch Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Get Started";
// Permissions
"Calendar Access Title" = "Calendar Access";
"Reminders Access Title" = "Reminders Access";
"Later Config Description" = "These can be configured later in System Preferences.";
"Back" = "Back";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/pl.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/pl.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Dziękujemy za pomoc przy rozwijaniu Clockera!";
"iRateMessageTitle" = "Oceń %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "Nie, dziękuję";
"iRateRateButton" = "Oceń teraz";
"iRateRemindButton" = "Przypomnij mi później";
"iRateUpdateMessage" = "Zaktualizuj teraz";
"ClockerVersion" = "Wersja %@";
"CLFeedbackAlertTitle" = "Dziękujemy za pomoc przy rozwijaniu Clockera!";
"app-name" = "Clocker";
"start-at-login" = "Uruchom przy logowaniu";
"setup-steps" = "It only takes 3 steps to set up Clocker";
"Permissions-Header" = "Uprawnienia";
"See your next Calendar event here." = "Tu zobaczysz swoje najbliższe wydarzenie z kalendarza.";
"Click here to start." = "Kliknij tutaj, aby rozpocząć.";
"Reminders Access" = "Dostęp do powiadomień";
"Calendar Access" = "Dostęp do kalendarza";
"Permissions" = "Uprawnienia";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Set reminders in the timezone of the location of your choice. Your reminders are stored in the default Reminders app.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Przyznane";
"Denied Button Text" = "Odrzucone";
"Grant Button Text" = "Przyznaj";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Rozpocznij";
// Tab Item Titles
"Preferences Tab" = "Ustawienia";
"Appearance Tab" = "Wygląd";
"Calendar Tab" = "Kalendarz";
"About Tab" = "O aplikacji";
"Permissions Tab" = "Uprawnienia";
// General Preferences Screen
"Start at Login" = "Uruchom Clockera przy logowaniu";
"Sort by Time Difference" = "Sortuj według Różnicy Czasu";
"Sort by Name" = "Sortuj wg Nazwy";
"Sort by Label" = "Sortuj według Etykiety";
"Search Field Placeholder" = "Wprowadź miasto, województwo lub nazwę kraju";
"No Timezone Selected" = "Wybierz strefę czasową!";
"Max Timezones Selected" = "Dozwolone maksymalnie 100 stref czasowych!";
"Max Search Characters" = "Dozwolone jest tylko 50 znaków!";
"Add Button Title" = "Dodaj";
"Close Button Title" = "Zamknij";
// Onboarding
"Open Clocker At Login" = "Uruchom Clockera przy logowaniu";
"Launch Clocker" = "Uruchom Clockera";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "It only takes 3 steps to setup Clocker.";
"Get Started" = "Rozpocznij";
// Permissions
"Calendar Access Title" = "Dostęp do kalendarza";
"Reminders Access Title" = "Dostęp do powiadomień";
"Later Config Description" = "These can be configured later in System Preferences.";
"Back" = "Wstecz";
"Continue" = "Dalej";
"Clocker is more useful when it can display events from your calendars." = "Clocker jest bardziej przydatny, gdy może wyświetlać wydarzenia z Twojego kalendarza.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Preferencje uruchomienia";
"Grant Access" = "Przyznaj dostęp";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Nieoczekiwany";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Uruchom przy logowaniu";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "Wszystko gotowe!";
"Thank you for the details." = "Dziękuję za szczegóły.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Główny panel opcji";
"Time Format" = "Format czasu";
"Day Display Options" = "Opcje wyswietlania daty";
"Show Future Slider" = "Pokaż suwak przyszłości";
"Show Sunrise/Sunset" = "Pokaż wschód/zachód Słońca";
"Display the time in seconds" = "Wyświetl czas z sekundami";
"Larger Text" = "Powiększenie tekstu";
"Future Slider Range" = "Zakres suwaka przyszłości";
"Include Date" = "Pokaż datę";
"Include Day" = "Pokaż dzień";
"Include Place Name" = "Pokaż miejsce";
"Menubar Display Options" = "Opcje wyświetlania paska menu";
/* Appears in Preferences -> Appearance which allows the user to switch between the compact and standard menubar mode. It doesn't lead anywhere. */
"Menubar Mode" = "Wygląd na pasku menu";
"Preview" = "Podgląd";
"Miscellaneous" = "Pozostałe";
// Empty View
"No places added" = "Brak dodanych miejsc";
// Panel
"No upcoming event." = "Brak nadchodzących wydarzeń.";
"You have no events scheduled for tomorrow." = "Nie masz zaplanowanych wydarzeń na jutro.";
// Review
"Enjoy using Clocker?" = "Podoba ci się Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Dane kontaktowe (opcjonalnie)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Twoja opinia jest zawsze mile widziana:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Pokaż całodniowe spotkania";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "znaki";
"Show events from" = "Pokaż wydarzenia z";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Przypomnienie ustawione";
"Successfully set." = "Zapisane.";
// Errors
"You're offline, maybe?" = "Jesteś offline (?)";
"Try again, maybe?" = "Spróbuj ponownie później";
"The Internet connection appears to be offline." = "Wygląda na to, że nie działa połączenie z internetem.";
// UI Tests
"New Zealand" = "Nowa Zelandia";
"Florida" = "Floryda";
"San Francisco" = "San Francisco";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/pt-BR.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Obrigado por ajudar a tornar o Clocker ainda melhor!";
"iRateMessageTitle" = "Avaliar %@";
"iRateAppMessage" = "Se você gosta de usar o %@, você se importaria de avaliá-lo? Não vai demorar mais de um minuto. Obrigado por seu apoio!";
"iRateGameMessage" = "Se você está gostando jogar %@, poderia avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!";
"iRateCancelButton" = "Não, Obrigado";
"iRateRateButton" = "Avaliar Agora";
"iRateRemindButton" = "Lembrar mais tarde";
"iRateUpdateMessage" = "Atualizar agora?";
"ClockerVersion" = "Versão %@";
"CLFeedbackAlertTitle" = "Obrigado por ajudar a tornar o Clocker ainda melhor!";
"app-name" = "Clocker";
"start-at-login" = "Iniciar ao iniciar sessão";
"setup-steps" = "São apenas 3 passos para configurar o Clocker";
"Permissions-Header" = "Permissões";
"See your next Calendar event here." = "Veja seu próximo evento do Calendário aqui.";
"Click here to start." = "Clique aqui para iniciar.";
"Reminders Access" = "Acessos aos Lembretes";
"Calendar Access" = "Acesso ao Calendário";
"Permissions" = "Permissões";
"Calendar Detail" = "Próximos eventos de seus calendários pessoais e compartilhados podem ser exibidos no menu e no painel.";
"Reminders Detail" = "Defina lembretes no fuso horário da localização de sua escolha. Seus lembretes são armazenados no aplicativo padrão Lembretes.";
"Privacy Text" = "Você pode alterar isso mais tarde na seção Privacidade das Preferências do Sistema.";
"Granted Button Text" = "Concedida";
"Denied Button Text" = "Rejeitada";
"Grant Button Text" = "Conceder";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "São apenas 3 passos para configurar o Clocker.";
"Get Started" = "Comece a Usar";
// Tab Item Titles
"Preferences Tab" = "Preferências";
"Appearance Tab" = "Aparência";
"Calendar Tab" = "Calendário";
"About Tab" = "Sobre";
"Permissions Tab" = "Permissões";
// General Preferences Screen
"Start at Login" = "Iniciar Clocker ao iniciar sessão";
"Sort by Time Difference" = "Ordenar por diferença de horário";
"Sort by Name" = "Ordenar por nome";
"Sort by Label" = "Ordenar por Etiqueta";
"Search Field Placeholder" = "Insira uma cidade, estado ou país";
"No Timezone Selected" = "Por favor, selecione um fuso horário!";
"Max Timezones Selected" = "Máximo de fusos horários permitido: 100!";
"Max Search Characters" = "Só são permitidos até 50 caracteres!";
"Add Button Title" = "Adicionar";
"Close Button Title" = "Fechar";
// Onboarding
"Open Clocker At Login" = "Abrir o Clocker ao iniciar sessão";
"Launch Clocker" = "Iniciar Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "São apenas 3 passos para configurar o Clocker.";
"Get Started" = "Comece a Usar";
// Permissions
"Calendar Access Title" = "Acesso ao Calendário";
"Reminders Access Title" = "Acessos aos Lembretes";
"Later Config Description" = "Isso pode ser configurado mais tarde nas Preferências de Sistema.";
"Back" = "Voltar";
"Continue" = "Continuar";
"Clocker is more useful when it can display events from your calendars." = "O bloqueador é mais útil quando pode exibir eventos de seus calendários.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "O bloqueador é mais útil quando pode exibir eventos de seus calendários. Você pode alterar essa configuração em Preferências do Sistema › Segurança e Privacidade › Privacidade.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Abrir Preferências";
"Grant Access" = "Conceder Acesso";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Próximos eventos de seus calendários pessoais e compartilhados podem ser exibidos no menu e no painel.";
"Granted" = "Concedido";
"Denied" = "Negado";
"Grant" = "Conceder";
"Unexpected" = "Inesperado";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "Mais opções de busca em Preferências do Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "Insira 3 ou mais caracteres para locais que gostaria de adicionar";
// Start at Login
"Launch at Login" = "Abrir ao iniciar sessão";
"This can be configured later in Clocker Preferences." = "Isso pode ser configurado mais tarde nas Preferências do Clocker.";
"Should Clocker open automatically on startup?" = "O Clocker deve abrir automaticamente na inicialização?";
// Final Onboarding Screen
"You're all set!" = "Tudo pronto!";
"Thank you for the details." = "Obrigado pelos detalhes.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Você verá um ícone de relógio na sua Barra de Menu ao iniciar o aplicativo. Se quiser ver um ícone do Dock, vá para Preferências.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Se você quiser nos ajudar a localizar o app no seu idioma ou receber atualizações pouco frequentes, digite seu e-mail!";
// Appearance Tab
"Panel Theme" = "Tema do painel";
"Favourite a timezone to enable menubar display options." = "Favorite um fuso horário para habilitar opções de exibição na barra de menus.";
"Main Panel Options" = "Opções do painel principal";
"Time Format" = "Formato da hora";
"Day Display Options" = "Opções de Exibição do Dia";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Mostrar Nascer do Sol / Pôr do Sol";
"Display the time in seconds" = "Exibir o tempo em segundos";
"Larger Text" = "Texto Maior";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Incluir Data";
"Include Day" = "Incluir Dia";
"Include Place Name" = "Incluir Nome do Lugar";
"Menubar Display Options" = "Opções de exibição da barra de menu";
"Menubar Mode" = "Modo da barra de menu";
"Preview" = "Pré-visualizar";
"Miscellaneous" = "Diversos";
// Empty View
"No places added" = "Nenhum local adicionado";
// Panel
"No upcoming event." = "Sem eventos futuros.";
"You have no events scheduled for tomorrow." = "Você não tem eventos agendados para amanhã.";
// Review
"Enjoy using Clocker?" = "Gostando de usar o Clocker?";
// App Feedback
"Tell us what you think!" = "Conte-nos o que você pensa!";
"Contact Information (Optional)" = "Informações de Contato (Opcional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Os campos de contato são opcionais! Suas informações de contato nos permitirão entrar em contato com você caso precisemos de mais informações ou possamos ajudar!";
// About View Screen
"Feedback is always welcome:" = "Feedback é sempre bem-vindo:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Mostrar Visualização de Eventos A Seguir";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Mostrar título da próxima reunião na barra de menus";
"Truncate menubar text longer than" = "Truncar texto de menu mais longo que";
"characters" = "caracteres";
"Show events from" = "Mostrar eventos de";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Se o título da reunião for “Reunião com Neel” e o comprimento de truncagem for definido como 5, o texto na barra de menu aparecerá como “Reuni...”";
// Notes Popover
"Reminder Set" = "Lembrete definido";
"Successfully set." = "Definido com sucesso.";
// Errors
"You're offline, maybe?" = "Você está offline, talvez?";
"Try again, maybe?" = "Tentar de novo, talvez?";
"The Internet connection appears to be offline." = "A conexão à Internet parece estar desligada.";
// UI Tests
"New Zealand" = "Nova Zelândia";
"Florida" = "Flórida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/pt-PT.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/ru.lproj/InfoPlist.strings
================================================
/* InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16. */
"CFBundleDisplayName" = "Clocker";
/* (No Comment) */
"CFBundleName" = "Clocker";
/* Privacy - Calendars Usage Description */
"NSCalendarsUsageDescription" = "Clocker can be more useful when it can display upcoming events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Авторское право © 2016, Абхишек Бантия";
/* Privacy - Location Always and When In Use Usage Description */
"NSLocationAlwaysAndWhenInUseUsageDescription" = "Clocker can be more useful when it can use your location to determine your current timezone.";
/* Privacy - Location Usage Description */
"NSLocationUsageDescription" = "Clocker can be more useful when it can use your location to determine your current timezone.";
/* Privacy - Reminders Usage Description */
"NSRemindersUsageDescription" = "Clocker can be more useful when it can set reminders for your selected timezone(s). You can change this setting in System Preferences › Security & Privacy › Privacy.";
================================================
FILE: Clocker/Clocker/ru.lproj/Localizable.strings
================================================
/* (No Comment) */
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Спасибо, что помогаете сделать Clocker еще лучше!";
"iRateMessageTitle" = "Оцените";
"iRateAppMessage" = "Если вам нравится %@, просьба уделить время, чтобы поставить оценку? Это займет не больше минуты. Спасибо за вашу поддержку!";
"iRateGameMessage" = "Если вам нравится%@, просьба уделить время, чтобы поставить оценку? Это займет не больше минуты. Спасибо за вашу поддержку!";
"iRateCancelButton" = "Нет, спасибо";
"iRateRateButton" = "Поставьте рейтинг сейчас";
"iRateRemindButton" = "Напомнить позже";
"iRateUpdateMessage" = "Обновить сейчас?";
"ClockerVersion" = "Версия";
"CLFeedbackAlertTitle" = "Благодарю! Вы помогаете мне сделать Clocker лучше!";
"app-name" = "Clocker";
"start-at-login" = "Запустить при логине";
"setup-steps" = "Нужно всего 3 шага что бы настроить Clocker";
"Permissions-Header" = "Права доступа";
"See your next Calendar event here." = "Отображать здесь Ваше следующее событие из календаря.";
"Click here to start." = "Нажмите здесь что бы начать.";
"Reminders Access" = "Доступ к напоминаниям";
"Calendar Access" = "Доступ к календарю";
"Permissions" = "Разрешения";
"Calendar Detail" = "Предстоящие события из вашего личного и общего календарей могут отображаться в строке меню и на панели.";
"Reminders Detail" = "Установите напоминания в часовом поясе в выбранном вами месте. Ваши напоминания хранятся в приложении по умолчанию.";
"Privacy Text" = "Вы можете изменить это позже в разделе «Конфиденциальность» системных настроек.";
"Granted Button Text" = "Разрешено";
"Denied Button Text" = "Запрещено";
"Grant Button Text" = "Разрешение";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Для настройки Clocker требуется всего 3 шага.";
"Get Started" = "Начнем";
// Tab Item Titles
"Preferences Tab" = "Настройки";
"Appearance Tab" = "Представление";
"Calendar Tab" = "Календарь";
"About Tab" = "Об этом";
"Permissions Tab" = "Разрешения";
// General Preferences Screen
"Start at Login" = "Запустить при логине";
"Sort by Time Difference" = "Сорт по разнице времени";
"Sort by Name" = "Сорт по имени";
"Sort by Label" = "Сорт по метке";
"Search Field Placeholder" = "Введите название города, штата или страны";
"No Timezone Selected" = "Пожалуйста, выберите часовой пояс!";
"Max Timezones Selected" = "Разрешено максимум 100 часовых поясов!";
"Max Search Characters" = "Разрешено всего 50 символов!";
"Add Button Title" = "Добавить";
"Close Button Title" = "Закрыть";
// Onboarding
"Open Clocker At Login" = "Открыть Clocker при входе";
"Launch Clocker" = "Запустить Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Нужно всего 3 шага что бы настроить Clocker.";
"Get Started" = "Начало работы";
// Permissions
"Calendar Access Title" = "Доступ к календарю";
"Reminders Access Title" = "Доступ к напоминаниям";
"Later Config Description" = "Это можно настроить позже в Системных Настройках.";
"Back" = "Назад";
"Continue" = "Продолжить";
"Clocker is more useful when it can display events from your calendars." = "Clocker полезнее когда он может отображать события из ваших календарей.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker полезнее когда он может отображать предстоящие события из ваших календарей. Вы можете изменить эти настройки перейдя в Системные настройки › Защита и безопасность › Приватность.";
"Launch Preferences" = "Параметры запуска";
"Grant Access" = "Разрешить доступ";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Предстоящие события из ваших персонального и общего календарей могут быть показаны в верхнем меню и панели.";
"Granted" = "Предоставлено";
"Denied" = "Отказано";
"Grant" = "Разрешить";
"Unexpected" = "Неожиданный";
// Onboarding Search
"Quick Add Locations" = "Быстрое добавление мест";
"More search options in Clocker Preferences." = "Больше вариантов поиска в настройках Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "Введите 3 или более символов для локаций, которые вы хотите добавить";
// Start at Login
"Launch at Login" = "Запуск при входе";
"This can be configured later in Clocker Preferences." = "Это можно изменить позже в настройках Clocker.";
"Should Clocker open automatically on startup?" = "Должен ли Clocker автоматически открываться при запуске?";
// Final Onboarding Screen
"You're all set!" = "Все готово!";
"Thank you for the details." = "Спасибо Вам за подробности.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "При запуске приложения вы увидите значок часов в строке меню. Если вы хотите увидеть значок в панели Dock, перейдите в раздел Настройки.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Если вы хотите помочь нам локализовать приложение на вашем языке или получить обновления, связанные с приложениями, пожалуйста, введите ваш email!";
// Appearance Tab
"Panel Theme" = "Тема панели";
"Favourite a timezone to enable menubar display options." = "Пометьте временную зону как избранную чтобы включить параметры отображения строки меню.";
"Main Panel Options" = "Параметры главной панели";
"Time Format" = "Формат времени";
"Day Display Options" = "Параметры отображения дня";
"Show Future Slider" = "Показать ползунок";
"Show Sunrise/Sunset" = "Показывать Восход/Закат";
"Display the time in seconds" = "Отображать время в секундах";
"Larger Text" = "Увеличенный текст";
"Future Slider Range" = "Диапазон ползунка";
"Include Date" = "Добавить Дату";
"Include Day" = "Добавить День";
"Include Place Name" = "Добавить название места";
"Menubar Display Options" = "Параметры отображения меню";
"Menubar Mode" = "Режимы меню";
"Preview" = "Предпросмотр";
"Miscellaneous" = "Прочее";
// Empty View
"No places added" = "Нет добавленных мест";
// Panel
"No upcoming event." = "Нет предстоящих событий.";
"You have no events scheduled for tomorrow." = "У вас нет запланированных на завтра событий.";
// Review
"Enjoy using Clocker?" = "Понравилось приложения Clocker?";
// App Feedback
"Tell us what you think!" = "Расскажите нам, что вы думаете!";
"Contact Information (Optional)" = "Контактная информация (необязательно)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Поля контактной информации необязательны! Ваша контактная информация позволит нам связаться с вами в случае необходимости дополнительной информации или может помочь нам!";
// About View Screen
"Feedback is always welcome:" = "Обратная связь всегда приветствуется:";
// Calendars View
"Upcoming Event View Options" = "Параметры просмотра Предстоящих Событий";
"Show Upcoming Event View" = "Показывать предстоящие события";
"Show All Day Meetings" = "Показать все встречи за день";
"Show Next Meeting Title in Menubar" = "Показывать название следующей встречи в меню";
"Truncate menubar text longer than" = "Урезать текст поля меню более чем";
"characters" = "символы";
"Show events from" = "Отображать события из";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Если заголовок митинга \"Митинг с Кариной\" и длина обрезания текста установлена как 5, текст в верхнем меню будет отображаться как \"Митин...\"";
// Notes Popover
"Reminder Set" = "Напоминание установлено";
"Successfully set." = "Успешно установлено.";
// Errors
"You're offline, maybe?" = "Возможно Вы не в сети?";
"Try again, maybe?" = "Попробовать еще раз?";
"The Internet connection appears to be offline." = "Похоже, что подключение к Интернету недоступно.";
// UI Tests
"New Zealand" = "Новая Зеландия";
"Florida" = "Флорида";
"San Francisco" = "Сан-Франциско";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/tr.lproj/InfoPlist.strings
================================================
/*
InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CFBundleName" = "Clocker";
================================================
FILE: Clocker/Clocker/tr.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Clocker'ı daha iyi hale getirmek için yaptığınız yardımlara teşekkürler!";
"iRateMessageTitle" = "OylamaMesajYorum%@";
"iRateAppMessage" = "%@ uygulamamız hoşunuza gittiyse, oy vermek ister misiniz? Bir dakikadan fazla sürmeyecektir. Desteğiniz için teşekkürler!";
"iRateGameMessage" = "%@ uygulamamız hoşunuza gittiyse, oy vermek ister misiniz? Bir dakikadan fazla sürmeyecektir. Desteğiniz için teşekkürler!";
"iRateCancelButton" = "Hayır, Teşekkürler";
"iRateRateButton" = "Şimdi Oyla";
"iRateRemindButton" = "Daha sonra hatırlat";
"iRateUpdateMessage" = "Şimdi güncelle?";
"ClockerVersion" = "Versiyon%@";
"CLFeedbackAlertTitle" = "Clocker'ı daha iyi hale getirmek için yaptığınız yardımlara teşekkürler!";
"app-name" = "Clocker";
"start-at-login" = "Oturum açarken başlat";
"setup-steps" = "Clocker'ı 3 adımda kur";
"Permissions-Header" = "Yetkiler";
"See your next Calendar event here." = "Bir sonraki takvim etkinliğini buradan gör.";
"Click here to start." = "Başlamak için buraya tıklayın.";
"Reminders Access" = "Hatırlatıcıya Giriş";
"Calendar Access" = "Takvim Erişimi";
"Permissions" = "Erişim Hakları";
"Calendar Detail" = "Kişisel veya paylaşılan takvimlerinizdeki yaklaşan etkinlikler menü çubuğunda veya panelde görünebilir.";
"Reminders Detail" = "Seçtiğiniz yerin saat diliminde hatırlatıcılar ekleyin. Hatırlatıcılarınız, varsayılan uygulamasında saklanır.";
"Privacy Text" = "Bunu daha sonra Sistem Tercihleri'nin Güvenlik ve Gizlilik bölümünden değiştirebilirsiniz.";
"Granted Button Text" = "Onaylandı";
"Denied Button Text" = "Reddedildi";
"Grant Button Text" = "Onayla";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Clocker'ı 3 adımda kur.";
"Get Started" = "Başlayın";
// Tab Item Titles
"Preferences Tab" = "Ayarlar";
"Appearance Tab" = "Görünüm";
"Calendar Tab" = "Takvim";
"About Tab" = "Hakkında";
"Permissions Tab" = "Yetkiler";
// General Preferences Screen
"Start at Login" = "Clocker'ı Başlangıçta başlat";
"Sort by Time Difference" = "Zaman farkına göre sırala";
"Sort by Name" = "Ada göre sırala";
"Sort by Label" = "Etikete göre sırala";
"Search Field Placeholder" = "Bir şehir, bölge veya ülke girin";
"No Timezone Selected" = "Lütfen saat dilimi seçin!";
"Max Timezones Selected" = "En fazla 100 saat dilimi kabul edilir!";
"Max Search Characters" = "Sadece 50 karakter kabul edilir!";
"Add Button Title" = "Ekle";
"Close Button Title" = "Kapat";
// Onboarding
"Open Clocker At Login" = "Clocker'ı Başlangıçta başlat";
"Launch Clocker" = "Clocker'ı çalıştır";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Clocker'i 3 adımda kur.";
"Get Started" = "Başlayın";
// Permissions
"Calendar Access Title" = "Takvim Erişimi";
"Reminders Access Title" = "Hatırlatıcıya Giriş";
"Later Config Description" = "Bu, daha sonra Sistem Ayarlarında değiştirilebilir.";
"Back" = "Geri";
"Continue" = "Devam et";
"Clocker is more useful when it can display events from your calendars." = "Clocker takvimlerdeki etkinliklerinizi gösterebilirse daha kullanışlı hale gelebilir.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker takviminizde bulunan sıradaki etkinlikleri gösterdiğinde daha kullanışlı hale gelir. Bu ayarı Sistem Tercihleri › Güvenlik & Gizlilik › Gizlilik kısmından değiştirebilirsiniz.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Başlatma Tercihleri";
"Grant Access" = "Erişim izni ver";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Kişisel veya paylaşılan takvimlerinizdeki yaklaşan etkinlikler menü çubuğunda veya panelde görünebilir.";
"Granted" = "İzin verildi";
"Denied" = "Reddedildi";
"Grant" = "Erişim ver";
"Unexpected" = "Beklenmedik";
// Onboarding Search
"Quick Add Locations" = "Hızlı lokasyon ekle";
"More search options in Clocker Preferences." = "Clocker Tercihlerinde daha fazla arama seçenekleri bulunur.";
"Enter 3 or more characters for locations you'll like to add" = "Eklemek istediğiniz konum için 3 veya daha fazla karakter girin";
// Start at Login
"Launch at Login" = "Açılışta Başlat";
"This can be configured later in Clocker Preferences." = "Bu daha sonra Clocker Tercihlerinde düzenlenebilir.";
"Should Clocker open automatically on startup?" = "Clocker başlangıçta otomatik açılsın mı?";
// Final Onboarding Screen
"You're all set!" = "Her şey tamam!";
"Thank you for the details." = "Detaylar için teşekkür ederiz.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "Uygulamayı başlattığınızda Menü Çubuğunuzda bir saat simgesi göreceksiniz. Bir Dock simgesi görmek isterseniz Tercihler'e gidin.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "Uygulamayı kendi dilinizde yerelleştirmemize veya nadiren uygulamayla ilgili güncellemeler almanıza yardımcı olmak isterseniz, lütfen e-postanızı girin!";
// Appearance Tab
"Panel Theme" = "Panel Teması";
"Favourite a timezone to enable menubar display options." = "Menu çubuğu görünümü seçeneklerini etkinleştirmek için bir zaman dilimini favorileyin.";
"Main Panel Options" = "Ana Panel Seçenekleri";
"Time Format" = "Zaman Formatı";
"Day Display Options" = "Gün Görünüm Seçenekleri";
"Show Future Slider" = "Zaman Kaydırıcısını Göster";
"Show Sunrise/Sunset" = "Gün Doğumu/Batımı'nı Göster";
"Display the time in seconds" = "Zamanı saniye şeklinde göster";
"Larger Text" = "Daha Büyük Yazı";
"Future Slider Range" = "Zaman Kaydırıcı Aralığı";
"Include Date" = "Tarihi Dahil Et";
"Include Day" = "Günü Dahil Et";
"Include Place Name" = "Yer Adını Dahil Et";
"Menubar Display Options" = "Menu Çubuğu Görünüm Seçenekleri";
/* Appears in Preferences -> Appearance which allows the user to switch between the compact and standard menubar mode. It doesn't lead anywhere. */
"Menubar Mode" = "Menü Çubuğu Mod'u";
"Preview" = "Ön İzleme";
"Miscellaneous" = "Çeşitli";
// Empty View
"No places added" = "Yer eklenmedi";
// Panel
"No upcoming event." = "Yaklaşan etkinlik yok.";
"You have no events scheduled for tomorrow." = "Yarın için yapılacak işiniz yok.";
// Review
"Enjoy using Clocker?" = "Clocker'ı kullanmaktan memnun musun?";
// App Feedback
"Tell us what you think!" = "Bize düşüncelerinizi bildiriniz!";
"Contact Information (Optional)" = "İletişim Bilgileri (İsteğe Bağlı)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Bağlantı girdileri isteğe bağlıdır! Bağlantı bilgilerinizi, sonrasında sizden daha fazla bilgi almak veya size yardım edebilmek için gerektiğinde kullanacağız!";
// About View Screen
"Feedback is always welcome:" = "Geri bildirimleriniz memnuniyetle karşılanır:";
// Calendars View
"Upcoming Event View Options" = "Sonraki etkinliği görüntüleme seçenekleri
Takvimleri Görüntüle";
"Show Upcoming Event View" = "Yaklaşan Etkinlikleri Göster";
"Show All Day Meetings" = "Günün bütün etkinliklerini göster";
"Show Next Meeting Title in Menubar" = "Bir sonraki etkinlik başlığını Menüde göster";
"Truncate menubar text longer than" = "Menü çubuğu metnini kısalt";
"characters" = "karakterler";
"Show events from" = "Şuradaki etkinlikleri göster";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "Eğer buluşma adı \"Ahmet ile Buluşma\" ise ve kısaltma uzunluğu 5 olarak ayarlıysa, menü çubuğundaki yazı \"Ahmet...\" olarak görünecek";
// Notes Popover
"Reminder Set" = "Hatırlatıcı Ayarlandı";
"Successfully set." = "Ayarlama başarılı.";
// Errors
"You're offline, maybe?" = "Acaba çevrimdışı mısınız?";
"Try again, maybe?" = "Belki tekrar denemek istersin?";
"The Internet connection appears to be offline." = "Internet bağlantınız çevrimdışı görünüyor.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/uk.lproj/Localizable.strings
================================================
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Thank you for helping make Clocker even better!";
"iRateMessageTitle" = "Оціни %@";
"iRateAppMessage" = "If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateGameMessage" = "If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!";
"iRateCancelButton" = "Ні, дякую";
"iRateRateButton" = "Оцінити зараз";
"iRateRemindButton" = "Нагадати пізніше";
"iRateUpdateMessage" = "Оновити зараз?";
"ClockerVersion" = "Версія %@";
"CLFeedbackAlertTitle" = "Дякуємо, що допомагаєте зробити Clocker ще кращим!";
"app-name" = "Clocker";
"start-at-login" = "Запускати при вході";
"setup-steps" = "Налаштування Clocker займе лише 3 кроки";
"Permissions-Header" = "Дозволи";
"See your next Calendar event here." = "Побачте вашу наступну подію Календаря тут.";
"Click here to start." = "Натисніть тут, щоб почати.";
"Reminders Access" = "Доступ до Нагадувань";
"Calendar Access" = "Доступ до Календаря";
"Permissions" = "Дозволи";
"Calendar Detail" = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Reminders Detail" = "Встановіть нагадування в часовому поясі вибраного вами місця. Ваші нагадування зберігаються в програмі Нагадування за умовчанням.";
"Privacy Text" = "You can change this later in the Privacy section of the System Preferences.";
"Granted Button Text" = "Надано";
"Denied Button Text" = "Відмовлено";
"Grant Button Text" = "Надати";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Налаштування Clocker займе лише 3 кроки.";
"Get Started" = "Почати роботу";
// Tab Item Titles
"Preferences Tab" = "Налаштування";
"Appearance Tab" = "Вигляд";
"Calendar Tab" = "Календар";
"About Tab" = "Про програму";
"Permissions Tab" = "Дозволи";
// General Preferences Screen
"Start at Login" = "Запускати Clocker при вході";
"Sort by Time Difference" = "Сортувати за Різницею у часі";
"Sort by Name" = "Сортувати за Назвою";
"Sort by Label" = "Сортувати за Позначенням";
"Search Field Placeholder" = "Введіть місто, область або назву країни";
"No Timezone Selected" = "Будь ласка, оберіть часовий пояс!";
"Max Timezones Selected" = "Максимально доступно 100 часових поясів!";
"Max Search Characters" = "Only 50 characters allowed!";
"Add Button Title" = "Додати";
"Close Button Title" = "Закрити";
// Onboarding
"Open Clocker At Login" = "Відкривати Clocker при вході";
"Launch Clocker" = "Запустити Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Налаштування Clocker займе лише 3 кроки.";
"Get Started" = "Почати роботу";
// Permissions
"Calendar Access Title" = "Доступ до Календаря";
"Reminders Access Title" = "Доступ до Нагадувань";
"Later Config Description" = "Це можна налаштувати пізніше в Системних параметрах.";
"Back" = "Назад";
"Continue" = "Continue";
"Clocker is more useful when it can display events from your calendars." = "Clocker більш корисний, коли може відображати події з ваших календарів.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker більш корисний, коли може відображати події з ваших календарів. Ви можете змінити цей параметр у Системні параметри › Безпека та приватність › Приватність.";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "Відкрити Системні параметри";
"Grant Access" = "Надати доступ";
"Upcoming events from your calendars can be shown in the menubar + panel." = "Upcoming events from your calendars can be shown in the menubar + panel.";
"Granted" = "Надано";
"Denied" = "Відмовлено";
"Grant" = "Надати";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "Quick Add Locations";
"More search options in Clocker Preferences." = "Більше варіантів пошуку в налаштуваннях Clocker.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Запускати при вході";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Формат часу";
"Day Display Options" = "Варіанти відображання дня";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Display the time in seconds" = "Відображати час у секундах";
"Larger Text" = "Більший текст";
"Future Slider Range" = "Future Slider Range";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
/* Appears in Preferences -> Appearance which allows the user to switch between the compact and standard menubar mode. It doesn't lead anywhere. */
"Menubar Mode" = "Menubar Mode";
"Preview" = "Preview";
"Miscellaneous" = "Miscellaneous";
// Empty View
"No places added" = "No places added";
// Panel
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Розкажіть нам, що ви думаєте!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Варіанти перегляду майбутньої події";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Next Meeting Title in Menubar" = "Show Next Meeting Title in Menubar";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "Try again, maybe?";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
================================================
FILE: Clocker/Clocker/zh-Hans.lproj/InfoPlist.strings
================================================
/* InfoPlist.strings
Clocker
Created by Abhishek Banthia on 3/27/16. */
"CFBundleDisplayName" = "Clocker";
/* (No Comment) */
"CFBundleName" = "Clocker";
/* Privacy - Calendars Usage Description */
"NSCalendarsUsageDescription" = "Clocker在展示你即将到来的日程时非常有用。你可以在 系统设置› 安全和隐私› 隐私 中更改设置。";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "版权所有© 2016, Abhishek Banthia";
/* Privacy - Location Always and When In Use Usage Description */
"NSLocationAlwaysAndWhenInUseUsageDescription" = "Clocker can be more useful when it can use your location to determine your current timezone.";
/* Privacy - Location Usage Description */
"NSLocationUsageDescription" = "Clocker can be more useful when it can use your location to determine your current timezone.";
/* Privacy - Reminders Usage Description */
"NSRemindersUsageDescription" = "Clocker can be more useful when it can set reminders for your selected timezone(s). You can change this setting in System Preferences › Security & Privacy › Privacy.";
================================================
FILE: Clocker/Clocker/zh-Hans.lproj/Localizable.strings
================================================
/* (No Comment) */
"CFBundleDisplayName" = "解锁器";
"Thank you for helping make Clocker even better!" = "感谢您帮助 Clocker 做得更好!";
"iRateMessageTitle" = "评价 %@";
"iRateAppMessage" = "如果您喜欢使用 %@,能否请您抽出时间来对它进行评价?评价不会超过一分钟。感谢您的支持 !";
"iRateGameMessage" = "如果您喜欢使用 %@,能否请您抽出时间来对它进行评价?评价不会超过一分钟。感谢您的支持 !";
"iRateCancelButton" = "不用了,谢谢";
"iRateRateButton" = "立即评分";
"iRateRemindButton" = "稍后提醒我";
"iRateUpdateMessage" = "现在更新?";
"ClockerVersion" = "版本 %@";
"CLFeedbackAlertTitle" = "感谢您帮助 Clocker 做得更好!";
"app-name" = "Clocker";
"start-at-login" = "开启时启动";
"setup-steps" = "只需要三步来设置 Clocker";
"Permissions-Header" = "权限";
"See your next Calendar event here." = "在这里查看你的下一个日历事件。";
"Click here to start." = "点此开始。";
"Reminders Access" = "提醒访问权限";
"Calendar Access" = "日历访问权限";
"Permissions" = "权限";
"Calendar Detail" = "未来你个人和分享的日历事件将显示在菜单栏和面板上。";
"Reminders Detail" = "在您选择的位置时区设置提醒。您的提醒存储在默认提醒应用中。";
"Privacy Text" = "您稍后可以在「系统偏好设置」的隐私部分更改此内容。";
"Granted Button Text" = "已授权";
"Denied Button Text" = "已拒绝";
"Grant Button Text" = "授权";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "只需要 3 步来设置 Clocker。";
"Get Started" = "开始";
// Tab Item Titles
"Preferences Tab" = "首选项";
"Appearance Tab" = "外观";
"Calendar Tab" = "日历";
"About Tab" = "关于";
"Permissions Tab" = "权限";
// General Preferences Screen
"Start at Login" = "登录时启动 Clocker";
"Sort by Time Difference" = "按时间差排序";
"Sort by Name" = "按名称排序";
"Sort by Label" = "按标签排序";
"Search Field Placeholder" = "输入城市、省/州或国家名称";
"No Timezone Selected" = "请选择一个时区!";
"Max Timezones Selected" = "最多允许 100 个时区!";
"Max Search Characters" = "最多允许 50 个字符!";
"Add Button Title" = "添加";
"Close Button Title" = "关闭";
// Onboarding
"Open Clocker At Login" = "登录时启动 Clocker";
"Launch Clocker" = "启动 Clocker";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "只需要三步来设置 Clocker。";
"Get Started" = "现在开始";
// Permissions
"Calendar Access Title" = "访问日历";
"Reminders Access Title" = "访问提醒";
"Later Config Description" = "这些可以稍后在系统偏好设置中配置。";
"Back" = "返回";
"Continue" = "继续";
"Clocker is more useful when it can display events from your calendars." = "Clocker 能显示日历中的事件时会更有用。";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker 在能显示日历中的事件时更有用。你可以在「系统偏好设置 > 安全性与隐私 > 隐私」中更改设置。";
"Launch Preferences" = "打开首选项";
"Grant Access" = "授予访问权限";
"Upcoming events from your calendars can be shown in the menubar + panel." = "你个人和共享日历的未来事件将显示在菜单栏和面板上。";
"Granted" = "已授权";
"Denied" = "已拒绝";
"Grant" = "授权";
"Unexpected" = "意外的";
// Onboarding Search
"Quick Add Locations" = "快速添加地点";
"More search options in Clocker Preferences." = "Clocker 首选项中的更多搜索选项。";
"Enter 3 or more characters for locations you'll like to add" = "为您想要添加的位置输入 3 个或更多字符";
// Start at Login
"Launch at Login" = "登录时启动";
"This can be configured later in Clocker Preferences." = "这可以稍后在 Clocker 首选项中进行配置。";
"Should Clocker open automatically on startup?" = "是否在启动时自动打开 Clocker?";
// Final Onboarding Screen
"You're all set!" = "已完成全部设置!";
"Thank you for the details." = "感谢您的详细信息。";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "当你启动应用时,会在菜单栏看到一个时钟图标。如果想在 Dock 上显示图标,请在首选项设置。";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "如果您想帮助翻译本应用或收到不定时的应用更新,请输入您的电子邮箱!";
// Appearance Tab
"Panel Theme" = "面板主题";
"Favourite a timezone to enable menubar display options." = "收藏一个时区以在菜单栏上显示可选项。";
"Main Panel Options" = "主面板选项";
"Time Format" = "时间格式";
"Day Display Options" = "日显示选项";
"Show Future Slider" = "显示未来滑块";
"Show Sunrise/Sunset" = "显示日出/日落";
"Display the time in seconds" = "显示秒数";
"Larger Text" = "更大字号";
"Future Slider Range" = "未来滑块范围";
"Include Date" = "包含日期";
"Include Day" = "包含日";
"Include Place Name" = "包含地名";
"Menubar Display Options" = "菜单栏显示选项";
"Menubar Mode" = "菜单栏模式";
"Preview" = "预览";
"Miscellaneous" = "杂项设置";
// Empty View
"No places added" = "没有添加地点";
// Panel
"No upcoming event." = "暂无事项";
"You have no events scheduled for tomorrow." = "您明天没有安排。";
// Review
"Enjoy using Clocker?" = "喜欢使用 Clocker 吗?";
// App Feedback
"Tell us what you think!" = "告诉我们您的想法!";
"Contact Information (Optional)" = "联系信息 (可选)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "联系人字段是可选项!我们需要更多信息或帮助时,将使用联络信息联络您!";
// About View Screen
"Feedback is always welcome:" = "欢迎提供反馈:";
// Calendars View
"Upcoming Event View Options" = "即将到来的事件视图选项";
"Show Upcoming Event View" = "显示即将到来的事件视图";
"Show All Day Meetings" = "显示全天会议";
"Show Next Meeting Title in Menubar" = "在菜单栏中显示下一个会议标题";
"Truncate menubar text longer than" = "截断菜单栏文字长度大于";
"characters" = "字符";
"Show events from" = "显示事件来源";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "如果会议标题是“Meeting with Neel”,并且截断长度设置为 5 ,菜单栏的文本将显示为“Meeti...”";
// Notes Popover
"Reminder Set" = "提醒设置";
"Successfully set." = "设置成功";
// Errors
"You're offline, maybe?" = "您已经离线?";
"Try again, maybe?" = "稍后再试?";
"The Internet connection appears to be offline." = "网络连接已断开。";
// UI Tests
"New Zealand" = "新西兰";
"Florida" = "佛罗里达";
"San Francisco" = "旧金山";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today 🎉";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker/zh-Hant.lproj/Localizable.strings
================================================
"About Tab" = "關於";
"Add Button Title" = "新增";
"Appearance Tab" = "外觀";
"Back" = "返回";
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
"CFBundleDisplayName" = "Clocker";
"CLFeedbackAlertTitle" = "感謝您的幫助,讓 Clocker 變得更好!";
"Calendar Access" = "取用您的行事曆";
/* Permissions */
"Calendar Access Title" = "取用您的行事曆";
"Calendar Detail" = "即將到來的行程會在選單列和面板中顯示。";
"Calendar Tab" = "行事曆";
"Click here to start." = "開始";
"Clocker is more useful when it can display events from your calendars." = "從您的行事曆顯示行程將使 Clocker 更實用。";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "從您的行事曆顯示行程將使 Clocker 更實用。您可以在「系統偏好設定」>「安全性與隱私」>「隱私權」更改此設定。";
"ClockerVersion" = "版本:%@";
"Close Button Title" = "關閉";
"Contact Information (Optional)" = "聯絡資訊(可留空)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "聯絡欄為可選填欄位!我們需要更多資訊或協助時,將會透過聯絡資訊聯絡您!";
"Continue" = "繼續";
"Copied to Clipboard" = "Copied to Clipboard";
"Day Display Options" = "日期顯示選項";
/* DST changes */
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Denied" = "拒絕";
"Denied Button Text" = "拒絕";
"Display the time in seconds" = "顯示時間秒數";
/* Review */
"Enjoy using Clocker?" = "喜歡使用 Clocker 嗎?";
"Enter 3 or more characters for locations you'll like to add" = "為您想加入的位置輸入 3 個或更多字元";
"Favourite a timezone to enable menubar display options." = "將一時區設為喜好項目以啟用選單列顯示選項。";
/* About View Screen */
"Feedback is always welcome:" = "Feedback is always welcome:";
"Florida" = "佛羅里達";
"Future Slider Range" = "未來滑桿範圍";
"Get Started" = "開始使用";
"Get Started" = "開始使用";
"Grant" = "允許";
"Grant Access" = "允許存取";
"Grant Button Text" = "允許";
"Granted" = "允許";
"Granted Button Text" = "允許";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "如果會議標題為「Meeting with Neel」、文字長度限制為 5,選單列中的文字將顯示為「Meeti...」。";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
"Include Date" = "包含日期";
"Include Day" = "包含星期";
"Include Place Name" = "包含位置名稱";
/* Welcome Onboarding */
"It only takes 3 steps to set up Clocker." = "設定 Clocker 只需要 3 個步驟。";
/* Welcome Onboarding */
"It only takes 3 steps to setup Clocker." = "設定 Clocker 只需要 3 個步驟。";
"Larger Text" = "文字大小";
"Later Config Description" = "這些可以稍後在「系統偏好設定」中進行設置。";
"Launch Clocker" = "啟動 Clocker";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "啟動偏好設定";
/* Start at Login */
"Launch at Login" = "登入時啟動";
"Main Panel Options" = "主要面板選項";
"Max Search Characters" = "只允許 50 個字元!";
"Max Timezones Selected" = "最多允許 100 個時區!";
"Menubar Display Options" = "選單列顯示選項";
"Menubar Mode" = "選單列模式";
"Miscellaneous" = "其他設定";
"More search options in Clocker Preferences." = "在 Clocker 偏好設定中更多的搜尋選項。";
/* UI Tests */
"New Zealand" = "紐西蘭";
"No Timezone Selected" = "請選取一個時區!";
/* Empty View */
"No places added" = "未加入地點";
/* Panel */
"No upcoming event." = "沒有即將到來的行程";
"No upcoming events for today!" = "No upcoming events for today 🎉";
/* Onboarding */
"Open Clocker At Login" = "在登入時打開 Clocker";
/* Appearance Tab */
"Panel Theme" = "面板主題";
"Permissions" = "權限";
"Permissions Tab" = "權限";
"Permissions-Header" = "權限";
/* Tab Item Titles */
"Preferences Tab" = "偏好設定";
"Preview" = "預覽";
"Privacy Text" = "您稍後可以在「系統偏好設定」>「安全性與隱私權」中更改。";
/* Onboarding Search */
"Quick Add Locations" = "快速加入位置";
/* Notes Popover */
"Reminder Set" = "Reminder Set";
"Reminders Access" = "取用提醒事項";
"Reminders Access Title" = "取用提醒事項";
"Reminders Detail" = "根據你選擇的位置設定提醒。您的提醒將儲存在預設的提醒事項應用程式。";
"San Francisco" = "舊金山";
"Search Field Placeholder" = "輸入一個地點的名稱";
"See your next Calendar event here." = "在此查看你的下一個日曆活動。";
"Should Clocker open automatically on startup?" = "啟動時自動打開 Clocker?";
"Show All Day Meetings" = "顯示整日的行程";
"Show Future Slider" = "顯示未來滑桿";
"Show Next Meeting Title in Menubar" = "在選單列中顯示下個行程";
"Show Sunrise/Sunset" = "顯示日出/日落";
"Show Upcoming Event View" = "顯示即將到來的行程";
"Show events from" = "Show events from";
"Sort by Label" = "按標籤排序";
"Sort by Name" = "按名稱排序";
"Sort by Time Difference" = "按時差排序";
/* General Preferences Screen */
"Start at Login" = "登入時打開 Clocker";
"Successfully set." = "設定成功。";
/* App Feedback */
"Tell us what you think!" = "告訴我們您的想法!";
"Thank you for helping make Clocker even better!" = "感謝您的幫助,讓 Clocker 變得更好!";
"Thank you for the details." = "Thank you for the details.";
"The Internet connection appears to be offline." = "Internet連線已斷開。";
"This can be configured later in Clocker Preferences." = "這可以稍後在 Clocker 偏好設定中進行設置。";
"Time Format" = "時間格式";
"Truncate menubar text longer than" = "選單列文字長度限制";
"Try again, maybe?" = "再試一次?";
"Unexpected" = "無法預期的";
/* Calendars View */
"Upcoming Event View Options" = "即將到來的行程顯示選項";
"Upcoming events from your calendars can be shown in the menubar + panel." = "即將到來的行程會在選單列和面板中顯示。";
"You have no events scheduled for tomorrow." = "您明天沒有排任何行程。";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "當應用程式啟動時,您將會在選單列看到 Clocker 圖像。如果您想在 Dock 上看到圖像,請前往偏好設定。";
/* Final Onboarding Screen */
"You're all set!" = "設定完成。";
/* Errors */
"You're offline, maybe?" = "You're offline, maybe?";
"app-name" = "Clocker";
"characters" = "字元";
"iRateAppMessage" = "如果您喜歡使用 %@ 的話,您是否願意花一點給予評價?不需要一分鐘就能完成。感謝您的支持!";
"iRateCancelButton" = "不用了,謝謝!";
"iRateGameMessage" = "如果您喜歡玩 %@ 的話,您是否願意花一點時間給予評價?不需一分鐘即可完成。感謝您的支持";
"iRateMessageTitle" = "評價 %@";
"iRateRateButton" = "現在評分吧!";
"iRateRemindButton" = "下次再提醒我";
"iRateUpdateMessage" = "立即更新";
"setup-steps" = "設定 Clocker 只需要 3 個步驟";
"start-at-login" = "在登入時啟動";
// iCloud
"Enable iCloud Sync" = "Enable iCloud Sync";
================================================
FILE: Clocker/Clocker-Bridging-Header.h
================================================
//
// Clocker-Bridging-Header.h
// Clocker
//
// Created by Banthia, Abhishek on 12/22/17.
//
#import "iVersion.h"
#import
#import
#import
================================================
FILE: Clocker/Clocker.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
3508CC942599FFEC000E3530 /* MenubarTitleProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3508CC932599FFEC000E3530 /* MenubarTitleProvider.swift */; };
3508CC9A259A0001000E3530 /* StatusItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3508CC99259A0001000E3530 /* StatusItemView.swift */; };
3508CC9F259A000E000E3530 /* StatusItemHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3508CC9E259A000E000E3530 /* StatusItemHandler.swift */; };
3508CCAA259A0027000E3530 /* StatusContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3508CCA9259A0027000E3530 /* StatusContainerView.swift */; };
3531F7C226936C6E00DF0111 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */; };
3531F7C326936C8300DF0111 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */; };
3531F7C426936C8300DF0111 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */; };
3531F7C526936C8400DF0111 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */; };
3531F80626938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; };
3531F80726938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; };
3531F80826938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; };
3531F80926938D7700DF0111 /* FirebaseCoreDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FD26938D7700DF0111 /* FirebaseCoreDiagnostics.framework */; };
3531F80A26938D7700DF0111 /* FirebaseCoreDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FD26938D7700DF0111 /* FirebaseCoreDiagnostics.framework */; };
3531F80B26938D7700DF0111 /* FirebaseCoreDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FD26938D7700DF0111 /* FirebaseCoreDiagnostics.framework */; };
3531F80C26938D7700DF0111 /* FirebaseDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FE26938D7700DF0111 /* FirebaseDatabase.framework */; };
3531F80D26938D7700DF0111 /* FirebaseDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FE26938D7700DF0111 /* FirebaseDatabase.framework */; };
3531F80E26938D7700DF0111 /* FirebaseDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FE26938D7700DF0111 /* FirebaseDatabase.framework */; };
3531F80F26938D7700DF0111 /* PromisesObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FF26938D7700DF0111 /* PromisesObjC.framework */; };
3531F81026938D7700DF0111 /* PromisesObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FF26938D7700DF0111 /* PromisesObjC.framework */; };
3531F81126938D7700DF0111 /* PromisesObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FF26938D7700DF0111 /* PromisesObjC.framework */; };
3531F81226938D7700DF0111 /* FirebaseCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80026938D7700DF0111 /* FirebaseCore.framework */; };
3531F81326938D7700DF0111 /* FirebaseCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80026938D7700DF0111 /* FirebaseCore.framework */; };
3531F81426938D7700DF0111 /* FirebaseCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80026938D7700DF0111 /* FirebaseCore.framework */; };
3531F81526938D7700DF0111 /* nanopb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80126938D7700DF0111 /* nanopb.framework */; };
3531F81626938D7700DF0111 /* nanopb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80126938D7700DF0111 /* nanopb.framework */; };
3531F81726938D7700DF0111 /* nanopb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80126938D7700DF0111 /* nanopb.framework */; };
3531F81826938D7700DF0111 /* FirebaseCrashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80226938D7700DF0111 /* FirebaseCrashlytics.framework */; };
3531F81926938D7700DF0111 /* FirebaseCrashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80226938D7700DF0111 /* FirebaseCrashlytics.framework */; };
3531F81A26938D7700DF0111 /* FirebaseCrashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80226938D7700DF0111 /* FirebaseCrashlytics.framework */; };
3531F81B26938D7700DF0111 /* FirebaseInstallations.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80326938D7700DF0111 /* FirebaseInstallations.framework */; };
3531F81C26938D7700DF0111 /* FirebaseInstallations.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80326938D7700DF0111 /* FirebaseInstallations.framework */; };
3531F81D26938D7700DF0111 /* FirebaseInstallations.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80326938D7700DF0111 /* FirebaseInstallations.framework */; };
3531F81E26938D7700DF0111 /* leveldb-library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80426938D7700DF0111 /* leveldb-library.framework */; };
3531F81F26938D7700DF0111 /* leveldb-library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80426938D7700DF0111 /* leveldb-library.framework */; };
3531F82026938D7700DF0111 /* leveldb-library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80426938D7700DF0111 /* leveldb-library.framework */; };
3531F82126938D7700DF0111 /* GoogleDataTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80526938D7700DF0111 /* GoogleDataTransport.framework */; };
3531F82226938D7700DF0111 /* GoogleDataTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80526938D7700DF0111 /* GoogleDataTransport.framework */; };
3531F82326938D7700DF0111 /* GoogleDataTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F80526938D7700DF0111 /* GoogleDataTransport.framework */; };
353B5BC52698B78A0023858D /* UpcomingEventStatusItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353B5BC42698B78A0023858D /* UpcomingEventStatusItemView.swift */; };
3548C45A26BECF1B00AFB533 /* UpcomingEventViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3548C45926BECF1B00AFB533 /* UpcomingEventViewItem.xib */; };
3548C45D26BEEF4C00AFB533 /* ParentPanelController+UpcomingEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3548C45C26BEEF4C00AFB533 /* ParentPanelController+UpcomingEvents.swift */; };
3548C45F26BEEFB400AFB533 /* UpcomingEventsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3548C45E26BEEFB400AFB533 /* UpcomingEventsDataSource.swift */; };
3548C46126BEEFE400AFB533 /* UpcomingEventViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3548C46026BEEFE400AFB533 /* UpcomingEventViewItem.swift */; };
35584D1427EF8EB5006E3EAD /* ThemerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35584D1327EF8EB5006E3EAD /* ThemerTests.swift */; };
35584D1827F0B019006E3EAD /* DateFormatterManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35584D1727F0B019006E3EAD /* DateFormatterManagerTests.swift */; };
35584D1A27F0B64E006E3EAD /* AppDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35584D1927F0B64E006E3EAD /* AppDelegateTests.swift */; };
35621CFC27F66C1900926D5C /* SearchDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35621CFB27F66C1900926D5C /* SearchDataSourceTests.swift */; };
357391872507277500D30819 /* TimeMarkerViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357391852507277500D30819 /* TimeMarkerViewItem.swift */; };
357391882507277500D30819 /* HourMarkerViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = 357391862507277500D30819 /* HourMarkerViewItem.xib */; };
3579765E2680208C009DDA6E /* ParentPanelController+ModernSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3579765D2680208C009DDA6E /* ParentPanelController+ModernSlider.swift */; };
3595FAD0227F88BC0044A12A /* UserDefaults + KVOExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3595FACF227F88BC0044A12A /* UserDefaults + KVOExtensions.swift */; };
35B2FEC0259A186F005DA84D /* StartupKit in Frameworks */ = {isa = PBXBuildFile; productRef = 35B2FEBF259A186F005DA84D /* StartupKit */; };
35B2FEDD259A2291005DA84D /* CoreLoggerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 35B2FEDC259A2291005DA84D /* CoreLoggerKit */; };
35B2FEF1259A2DB1005DA84D /* CoreModelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 35B2FEF0259A2DB1005DA84D /* CoreModelKit */; };
35BD9A572807580800077443 /* EventInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35BD9A562807580800077443 /* EventInfoTests.swift */; };
35C36EF122595F14002FA5C6 /* OnboardingPermissionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EE822595F13002FA5C6 /* OnboardingPermissionsViewController.swift */; };
35C36EF222595F14002FA5C6 /* OnboardingWelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EE922595F13002FA5C6 /* OnboardingWelcomeViewController.swift */; };
35C36EF322595F14002FA5C6 /* WelcomeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 35C36EEA22595F13002FA5C6 /* WelcomeView.xib */; };
35C36EF422595F14002FA5C6 /* StartAtLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EEB22595F13002FA5C6 /* StartAtLoginViewController.swift */; };
35C36EF522595F14002FA5C6 /* OnboardingSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EEC22595F13002FA5C6 /* OnboardingSearchController.swift */; };
35C36EF622595F14002FA5C6 /* OnboardingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EED22595F13002FA5C6 /* OnboardingController.swift */; };
35C36EF722595F14002FA5C6 /* FinalOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EEE22595F13002FA5C6 /* FinalOnboardingViewController.swift */; };
35C36EF822595F14002FA5C6 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 35C36EEF22595F14002FA5C6 /* Onboarding.storyboard */; };
35C36EF922595F14002FA5C6 /* OnboardingParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EF022595F14002FA5C6 /* OnboardingParentViewController.swift */; };
35C36EFB2259616B002FA5C6 /* Solar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFA2259616B002FA5C6 /* Solar.swift */; };
35C36F0E225961DA002FA5C6 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFE225961D9002FA5C6 /* Date+Bundle.swift */; };
35C36F10225961DA002FA5C6 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F00225961D9002FA5C6 /* Constants.swift */; };
35C36F12225961DA002FA5C6 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F02225961DA002FA5C6 /* Date+Components.swift */; };
35C36F13225961DA002FA5C6 /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F03225961DA002FA5C6 /* Date+TimeAgo.swift */; };
35C36F14225961DA002FA5C6 /* Integer+DateTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F04225961DA002FA5C6 /* Integer+DateTools.swift */; };
35C36F15225961DA002FA5C6 /* TimeChunk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F05225961DA002FA5C6 /* TimeChunk.swift */; };
35C36F16225961DA002FA5C6 /* Date+Inits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F06225961DA002FA5C6 /* Date+Inits.swift */; };
35C36F17225961DA002FA5C6 /* DateTools.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 35C36F07225961DA002FA5C6 /* DateTools.bundle */; };
35C36F18225961DA002FA5C6 /* Date+Comparators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F08225961DA002FA5C6 /* Date+Comparators.swift */; };
35C36F19225961DA002FA5C6 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F09225961DA002FA5C6 /* Enums.swift */; };
35C36F1A225961DA002FA5C6 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F0A225961DA002FA5C6 /* Date+Manipulations.swift */; };
35C36F1B225961DA002FA5C6 /* Date+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F0B225961DA002FA5C6 /* Date+Format.swift */; };
35C36F2022596253002FA5C6 /* OneWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F1E22596253002FA5C6 /* OneWindowController.swift */; };
35C36F2122596253002FA5C6 /* AppearanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F1F22596253002FA5C6 /* AppearanceViewController.swift */; };
35C36F2B2259D6FA002FA5C6 /* ParentPanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F272259D6FA002FA5C6 /* ParentPanelController.swift */; };
35C36F2C2259D6FA002FA5C6 /* PanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F282259D6FA002FA5C6 /* PanelController.swift */; };
35C36F372259D7C3002FA5C6 /* AddTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F322259D7C3002FA5C6 /* AddTableViewCell.swift */; };
35C36F412259D892002FA5C6 /* Themer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F392259D892002FA5C6 /* Themer.swift */; };
35C36F422259D892002FA5C6 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F3A2259D892002FA5C6 /* Timer.swift */; };
35C36F452259D892002FA5C6 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F3D2259D892002FA5C6 /* Strings.swift */; };
35C36F462259D892002FA5C6 /* DataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F3E2259D892002FA5C6 /* DataStore.swift */; };
35C36F472259D892002FA5C6 /* Reach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F3F2259D892002FA5C6 /* Reach.swift */; };
35C36F482259D892002FA5C6 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F402259D892002FA5C6 /* NetworkManager.swift */; };
35C36F4B2259D971002FA5C6 /* PointingHandCursorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F4A2259D971002FA5C6 /* PointingHandCursorButton.swift */; };
35C36F4E2259D981002FA5C6 /* DateFormatterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F4C2259D981002FA5C6 /* DateFormatterManager.swift */; };
35C36F4F2259D981002FA5C6 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F4D2259D981002FA5C6 /* AppDefaults.swift */; };
35C36F572259DD8A002FA5C6 /* TimezoneDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F532259DD8A002FA5C6 /* TimezoneDataSource.swift */; };
35C36F582259DD8A002FA5C6 /* PanelTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F542259DD8A002FA5C6 /* PanelTableView.swift */; };
35C36F592259DD8A002FA5C6 /* TimezoneCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F552259DD8A002FA5C6 /* TimezoneCellView.swift */; };
35C36F5A2259DD8A002FA5C6 /* Panelr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F562259DD8A002FA5C6 /* Panelr.swift */; };
35C36F5D2259DD96002FA5C6 /* TimezoneDataOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F5B2259DD96002FA5C6 /* TimezoneDataOperations.swift */; };
35C36F612259DE67002FA5C6 /* NotesPopover.xib in Resources */ = {isa = PBXBuildFile; fileRef = 35C36F5F2259DE67002FA5C6 /* NotesPopover.xib */; };
35C36F622259DE67002FA5C6 /* NotesPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F602259DE67002FA5C6 /* NotesPopover.swift */; };
35C36F662259DF4C002FA5C6 /* UpcomingEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F642259DF4C002FA5C6 /* UpcomingEventView.swift */; };
35C36F672259DF4C002FA5C6 /* ReviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F652259DF4C002FA5C6 /* ReviewController.swift */; };
35C36F692259DF55002FA5C6 /* TextViewWithPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F682259DF55002FA5C6 /* TextViewWithPlaceholder.swift */; };
35C36F6B2259E0E1002FA5C6 /* FloatingWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 35C36F6A2259E0E1002FA5C6 /* FloatingWindow.xib */; };
35C36F6F2259E185002FA5C6 /* CustomSliderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F6C2259E185002FA5C6 /* CustomSliderCell.swift */; };
35C36F702259E185002FA5C6 /* BackgroundPanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F6D2259E185002FA5C6 /* BackgroundPanelView.swift */; };
35C36F712259E185002FA5C6 /* NoTimezoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F6E2259E185002FA5C6 /* NoTimezoneView.swift */; };
35C36F732259E1AA002FA5C6 /* FloatingWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F722259E1AA002FA5C6 /* FloatingWindowController.swift */; };
35C36F772259E1D0002FA5C6 /* AppKit + Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F742259E1CF002FA5C6 /* AppKit + Additions.swift */; };
35C36F782259E1D0002FA5C6 /* Foundation + Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F752259E1CF002FA5C6 /* Foundation + Additions.swift */; };
35C36F792259E1D0002FA5C6 /* String + Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F762259E1CF002FA5C6 /* String + Additions.swift */; };
35C36F912259EAF4002FA5C6 /* Preferences.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 35C36F902259EAF4002FA5C6 /* Preferences.storyboard */; };
35C36F972259EBB1002FA5C6 /* AppFeedbackWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 35C36F952259EBB1002FA5C6 /* AppFeedbackWindow.xib */; };
35C36F982259EBB1002FA5C6 /* AppFeedbackWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F962259EBB1002FA5C6 /* AppFeedbackWindowController.swift */; };
35C36FA02259ED6D002FA5C6 /* CalendarHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F9D2259ED6D002FA5C6 /* CalendarHandler.swift */; };
35C36FA12259ED6D002FA5C6 /* EventCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F9E2259ED6D002FA5C6 /* EventCenter.swift */; };
35C36FA22259ED6D002FA5C6 /* RemindersHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F9F2259ED6D002FA5C6 /* RemindersHandler.swift */; };
35C36FA42259EEC2002FA5C6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36FA32259EEC2002FA5C6 /* AppDelegate.swift */; };
35D23E3727F27E2E00C6DD55 /* ReviewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35D23E3627F27E2E00C6DD55 /* ReviewControllerTests.swift */; };
35DFBCEF26A8468900D6648B /* ConfigExport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35DFBCEE26A8468900D6648B /* ConfigExport.swift */; };
35E65125268EDD2E00E3E1E3 /* Toasty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35E65124268EDD2E00E3E1E3 /* Toasty.swift */; };
9A0385BB269E3434003B5E72 /* StandardMenubarHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0385BA269E3434003B5E72 /* StandardMenubarHandlerTests.swift */; };
9A0385C0269E8891003B5E72 /* PermissionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0385BF269E8891003B5E72 /* PermissionsTests.swift */; };
9A0A1C8C20903DBD0012003B /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87651C1FEDC500A7A2DF /* CoreLocation.framework */; };
9A13BAD61CA87F08007C6CBE /* Panel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAD81CA87F08007C6CBE /* Panel.xib */; };
9A13BAE01CA882FA007C6CBE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAE21CA882FA007C6CBE /* InfoPlist.strings */; };
9A13BAEA1CA88A76007C6CBE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAEC1CA88A76007C6CBE /* Localizable.strings */; };
9A20A04B1C4DEED200FB45AB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A20A04A1C4DEED200FB45AB /* IOKit.framework */; };
9A24A1881ED902CC0095201E /* EventKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A24A1871ED902CC0095201E /* EventKit.framework */; };
9A3169C11D2CC5AA0079FDF8 /* com.abhishek.ClockerHelper.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A3169C01D2CC5AA0079FDF8 /* com.abhishek.ClockerHelper.plist */; };
9A43792A1BEC230A00F4E27F /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A4379291BEC230A00F4E27F /* libc++.tbd */; };
9A56DB801C1CFB73004CE6AF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A56DB7D1C1CFB73004CE6AF /* MainMenu.xib */; };
9A5E75E4204CC39700119939 /* ShortcutRecorder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A86E2BC1CE04F1600547EE7 /* ShortcutRecorder.framework */; };
9A5E75E5204CC39700119939 /* ShortcutRecorder.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9A86E2BC1CE04F1600547EE7 /* ShortcutRecorder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9A5E75E8204CC39700119939 /* PTHotKey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A86E2BE1CE04F1600547EE7 /* PTHotKey.framework */; };
9A5E75E9204CC39700119939 /* PTHotKey.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9A86E2BE1CE04F1600547EE7 /* PTHotKey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9A6D93371CF3E82F005A8690 /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A6D93361CF3E82F005A8690 /* CoreImage.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9A7547C91F183729004705EF /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A20A06F1C4E804D00FB45AB /* ServiceManagement.framework */; };
9A7547D41F184DC3004705EF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A7547D31F184DC3004705EF /* AppDelegate.m */; };
9A7547D71F184DC3004705EF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A7547D61F184DC3004705EF /* main.m */; };
9A7547DC1F184DC3004705EF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A7547DB1F184DC3004705EF /* Assets.xcassets */; };
9A7547DF1F184DC3004705EF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A7547DD1F184DC3004705EF /* Main.storyboard */; };
9A7547E51F184E3F004705EF /* ClockerHelper.app in Login Item Helper */ = {isa = PBXBuildFile; fileRef = 9A7547D01F184DC3004705EF /* ClockerHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
9A8605AE1BEC148400A810A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A8605AD1BEC148400A810A4 /* main.m */; };
9A8B256A232EFAD300204CAD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAEC1CA88A76007C6CBE /* Localizable.strings */; };
9A97419B2455442100087B0D /* OnboardingSearchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A97419A2455442100087B0D /* OnboardingSearchTests.swift */; };
9A9E87621C1FEDB500A7A2DF /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87611C1FEDB500A7A2DF /* CFNetwork.framework */; };
9A9E876A1C1FEDDB00A7A2DF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87691C1FEDDB00A7A2DF /* SystemConfiguration.framework */; };
9AA522C023415BDD00C9E005 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9AA522BE23415BDD00C9E005 /* InfoPlist.strings */; };
9AA522C323415BDD00C9E005 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9AA522C123415BDD00C9E005 /* InfoPlist.strings */; };
9AB6F1562259CF3900A44663 /* CalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F1552259CF3900A44663 /* CalendarViewController.swift */; };
9AB6F1582259CFFC00A44663 /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F1572259CFFC00A44663 /* AboutViewController.swift */; };
9AB6F15D2259D08300A44663 /* iVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F15A2259D08300A44663 /* iVersion.m */; };
9AB6F15E2259D08300A44663 /* iVersion.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9AB6F15C2259D08300A44663 /* iVersion.bundle */; };
9AB6F1612259D1B000A44663 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F15F2259D1B000A44663 /* PreferencesViewController.swift */; };
9AB6F1622259D1B000A44663 /* PreferencesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F1602259D1B000A44663 /* PreferencesDataSource.swift */; };
9AB6F1642259D1B900A44663 /* ParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F1632259D1B800A44663 /* ParentViewController.swift */; };
9AB6F1672259D23200A44663 /* PermissionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6F1662259D23200A44663 /* PermissionsViewController.swift */; };
9AB89E031CE97A4900EC8EB1 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9AB89E021CE97A4900EC8EB1 /* Media.xcassets */; };
9ABF455B268FDABA002C779B /* CopyToClipboardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ABF4559268FDABA002C779B /* CopyToClipboardTests.swift */; };
9ABFB3801CA6882000E10745 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ABFB37F1CA6882000E10745 /* ApplicationServices.framework */; };
9AC678E41C1ABAB9003B4F6B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AC678E31C1ABAB9003B4F6B /* QuartzCore.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9ACB31401EDA994200F3E1D3 /* ShortcutRecorder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ACB313F1EDA994200F3E1D3 /* ShortcutRecorder.framework */; };
9ACF469D1DCBD45200C49B51 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ACF469C1DCBD45200C49B51 /* Quartz.framework */; };
9ACF618D231DABAE00F5E51E /* SearchDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ACF618C231DABAE00F5E51E /* SearchDataSource.swift */; };
C20839CA21515C1E00C86589 /* ClockerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C20839C921515C1E00C86589 /* ClockerUnitTests.swift */; };
C213713420B4FD920024D5A4 /* FloatingWindowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C213713320B4FD920024D5A4 /* FloatingWindowTests.swift */; };
C22F3D802107778A0001D5E1 /* ShortcutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C22F3D7F2107778A0001D5E1 /* ShortcutTests.swift */; };
C264A0C520B897D800CCD875 /* PreferencesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C264A0C420B897D800CCD875 /* PreferencesTest.swift */; };
C264A0C820B898D600CCD875 /* PanelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C264A0C720B898D600CCD875 /* PanelTests.swift */; };
C2AB022421AEED590014A401 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AB022321AEED590014A401 /* OnboardingTests.swift */; };
C2BFE3E62049F82300825BE5 /* ClockerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = C2BFE3E52049F82300825BE5 /* ClockerUITests.m */; };
C2CCCD8220619C4C00F2DFC2 /* LocationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2CCCD8120619C4C00F2DFC2 /* LocationController.swift */; };
C2D30A8A210245C6000BFAEE /* ReviewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D30A89210245C6000BFAEE /* ReviewTests.swift */; };
C2D30A8D21025106000BFAEE /* NetworkDisconnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D30A8C21025106000BFAEE /* NetworkDisconnectionTests.swift */; };
C2F7821B20B70E3700B6CD07 /* AboutUsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F7821A20B70E3700B6CD07 /* AboutUsTests.swift */; };
DD4F7C0913C30F9F00825C6E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD4F7C0813C30F9F00825C6E /* Cocoa.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
9A5E75E6204CC39700119939 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 9398377F0DA42965007F53F3;
remoteInfo = ShortcutRecorder.framework;
};
9A5E75EA204CC39700119939 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = E273122D1349EC9000A84433;
remoteInfo = PTHotKey.framework;
};
9A86E2BB1CE04F1600547EE7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 939837800DA42965007F53F3;
remoteInfo = ShortcutRecorder.framework;
};
9A86E2BD1CE04F1600547EE7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = E273122E1349EC9000A84433;
remoteInfo = PTHotKey.framework;
};
C20839CC21515C1F00C86589 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DD4F7BFB13C30F9F00825C6E /* Project object */;
proxyType = 1;
remoteGlobalIDString = DD4F7C0313C30F9F00825C6E;
remoteInfo = Clocker;
};
C2BFE3E82049F82300825BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DD4F7BFB13C30F9F00825C6E /* Project object */;
proxyType = 1;
remoteGlobalIDString = DD4F7C0313C30F9F00825C6E;
remoteInfo = Clocker;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9A20A0711C4E808500FB45AB /* Login Item Helper */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = Contents/Library/LoginItems;
dstSubfolderSpec = 1;
files = (
9A7547E51F184E3F004705EF /* ClockerHelper.app in Login Item Helper */,
);
name = "Login Item Helper";
runOnlyForDeploymentPostprocessing = 0;
};
9A5E75EC204CC39700119939 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
9A5E75E9204CC39700119939 /* PTHotKey.framework in Embed Frameworks */,
9A5E75E5204CC39700119939 /* ShortcutRecorder.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3508CC932599FFEC000E3530 /* MenubarTitleProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenubarTitleProvider.swift; sourceTree = ""; };
3508CC99259A0001000E3530 /* StatusItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItemView.swift; sourceTree = ""; };
3508CC9E259A000E000E3530 /* StatusItemHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItemHandler.swift; sourceTree = ""; };
3508CCA9259A0027000E3530 /* StatusContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContainerView.swift; sourceTree = ""; };
352AF497232E07B400D96FA7 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/InfoPlist.strings; sourceTree = ""; };
352AF499232E07B400D96FA7 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = ""; };
3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
3531F7EA26936D8800DF0111 /* Firebase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Firebase.h; sourceTree = ""; };
3531F7F42693882300DF0111 /* Keys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Keys.plist; path = Internal/Keys.plist; sourceTree = ""; };
3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleUtilities.framework; path = Frameworks/Firebase/GoogleUtilities.framework; sourceTree = ""; };
3531F7FD26938D7700DF0111 /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/Firebase/FirebaseCoreDiagnostics.framework; sourceTree = ""; };
3531F7FE26938D7700DF0111 /* FirebaseDatabase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseDatabase.framework; path = Frameworks/Firebase/FirebaseDatabase.framework; sourceTree = ""; };
3531F7FF26938D7700DF0111 /* PromisesObjC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PromisesObjC.framework; path = Frameworks/Firebase/PromisesObjC.framework; sourceTree = ""; };
3531F80026938D7700DF0111 /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/Firebase/FirebaseCore.framework; sourceTree = ""; };
3531F80126938D7700DF0111 /* nanopb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = nanopb.framework; path = Frameworks/Firebase/nanopb.framework; sourceTree = ""; };
3531F80226938D7700DF0111 /* FirebaseCrashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCrashlytics.framework; path = Frameworks/Firebase/FirebaseCrashlytics.framework; sourceTree = ""; };
3531F80326938D7700DF0111 /* FirebaseInstallations.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseInstallations.framework; path = Frameworks/Firebase/FirebaseInstallations.framework; sourceTree = ""; };
3531F80426938D7700DF0111 /* leveldb-library.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "leveldb-library.framework"; path = "Frameworks/Firebase/leveldb-library.framework"; sourceTree = ""; };
3531F80526938D7700DF0111 /* GoogleDataTransport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleDataTransport.framework; path = Frameworks/Firebase/GoogleDataTransport.framework; sourceTree = ""; };
353B5BC42698B78A0023858D /* UpcomingEventStatusItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpcomingEventStatusItemView.swift; sourceTree = ""; };
353B5BC72698D4BB0023858D /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = ""; };
3548C45926BECF1B00AFB533 /* UpcomingEventViewItem.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UpcomingEventViewItem.xib; sourceTree = ""; };
3548C45C26BEEF4C00AFB533 /* ParentPanelController+UpcomingEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParentPanelController+UpcomingEvents.swift"; sourceTree = ""; };
3548C45E26BEEFB400AFB533 /* UpcomingEventsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpcomingEventsDataSource.swift; sourceTree = ""; };
3548C46026BEEFE400AFB533 /* UpcomingEventViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpcomingEventViewItem.swift; sourceTree = ""; };
3552066027AF6277000EF08F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; };
3552066227AF63DC000EF08F /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; };
3552066327AF63DC000EF08F /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; };
3552066427AF6488000EF08F /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; };
3552066527AF6489000EF08F /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; };
35584D1327EF8EB5006E3EAD /* ThemerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemerTests.swift; sourceTree = ""; };
35584D1727F0B019006E3EAD /* DateFormatterManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateFormatterManagerTests.swift; sourceTree = ""; };
35584D1927F0B64E006E3EAD /* AppDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegateTests.swift; sourceTree = ""; };
35621CFB27F66C1900926D5C /* SearchDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchDataSourceTests.swift; sourceTree = ""; };
3567F7DB288DC6520049C7A9 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = ""; };
3569A44E25441F320087E254 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; };
357391852507277500D30819 /* TimeMarkerViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeMarkerViewItem.swift; sourceTree = ""; };
357391862507277500D30819 /* HourMarkerViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HourMarkerViewItem.xib; sourceTree = ""; };
3579765D2680208C009DDA6E /* ParentPanelController+ModernSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParentPanelController+ModernSlider.swift"; sourceTree = ""; };
3595FACF227F88BC0044A12A /* UserDefaults + KVOExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults + KVOExtensions.swift"; sourceTree = ""; };
35A6A4B925C5DEF300356073 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = ""; };
35B2FEB1259A1649005DA84D /* StartupKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = StartupKit; sourceTree = ""; };
35B2FED4259A2244005DA84D /* CoreLoggerKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CoreLoggerKit; sourceTree = ""; };
35B2FEE4259A2C25005DA84D /* CoreModelKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CoreModelKit; sourceTree = ""; };
35BD9A562807580800077443 /* EventInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventInfoTests.swift; sourceTree = ""; };
35C11E2024873A550031F18C /* VersionUpdateHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionUpdateHandler.swift; sourceTree = ""; };
35C36EE822595F13002FA5C6 /* OnboardingPermissionsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingPermissionsViewController.swift; sourceTree = ""; };
35C36EE922595F13002FA5C6 /* OnboardingWelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingWelcomeViewController.swift; sourceTree = ""; };
35C36EEA22595F13002FA5C6 /* WelcomeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WelcomeView.xib; sourceTree = ""; };
35C36EEB22595F13002FA5C6 /* StartAtLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartAtLoginViewController.swift; sourceTree = ""; };
35C36EEC22595F13002FA5C6 /* OnboardingSearchController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSearchController.swift; sourceTree = ""; };
35C36EED22595F13002FA5C6 /* OnboardingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingController.swift; sourceTree = ""; };
35C36EEE22595F13002FA5C6 /* FinalOnboardingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FinalOnboardingViewController.swift; sourceTree = ""; };
35C36EEF22595F14002FA5C6 /* Onboarding.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = ""; };
35C36EF022595F14002FA5C6 /* OnboardingParentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingParentViewController.swift; sourceTree = ""; };
35C36EFA2259616B002FA5C6 /* Solar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Solar.swift; sourceTree = ""; };
35C36EFE225961D9002FA5C6 /* Date+Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Bundle.swift"; sourceTree = ""; };
35C36F00225961D9002FA5C6 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
35C36F02225961DA002FA5C6 /* Date+Components.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Components.swift"; sourceTree = ""; };
35C36F03225961DA002FA5C6 /* Date+TimeAgo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+TimeAgo.swift"; sourceTree = ""; };
35C36F04225961DA002FA5C6 /* Integer+DateTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Integer+DateTools.swift"; sourceTree = ""; };
35C36F05225961DA002FA5C6 /* TimeChunk.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeChunk.swift; sourceTree = ""; };
35C36F06225961DA002FA5C6 /* Date+Inits.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Inits.swift"; sourceTree = ""; };
35C36F07225961DA002FA5C6 /* DateTools.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = DateTools.bundle; sourceTree = ""; };
35C36F08225961DA002FA5C6 /* Date+Comparators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Comparators.swift"; sourceTree = ""; };
35C36F09225961DA002FA5C6 /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; };
35C36F0A225961DA002FA5C6 /* Date+Manipulations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Manipulations.swift"; sourceTree = ""; };
35C36F0B225961DA002FA5C6 /* Date+Format.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Format.swift"; sourceTree = ""; };
35C36F1E22596253002FA5C6 /* OneWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OneWindowController.swift; sourceTree = ""; };
35C36F1F22596253002FA5C6 /* AppearanceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearanceViewController.swift; sourceTree = ""; };
35C36F272259D6FA002FA5C6 /* ParentPanelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParentPanelController.swift; sourceTree = ""; };
35C36F282259D6FA002FA5C6 /* PanelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PanelController.swift; sourceTree = ""; };
35C36F322259D7C3002FA5C6 /* AddTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddTableViewCell.swift; sourceTree = ""; };
35C36F392259D892002FA5C6 /* Themer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Themer.swift; sourceTree = ""; };
35C36F3A2259D892002FA5C6 /* Timer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timer.swift; sourceTree = ""; };
35C36F3D2259D892002FA5C6 /* Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; };
35C36F3E2259D892002FA5C6 /* DataStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = "