diff --git a/.gitignore b/.gitignore
index 0c419d5..e9539b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
.DS_Store
-KeyPopper.xcodeproj/project.xcworkspace/xcuserdata
\ No newline at end of file
+KeyPopper.xcodeproj/project.xcworkspace/xcuserdata
+/KeyPopper Installer/build
+KeyPopper.xcodeproj/xcuserdata/
diff --git a/KettleCornService/KettleCornSerivce.plist b/KettleCornService/KettleCornSerivce.plist
new file mode 100644
index 0000000..863b987
--- /dev/null
+++ b/KettleCornService/KettleCornSerivce.plist
@@ -0,0 +1,15 @@
+
+
+
+
+ Label
+ sh.linus.keypopper.KettleCornSerivce
+ Program
+ /Library/PreferencePanes/KeyPopper\ PrefPane.prefPane/Contents/XPCServices/KettleCornService
+ MachServices
+
+ sh.linus.keypopper.KettleCornService.mach
+
+
+
+
diff --git a/KettleCornService/KettleCornService.entitlements b/KettleCornService/KettleCornService.entitlements
new file mode 100644
index 0000000..49ad0bb
--- /dev/null
+++ b/KettleCornService/KettleCornService.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.automation.apple-events
+
+
+
diff --git a/KettleCornService/KettleCornService.swift b/KettleCornService/KettleCornService.swift
new file mode 100644
index 0000000..7831596
--- /dev/null
+++ b/KettleCornService/KettleCornService.swift
@@ -0,0 +1,81 @@
+//
+// KettleCornService.swift
+// KettleCornService
+//
+// Created by Linus Skucas on 8/3/21.
+//
+
+import Foundation
+
+struct SoundState {
+ private let userDefaults = UserDefaults.init(suiteName: "sh.linus.keypopper")!
+
+ var sound: PoppingSounds {
+ get {
+ let soundInt = userDefaults.integer(forKey: "sound")
+ let sound = PoppingSounds(rawValue: soundInt)!
+ return sound
+ }
+ set {
+ userDefaults.set(newValue.rawValue, forKey: "sound")
+ }
+ }
+ var enabled: Bool {
+ get {
+ let enabled = userDefaults.bool(forKey: "enabled")
+ return enabled
+ }
+ set {
+ userDefaults.set(newValue, forKey: "enabled")
+ }
+ }
+ static var shared: SoundState = SoundState()
+}
+
+@objc class KettleCornService: NSObject, KettleCornServiceProtocol {
+// func hello(_ text: String, withReply reply: @escaping (String) -> Void) {
+// reply("Hello, \(text)!")
+// }
+
+ var connection: NSXPCConnection!
+ var service: PoppingServiceProtocol!
+
+ override init() {
+ super.init()
+ connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.PoppingService.mach")
+ connection.remoteObjectInterface = NSXPCInterface(with: PoppingServiceProtocol.self)
+ connection.resume()
+
+ service = connection.remoteObjectProxyWithErrorHandler { error in
+ fatalError("Error: \(error.localizedDescription)")
+ } as! PoppingServiceProtocol
+ }
+
+ func changeSoundTo(_ soundInt: Int) {
+ let sound = PoppingSounds(rawValue: soundInt)!
+ // Store sound
+ NSLog("Change sound")
+ SoundState.shared.sound = sound
+ }
+
+ func changeSoundState(shouldPlaySound: Bool) {
+ NSLog("Change state")
+ SoundState.shared.enabled = shouldPlaySound
+ }
+
+ func boop() {
+ guard SoundState.shared.enabled else { return }
+
+ switch SoundState.shared.sound {
+ case .pop:
+ service.pop()
+ NSLog("POP")
+ case .frog:
+ service.frog()
+ NSLog("Frog")
+ case .moo:
+ service.moo()
+ NSLog("Moo")
+ }
+ }
+}
diff --git a/KettleCornService/KettleCornServiceDelegate.swift b/KettleCornService/KettleCornServiceDelegate.swift
new file mode 100644
index 0000000..8bd6302
--- /dev/null
+++ b/KettleCornService/KettleCornServiceDelegate.swift
@@ -0,0 +1,19 @@
+//
+// KettleCornServiceDelegate.swift
+// KettleCornService
+//
+// Created by Linus Skucas on 8/3/21.
+//
+
+import Foundation
+
+class KettleCornServiceDelegate: NSObject, NSXPCListenerDelegate {
+ func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
+ let exportedObject = KettleCornService()
+ newConnection.exportedInterface = NSXPCInterface(with: KettleCornServiceProtocol.self)
+ newConnection.exportedObject = exportedObject
+
+ newConnection.resume()
+ return true
+ }
+}
diff --git a/KettleCornService/KettleCornServiceProtocol.swift b/KettleCornService/KettleCornServiceProtocol.swift
new file mode 100644
index 0000000..1c3ee1a
--- /dev/null
+++ b/KettleCornService/KettleCornServiceProtocol.swift
@@ -0,0 +1,16 @@
+//
+// KettleCornServiceProtocol.swift
+// KettleCornService
+//
+// Created by Linus Skucas on 8/3/21.
+//
+
+import Foundation
+
+@objc(KettleCornServiceProtocol) protocol KettleCornServiceProtocol {
+// func hello(_ text: String, withReply reply: @escaping (String) -> Void)
+ func changeSoundTo(_ soundInt: Int)
+ func changeSoundState(shouldPlaySound: Bool)
+ func boop()
+}
+
diff --git a/KettleCornService/main.swift b/KettleCornService/main.swift
new file mode 100644
index 0000000..8ac4c08
--- /dev/null
+++ b/KettleCornService/main.swift
@@ -0,0 +1,14 @@
+//
+// main.swift
+// KettleCornService
+//
+// Created by Linus Skucas on 8/3/21.
+//
+
+import Foundation
+
+let delegate = KettleCornServiceDelegate()
+let listener = NSXPCListener(machServiceName: "sh.linus.keypopper.KettleCornService.mach")
+listener.delegate = delegate
+listener.resume()
+RunLoop.main.run()
diff --git a/KeyPopper Catcher/AppDelegate.swift b/KeyPopper Catcher/AppDelegate.swift
new file mode 100644
index 0000000..1bc922d
--- /dev/null
+++ b/KeyPopper Catcher/AppDelegate.swift
@@ -0,0 +1,61 @@
+//
+// AppDelegate.swift
+// KeyPopper Catcher
+//
+// Created by Linus Skucas on 8/13/21.
+//
+
+import Cocoa
+
+@main
+class AppDelegate: NSObject, NSApplicationDelegate {
+
+// var connection: NSXPCConnection!
+// var service: KettleCornServiceProtocol!
+
+ func applicationDidFinishLaunching(_ aNotification: Notification) {
+ // Insert code here to initialize your application
+
+// connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach")
+// connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self)
+// connection.resume()
+//
+// service = connection.remoteObjectProxyWithErrorHandler { error in
+// fatalError("Error: \(error.localizedDescription)")
+// } as! KettleCornServiceProtocol
+
+ let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue)
+ NSLog("gggp")
+ func cgEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged? {
+ let connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach")
+ connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self)
+ connection.resume()
+
+ let service = connection.remoteObjectProxyWithErrorHandler { error in
+ fatalError("Error: \(error.localizedDescription)")
+ } as! KettleCornServiceProtocol
+ service.boop()
+ return nil
+ }
+
+ guard let eventTap = CGEvent.tapCreate(tap: .cgAnnotatedSessionEventTap, place: .headInsertEventTap, options: .listenOnly, eventsOfInterest: CGEventMask(eventMask), callback: cgEventCallback, userInfo: nil) else {
+ DispatchQueue.main.async {
+ NSLog("faileddddddddd")
+ }
+ return
+ }
+ let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
+ CGEvent.tapEnable(tap: eventTap, enable: true)
+ CFRunLoopRun()
+ }
+
+ func applicationWillTerminate(_ aNotification: Notification) {
+ // Insert code here to tear down your application
+// connection.invalidate()
+ }
+
+ func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
+ return true
+ }
+}
diff --git a/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json b/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json b/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..3f00db4
--- /dev/null
+++ b/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "512x512"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "512x512"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/KeyPopper Catcher/Assets.xcassets/Contents.json b/KeyPopper Catcher/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/KeyPopper Catcher/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/KeyPopper Catcher/Base.lproj/Main.storyboard b/KeyPopper Catcher/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..d79679d
--- /dev/null
+++ b/KeyPopper Catcher/Base.lproj/Main.storyboard
@@ -0,0 +1,684 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeyPopper Catcher/KeyPopper Catcher.entitlements b/KeyPopper Catcher/KeyPopper Catcher.entitlements
new file mode 100644
index 0000000..49ad0bb
--- /dev/null
+++ b/KeyPopper Catcher/KeyPopper Catcher.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.automation.apple-events
+
+
+
diff --git a/KeyPopper Catcher/KeyPopper-Catcher-Info.plist b/KeyPopper Catcher/KeyPopper-Catcher-Info.plist
new file mode 100644
index 0000000..6f7ae58
--- /dev/null
+++ b/KeyPopper Catcher/KeyPopper-Catcher-Info.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ LSUIElement
+
+
+
diff --git a/KeyPopper Catcher/KeyPopperCatcher.plist b/KeyPopper Catcher/KeyPopperCatcher.plist
new file mode 100644
index 0000000..a7cb74d
--- /dev/null
+++ b/KeyPopper Catcher/KeyPopperCatcher.plist
@@ -0,0 +1,20 @@
+
+
+
+
+ ProgramArguments
+
+ /usr/bin/open
+ -W
+ /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/SharedSupport/KeyPopper Catcher.app
+
+ KeepAlive
+
+ Label
+ sh.linus.keypopper.KeyPopper-Catcher
+ LimitLoadToSessionType
+ Aqua
+ RunAtLoad
+
+
+
diff --git a/KeyPopper Installer/KeyPopper.pkgproj b/KeyPopper Installer/KeyPopper.pkgproj
new file mode 100644
index 0000000..8d53697
--- /dev/null
+++ b/KeyPopper Installer/KeyPopper.pkgproj
@@ -0,0 +1,966 @@
+
+
+
+
+ PACKAGES
+
+
+ MUST-CLOSE-APPLICATION-ITEMS
+
+
+ APPLICATION_ID
+ com.apple.systempreferences
+ STATE
+
+
+
+ MUST-CLOSE-APPLICATIONS
+
+ PACKAGE_FILES
+
+ DEFAULT_INSTALL_LOCATION
+ /
+ HIERARCHY
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Applications
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 509
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Application Support
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Automator
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Documentation
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Extensions
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Filesystems
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Frameworks
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Input Methods
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Internet Plug-Ins
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ /Users/linus/Sources/KeyPopper/KettleCornService/KettleCornSerivce.plist
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 420
+ TYPE
+ 3
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ /Users/linus/Sources/KeyPopper/KeyPopper Catcher/KeyPopperCatcher.plist
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 420
+ TYPE
+ 3
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ /Users/linus/Sources/KeyPopper/PoppingService/PoppingService.plist
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 420
+ TYPE
+ 3
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ LaunchAgents
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchDaemons
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ BUNDLE_CAN_DOWNGRADE
+
+ BUNDLE_POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ BUNDLE_PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ /Users/linus/Sources/App Release/KeyPopper PrefPane 2021-08-14 16-29-03/Products/Users/linus/Library/PreferencePanes/KeyPopper PrefPane.prefPane
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 3
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ PreferencePanes
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Preferences
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Printers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PrivilegedHelperTools
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1005
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickLook
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickTime
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Screen Savers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Scripts
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Services
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Widgets
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Library
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Shared
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1023
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Users
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ /
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+ PAYLOAD_TYPE
+ 0
+ PRESERVE_EXTENDED_ATTRIBUTES
+
+ SHOW_INVISIBLE
+
+ SPLIT_FORKS
+
+ TREAT_MISSING_FILES_AS_WARNING
+
+ VERSION
+ 5
+
+ PACKAGE_SCRIPTS
+
+ POSTINSTALL_PATH
+
+ PATH
+ /Users/linus/Sources/KeyPopper/KeyPopper Installer/install.sh
+ PATH_TYPE
+ 0
+
+ PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ RESOURCES
+
+
+ PACKAGE_SETTINGS
+
+ AUTHENTICATION
+ 0
+ CONCLUSION_ACTION
+ 0
+ FOLLOW_SYMBOLIC_LINKS
+
+ IDENTIFIER
+ sh.linus.keypopper.installer
+ LOCATION
+ 0
+ NAME
+ KeyPopper
+ OVERWRITE_PERMISSIONS
+
+ PAYLOAD_SIZE
+ -1
+ REFERENCE_PATH
+
+ RELOCATABLE
+
+ USE_HFS+_COMPRESSION
+
+ VERSION
+ 1.0
+
+ TYPE
+ 0
+ UUID
+ 8257C519-F2B7-47D3-BEAF-DEA802FC82CC
+
+
+ PROJECT
+
+ PROJECT_COMMENTS
+
+ NOTES
+
+
+
+ PROJECT_PRESENTATION
+
+ BACKGROUND
+
+ ALIGNMENT
+ 6
+ APPAREANCES
+
+ DARK_AQUA
+
+ LIGHT_AQUA
+
+ ALIGNMENT
+ 6
+ BACKGROUND_PATH
+
+ PATH
+ /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/PrefPane.tiff
+ PATH_TYPE
+ 0
+
+ CUSTOM
+
+ LAYOUT_DIRECTION
+ 1
+ SCALING
+ 0
+
+
+ BACKGROUND_PATH
+
+ PATH
+ /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/PrefPane.tiff
+ PATH_TYPE
+ 0
+
+ CUSTOM
+
+ LAYOUT_DIRECTION
+ 1
+ SCALING
+ 0
+ SHARED_SETTINGS_FOR_ALL_APPAREANCES
+
+
+ INSTALLATION_STEPS
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewIntroductionController
+ INSTALLER_PLUGIN
+ Introduction
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewReadMeController
+ INSTALLER_PLUGIN
+ ReadMe
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewLicenseController
+ INSTALLER_PLUGIN
+ License
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewDestinationSelectController
+ INSTALLER_PLUGIN
+ TargetSelect
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewInstallationTypeController
+ INSTALLER_PLUGIN
+ PackageSelection
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewInstallationController
+ INSTALLER_PLUGIN
+ Install
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewSummaryController
+ INSTALLER_PLUGIN
+ Summary
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ INTRODUCTION
+
+ LOCALIZATIONS
+
+
+ LICENSE
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+
+ PATH
+ /Users/linus/Sources/KeyPopper/KeyPopper Installer/license.rtf
+ PATH_TYPE
+ 0
+
+
+
+ MODE
+ 0
+
+ README
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+
+ PATH
+ /Users/linus/Sources/KeyPopper/KeyPopper Installer/readme.rtf
+ PATH_TYPE
+ 0
+
+
+
+
+ TITLE
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+ KeyPopper
+
+
+
+
+ PROJECT_REQUIREMENTS
+
+ LIST
+
+
+ BEHAVIOR
+ 3
+ DICTIONARY
+
+ IC_REQUIREMENT_OS_DISK_TYPE
+ 0
+ IC_REQUIREMENT_OS_DISTRIBUTION_TYPE
+ 0
+ IC_REQUIREMENT_OS_MINIMUM_VERSION
+ 101500
+
+ IC_REQUIREMENT_CHECK_TYPE
+ 1
+ IDENTIFIER
+ fr.whitebox.Packages.requirement.os
+ MESSAGE
+
+
+ LANGUAGE
+ English
+ VALUE
+ This volume is too old.
+
+
+ NAME
+ Operating System
+ STATE
+
+
+
+ RESOURCES
+
+ ROOT_VOLUME_ONLY
+
+
+ PROJECT_SETTINGS
+
+ BUILD_FORMAT
+ 0
+ BUILD_PATH
+
+ PATH
+ build
+ PATH_TYPE
+ 1
+
+ EXCLUDED_FILES
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .DS_Store
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove .DS_Store files
+ PROXY_TOOLTIP
+ Remove ".DS_Store" files created by the Finder.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .pbdevelopment
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove .pbdevelopment files
+ PROXY_TOOLTIP
+ Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ CVS
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .cvsignore
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .cvspass
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .svn
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .git
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .gitignore
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove SCM metadata
+ PROXY_TOOLTIP
+ Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ classes.nib
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ designable.db
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ info.nib
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Optimize nib files
+ PROXY_TOOLTIP
+ Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ Resources Disabled
+ TYPE
+ 1
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove Resources Disabled folders
+ PROXY_TOOLTIP
+ Remove "Resources Disabled" folders.
+ STATE
+
+
+
+ SEPARATOR
+
+
+
+ NAME
+ KeyPopper
+ PAYLOAD_ONLY
+
+ TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING
+
+
+
+ TYPE
+ 0
+ VERSION
+ 2
+
+
diff --git a/KeyPopper Installer/install.sh b/KeyPopper Installer/install.sh
new file mode 100755
index 0000000..5337f09
--- /dev/null
+++ b/KeyPopper Installer/install.sh
@@ -0,0 +1,5 @@
+launchctl load /Library/LaunchAgents/KettleCornSerivce.plist
+launchctl load /Library/LaunchAgents/PoppingService.plist
+launchctl load /Library/LaunchAgents/KeyPopperCatcher.plist
+
+open "/Library/PreferencePanes/KeyPopper PrefPane.prefPane"
\ No newline at end of file
diff --git a/KeyPopper Installer/license.rtf b/KeyPopper Installer/license.rtf
new file mode 100644
index 0000000..00c74f9
--- /dev/null
+++ b/KeyPopper Installer/license.rtf
@@ -0,0 +1,111 @@
+{\rtf1\mac\ansicpg10000\cocoartf\nisusversion50201\nisusorigversion50201 {\*\nisusorigdate\yr2021\mo8\dy14\hr17\min34 }{\*\nisussysvers 11.5.0}{\*\nisusorigsysvers 11.5.0}\deff0
+{\*\fonttbl
+{\f0\fswiss\fcharset77 SFPro-Regular{\*\falt SF Pro};}
+{\f1\fnil\fcharset77 Tahoma-Bold{\*\falt Tahoma};}
+{\f2\fswiss\fcharset77 Tahoma;}}
+{\colortbl ;\red0\green0\blue0 ;}\nisusrevtypes0\donotshowinsdel1
+{\*\nisustoctable
+{\nisustoc\tcf68 {\nisustocname Default TOC}{\*\nisustoctabrep }{\*\nisustocretrep }{\nisustoclevelstyle TOC 1}{\nisustoclevelstyle TOC 2}{\nisustoclevelstyle TOC 3}{\nisustoclevelstyle TOC 4}{\nisustoclevelstyle TOC 5}{\nisustoclevelstyle TOC 6}{\nisustoclevelstyle TOC 7}{\nisustoclevelstyle TOC 8}{\nisustoclevelstyle TOC 9}}\nisusactivetoc68 }
+{\*\nisusxetable
+{\nisusxe\xef68 {\nisusxename Default Index}{\nisusxeheaderstyle Index Heading}{\nisusxelevelstyle Index 1}{\nisusxelevelstyle Index 2}{\nisusxelevelstyle Index 3}{\nisusxelevelstyle Index 4}{\nisusxelevelstyle Index 5}{\nisusxelevelstyle Index 6}{\nisusxelevelstyle Index 7}{\nisusxelevelstyle Index 8}{\nisusxelevelstyle Index 9}{\*\fldinst INDEX \\k ". " \\g \endash \\e "\tab " \\l ", " \\f D}}\nisusactivexe68 }
+{\stylesheet
+{\s106\snext106\f0 \ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Normal;}
+{\s107\snext106\sbasedon106\f1\fs28\b \ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Title;}
+{\s108\nisusnoteplacement2\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle120\nisusnotedocstyletarget1\nisusnoterefstyle121 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Endnote;}
+{\s109\nisusnoteplacement0\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle120\nisusnotedocstyletarget1\nisusnoterefstyle121 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\nowidctlpar\keep0\keepn0\pagebb0\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footnote;}
+{\s110\snext106\sbasedon106\f1\fs28\b \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl1 Heading 1;}
+{\s111\snext106\sbasedon110\f1\fs26\b\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl2 Heading 2;}
+{\s112\snext106\sbasedon111\f1\fs26\b\i \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl3 Heading 3;}
+{\s113\snext106\sbasedon112\f2\fs26\b0\i0\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl4 Heading 4;}
+{\s114\snext106\sbasedon113\f2\fs26\b0\i0\ul \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl5 Heading 5;}
+{\s115\snext106\sbasedon114\f2\fs26\b0\i\ul\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl6 Heading 6;}
+{\s116\snext116\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Header;}
+{\s117\snext117\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footer;}
+{\s118\snext118\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li1080\lin1080\fi0\ri1020\rin1020 Block Quote;}
+{\*\cs119\b Strong;}
+{\*\cs120\super Note Reference;}
+{\*\cs121\sbasedon120\nosupersub Note Reference in Note;}
+{\*\cs122\i Emphatic;}}
+{\*\listtable
+{\list\listhybrid {\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li648\lin648\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1008\lin1008\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1368\lin1368\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1728\lin1728\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2088\lin2088\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2448\lin2448\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2808\lin2808\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3168\lin3168\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3528\lin3528\fi-360\ri0\rin0 }
+{\listname ;}\listid88001\nisuslistcontnum0 {\*\liststylename Bullet List;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li576\lin576\fi-576\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li796\lin796\fi-796\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1016\lin1016\fi-1016\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1236\lin1236\fi-1236\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1456\lin1456\fi-1456\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1676\lin1676\fi-1676\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1896\lin1896\fi-1896\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2116\lin2116\fi-2116\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2336\lin2336\fi-2336\ri0\rin0 }
+{\listname ;}\listid88002\nisuslistcontnum1 {\*\liststylename Headings;}}
+{\list\listhybrid {\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1008\lin1008\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1368\lin1368\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1728\lin1728\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2088\lin2088\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2448\lin2448\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2808\lin2808\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3168\lin3168\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3528\lin3528\fi-360\ri0\rin0 }
+{\listname ;}\listid88003\nisuslistcontnum0 {\*\liststylename Lettered List;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li720\lin720\fi-432\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1080\lin1080\fi-430\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1440\lin1440\fi-430\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1800\lin1800\fi-430\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2160\lin2160\fi-430\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2520\lin2520\fi-430\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2880\lin2880\fi-430\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3240\lin3240\fi-432\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3600\lin3600\fi-432\ri0\rin0 }
+{\listname ;}\listid88004\nisuslistcontnum0 {\*\liststylename Number List;}}
+{\list\listhybrid {\listlevel\levelnfc1\levelnfcn1\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li360\lin360\fi-360\ri0\rin0 }
+{\listlevel\levelnfc3\levelnfcn3\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li720\lin720\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1080\lin1080\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'03);}{\levelnumbers \'01;}\li1440\lin1440\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li1800\lin1800\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2160\lin2160\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'06);}{\levelnumbers \'02;}\li2520\lin2520\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'07);}{\levelnumbers \'02;}\li2880\lin2880\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'08);}{\levelnumbers \'02;}\li3240\lin3240\fi-360\ri0\rin0 }
+{\listname ;}\listid88005\nisuslistcontnum0 {\*\liststylename Outline;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-648\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li868\lin868\fi-868\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1088\lin1088\fi-1088\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1308\lin1308\fi-1308\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1528\lin1528\fi-1528\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1748\lin1748\fi-1748\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1968\lin1968\fi-1968\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2188\lin2188\fi-2188\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2408\lin2408\fi-2408\ri0\rin0 }
+{\listname ;}\listid88006\nisuslistcontnum0 {\*\liststylename Tiered List;}}}
+{\*\listoverridetable
+{\listoverride\listid88001\listoverridecount0\ls1 }
+{\listoverride\listid88002\listoverridecount0\ls2 }
+{\listoverride\listid88003\listoverridecount0\ls3 }
+{\listoverride\listid88004\listoverridecount0\ls4 }
+{\listoverride\listid88005\listoverridecount0\ls5 }
+{\listoverride\listid88006\listoverridecount0\ls6 }}
+\defformat {\info {\*\nisusgmtoffset -7:00}{\author Linus Skucas}{\creatim\yr2021\mo8\dy14\hr17\min34 }{\revtim\yr2021\mo8\dy14\hr17\min35 }\nofpages1 }{\*\userprops }\nisusrulerunits0\nisusstatusbar1\nisusareaid1\viewkind1\viewzk1\nisusviewruler1\nisusviewrulerh1\nisusviewrulerv0\nisusviewtoolbar1\nisusviewtooldrawer1\nisusviewtoolswidth250\nisusviewpagenumtype1\nisusviewrulericons0\donotshowcomments1
+{\*\nisusviewsettings\viewkind4\viewscale125 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\viewkind1\viewzk1 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}{\*\closedtochandles }}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew102\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew103\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew104\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+\nisusareasplitv0
+{\*\nisuswindow\x63\y1006\w1074\actualw1324\h864 }
+\nshwinv0\nshwpg1\nisusinlinespell1\nisushyphnone\spltpgpar\nisusselectstart102\nisusselectlength0\ftnstart1\ftnnar\aftnstart1\aftnnar\aenddoc\fet2\ftnbj\paperw12240\paperh15840\margl1440\margr1440\margt1800\margb1800\gutter0\pgnstart1\nocolbal\widowctrl \f0
+\sectd\endnhere\sftnnar\saftnnar\cols1\ltrsect\colbalsxn0\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1800\margbsxn1800\guttersxn0\headery720\footery720\pgnstarts1\pgnrestart\pgndec\sxnstarts1\sxnrestart\sxndec
+{\header\plain\pard\s116\ltrpar\pardirnatural\ql\f0\fs24 }
+{\footer\plain\pard\s117\ltrpar\pardirnatural\ql\f0\fs24 }
+\deftab720 {\*\nisusscroll\nisusarea1\xoffset0\yoffset95 }{\pard\s106\ltrpar\pardirnatural\ql {By using KeyPopper you agree not to sue or take me to court for anything.\par
+\par
+Thanks for using KeyPopper!\nisusselectcaret\par }}}
\ No newline at end of file
diff --git a/KeyPopper Installer/readme.rtf b/KeyPopper Installer/readme.rtf
new file mode 100644
index 0000000..119805d
--- /dev/null
+++ b/KeyPopper Installer/readme.rtf
@@ -0,0 +1,129 @@
+{\rtf1\mac\ansicpg10000\cocoartf\nisusversion50201\nisusorigversion50201 {\*\nisusorigdate\yr2021\mo8\dy14\hr17\min23 }{\*\nisussysvers 11.5.0}{\*\nisusorigsysvers 11.5.0}\deff0
+{\*\fonttbl
+{\f0\fswiss\fcharset77 SFPro-Regular{\*\falt SF Pro};}
+{\f1\fswiss\fcharset77 SFPro-Bold{\*\falt SF Pro};}
+{\f2\fnil\fcharset77 Tahoma-Bold{\*\falt Tahoma};}
+{\f3\fswiss\fcharset77 Tahoma;}}
+{\colortbl ;\red0\green0\blue0 ;\red252\green128\blue8 ;}\nisusrevtypes0\donotshowinsdel1
+{\*\nisustoctable
+{\nisustoc\tcf68 {\nisustocname Default TOC}{\*\nisustoctabrep }{\*\nisustocretrep }{\nisustoclevelstyle TOC 1}{\nisustoclevelstyle TOC 2}{\nisustoclevelstyle TOC 3}{\nisustoclevelstyle TOC 4}{\nisustoclevelstyle TOC 5}{\nisustoclevelstyle TOC 6}{\nisustoclevelstyle TOC 7}{\nisustoclevelstyle TOC 8}{\nisustoclevelstyle TOC 9}}\nisusactivetoc68 }
+{\*\nisusxetable
+{\nisusxe\xef68 {\nisusxename Default Index}{\nisusxeheaderstyle Index Heading}{\nisusxelevelstyle Index 1}{\nisusxelevelstyle Index 2}{\nisusxelevelstyle Index 3}{\nisusxelevelstyle Index 4}{\nisusxelevelstyle Index 5}{\nisusxelevelstyle Index 6}{\nisusxelevelstyle Index 7}{\nisusxelevelstyle Index 8}{\nisusxelevelstyle Index 9}{\*\fldinst INDEX \\k ". " \\g \endash \\e "\tab " \\l ", " \\f D}}\nisusactivexe68 }
+{\stylesheet
+{\s106\snext106\f0 \ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Normal;}
+{\s107\snext107\sbasedon106\f0\ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Table Cell;}
+{\s108\snext106\sbasedon106\f2\fs28\b \ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Title;}
+{\s109\nisusnoteplacement2\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle121\nisusnotedocstyletarget1\nisusnoterefstyle122 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Endnote;}
+{\s110\nisusnoteplacement0\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle121\nisusnotedocstyletarget1\nisusnoterefstyle122 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\nowidctlpar\keep0\keepn0\pagebb0\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footnote;}
+{\s111\snext106\sbasedon106\f2\fs28\b \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl1 Heading 1;}
+{\s112\snext106\sbasedon111\f2\fs26\b\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl2 Heading 2;}
+{\s113\snext106\sbasedon112\f2\fs26\b\i \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl3 Heading 3;}
+{\s114\snext106\sbasedon113\f3\fs26\b0\i0\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl4 Heading 4;}
+{\s115\snext106\sbasedon114\f3\fs26\b0\i0\ul \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl5 Heading 5;}
+{\s116\snext106\sbasedon115\f3\fs26\b0\i\ul\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl6 Heading 6;}
+{\s117\snext117\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Header;}
+{\s118\snext118\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footer;}
+{\s119\snext119\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li1080\lin1080\fi0\ri1020\rin1020 Block Quote;}
+{\*\cs120\b Strong;}
+{\*\cs121\super Note Reference;}
+{\*\cs122\sbasedon121\nosupersub Note Reference in Note;}
+{\*\cs123\i Emphatic;}}
+{\*\listtable
+{\list\listhybrid {\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li648\lin648\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1008\lin1008\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1368\lin1368\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1728\lin1728\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2088\lin2088\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2448\lin2448\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2808\lin2808\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3168\lin3168\fi-360\ri0\rin0 }
+{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3528\lin3528\fi-360\ri0\rin0 }
+{\listname ;}\listid88001\nisuslistcontnum0 {\*\liststylename Bullet List;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li576\lin576\fi-576\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li796\lin796\fi-796\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1016\lin1016\fi-1016\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1236\lin1236\fi-1236\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1456\lin1456\fi-1456\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1676\lin1676\fi-1676\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1896\lin1896\fi-1896\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2116\lin2116\fi-2116\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2336\lin2336\fi-2336\ri0\rin0 }
+{\listname ;}\listid88002\nisuslistcontnum1 {\*\liststylename Headings;}}
+{\list\listhybrid {\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1008\lin1008\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1368\lin1368\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1728\lin1728\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2088\lin2088\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2448\lin2448\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2808\lin2808\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3168\lin3168\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3528\lin3528\fi-360\ri0\rin0 }
+{\listname ;}\listid88003\nisuslistcontnum0 {\*\liststylename Lettered List;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li720\lin720\fi-432\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1080\lin1080\fi-430\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1440\lin1440\fi-430\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1800\lin1800\fi-430\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2160\lin2160\fi-430\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2520\lin2520\fi-430\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2880\lin2880\fi-430\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3240\lin3240\fi-432\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3600\lin3600\fi-432\ri0\rin0 }
+{\listname ;}\listid88004\nisuslistcontnum0 {\*\liststylename Number List;}}
+{\list\listhybrid {\listlevel\levelnfc1\levelnfcn1\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li360\lin360\fi-360\ri0\rin0 }
+{\listlevel\levelnfc3\levelnfcn3\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li720\lin720\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1080\lin1080\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'03);}{\levelnumbers \'01;}\li1440\lin1440\fi-360\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li1800\lin1800\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2160\lin2160\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'06);}{\levelnumbers \'02;}\li2520\lin2520\fi-360\ri0\rin0 }
+{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'07);}{\levelnumbers \'02;}\li2880\lin2880\fi-360\ri0\rin0 }
+{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'08);}{\levelnumbers \'02;}\li3240\lin3240\fi-360\ri0\rin0 }
+{\listname ;}\listid88005\nisuslistcontnum0 {\*\liststylename Outline;}}
+{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-648\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li868\lin868\fi-868\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1088\lin1088\fi-1088\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1308\lin1308\fi-1308\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1528\lin1528\fi-1528\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1748\lin1748\fi-1748\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1968\lin1968\fi-1968\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2188\lin2188\fi-2188\ri0\rin0 }
+{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2408\lin2408\fi-2408\ri0\rin0 }
+{\listname ;}\listid88006\nisuslistcontnum0 {\*\liststylename Tiered List;}}}
+{\*\listoverridetable
+{\listoverride\listid88001\listoverridecount1 {\lfolevel\listoverridestartat\levelstartat1\nisuslistsoftoverridestartat }\ls1 }
+{\listoverride\listid88001\listoverridecount0\ls2 }
+{\listoverride\listid88002\listoverridecount0\ls3 }
+{\listoverride\listid88003\listoverridecount0\ls4 }
+{\listoverride\listid88004\listoverridecount0\ls5 }
+{\listoverride\listid88005\listoverridecount0\ls6 }
+{\listoverride\listid88006\listoverridecount0\ls7 }}
+\defformat {\info {\*\nisusgmtoffset -7:00}{\author Linus Skucas}{\creatim\yr2021\mo8\dy14\hr17\min23 }{\revtim\yr2021\mo8\dy14\hr17\min34 }\nofpages1 }{\*\userprops }\nisusrulerunits0\nisusstatusbar1\nisusareaid1\viewkind1\viewzk1\nisusviewruler1\nisusviewrulerh1\nisusviewrulerv0\nisusviewtoolbar1\nisusviewtooldrawer1\nisusviewtoolswidth250\nisusviewpagenumtype1\nisusviewrulericons0\donotshowcomments1
+{\*\nisusviewsettings\viewkind4\viewscale125 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\viewkind1\viewzk1 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}{\*\closedtochandles }}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew102\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew103\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+{\*\nisusviewsettings\nisusviewknew104\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}}
+\nisusareasplitv0
+{\*\nisuswindow\x63\y1034\w1074\actualw1324\h864 }
+\nshwinv0\nshwpg1\nisusinlinespell1\nisushyphnone\spltpgpar\nisusselectstart542\nisusselectlength1\ftnstart1\ftnnar\aftnstart1\aftnnar\aenddoc\fet2\ftnbj\paperw12240\paperh15840\margl1440\margr1440\margt1800\margb1800\gutter0\pgnstart1\nocolbal\widowctrl \f0
+\sectd\endnhere\sftnnar\saftnnar\cols1\ltrsect\colbalsxn0\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1800\margbsxn1800\guttersxn0\headery720\footery720\pgnstarts1\pgnrestart\pgndec\sxnstarts1\sxnrestart\sxndec
+{\header\plain\pard\s117\ltrpar\pardirnatural\ql\f0\fs24 }
+{\footer\plain\pard\s118\ltrpar\pardirnatural\ql\f0\fs24 }
+\deftab720 {\*\nisusscroll\nisusarea1\xoffset0\yoffset95 }{\pard\s106\ltrpar\pardirnatural\ql {Hello!\par
+This will install the KeyPopper software on your computer. KeyPopper does not collect, store, or send your keystrokes anywhere.\par
+\par
+This installation package will install: \par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\f1\b\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls1\ilvl0\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\f1\b 3 Launch Agents}{\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {2 are XPC services for communication\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {1 is an app which will be launched whenever your system is started.\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {The Launch Agents will be loaded, too.\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl0\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {1 Preference Pane\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {For controlling the sounds.\par }}
+{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {This preference pane will be opened right after installation.\par }}
+{\pard\s106\ltrpar\pardirnatural\ql {\par
+If you want to change the sound or turn off the sound, go to the Preference Pane.\par
+{\nisusselected1 \par }}}
+{\pard\nisusnos\ltrpar\pardirnatural\ql\nisustableprefix0 }\plain\intbl
+\trowd\trqc\nisustrhoffset-53\ltrrow\trrh1500\clheight1500\nisustablepadt0\nisustablepadl20\nisustablepadb100\nisustablepadr20\clvertalc\clbrdrt\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\clbrdrb\brdrs\brdrw20\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clftsWidth3\clwWidth8620\cellx8620
+{{\pard\intbl\s106\ltrpar\pardirnatural\qc {\intbl For KeyPopper to work it must monitor your keystrokes. They will not be sent anywhere. After installation you will be prompted that an app called {\f1\b\cf2\intbl KeyPopper Catcher} wants input monitoring permissions. You must give permissions for KeyPopper to work. \cell }}\row }
+\pard\plain {\pard\nisusnos\ltrpar\pardirnatural\ql {\par }}}
\ No newline at end of file
diff --git a/KeyPopper.xcodeproj/project.pbxproj b/KeyPopper.xcodeproj/project.pbxproj
index 8d7fa2b..d20d233 100644
--- a/KeyPopper.xcodeproj/project.pbxproj
+++ b/KeyPopper.xcodeproj/project.pbxproj
@@ -7,20 +7,177 @@
objects = {
/* Begin PBXBuildFile section */
- 1587085826B89CC50082DB8F /* PrefPane.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1587085726B89CC50082DB8F /* PrefPane.tiff */; };
+ 151BCD9926C8485900F1EA89 /* KeyPopper Catcher.app in Copy Catcher */ = {isa = PBXBuildFile; fileRef = 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 151BCD9E26C853E800F1EA89 /* PrefPane.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */; };
+ 151BCDAA26C86FBF00F1EA89 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDA926C86FBF00F1EA89 /* main.swift */; };
+ 151BCDAF26C86FFD00F1EA89 /* PoppingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */; };
+ 151BCDB126C8700800F1EA89 /* PoppingServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */; };
+ 151BCDB326C8701100F1EA89 /* PoppingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB226C8701100F1EA89 /* PoppingService.swift */; };
+ 151BCDB826C870CD00F1EA89 /* PoppingService in Copy PoppingService */ = {isa = PBXBuildFile; fileRef = 151BCDA726C86FBF00F1EA89 /* PoppingService */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
+ 151BCDC326C874DB00F1EA89 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC026C874DB00F1EA89 /* AVKit.framework */; };
+ 151BCDC426C874DB00F1EA89 /* AVFAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */; };
+ 151BCDC526C874DB00F1EA89 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */; };
+ 151BCDC726C8765600F1EA89 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC626C8765600F1EA89 /* AppKit.framework */; };
+ 151BCDC826C8771E00F1EA89 /* PoppingServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */; };
+ 151BCDCC26C87E0200F1EA89 /* pop.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDB926C8711000F1EA89 /* pop.mp3 */; };
+ 151BCDCD26C87E0200F1EA89 /* moo.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDBC26C873B600F1EA89 /* moo.mp3 */; };
+ 151BCDCE26C87E0200F1EA89 /* frog.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDBE26C874C900F1EA89 /* frog.mp3 */; };
+ 1525B06A26BA208000A504EB /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B06926BA208000A504EB /* main.swift */; };
+ 1525B06F26BA21FF00A504EB /* KettleCornServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */; };
+ 1525B07126BA227700A504EB /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; };
+ 1525B07326BA22AD00A504EB /* KettleCornService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07226BA22AD00A504EB /* KettleCornService.swift */; };
+ 1525B07A26BA27E000A504EB /* KettleCornService in Copy Services to Bundle */ = {isa = PBXBuildFile; fileRef = 1525B06726BA208000A504EB /* KettleCornService */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
+ 154214B626BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms in Resources */ = {isa = PBXBuildFile; fileRef = 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */; };
+ 1542150B26C05E02007E4A08 /* PoppingSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1542150A26C05E02007E4A08 /* PoppingSounds.swift */; };
+ 1542150C26C05E02007E4A08 /* PoppingSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1542150A26C05E02007E4A08 /* PoppingSounds.swift */; };
+ 1542150E26C068FF007E4A08 /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; };
1587085B26B89CC50082DB8F /* KeyPopper.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1587085926B89CC50082DB8F /* KeyPopper.xib */; };
1587086226B8A04B0082DB8F /* KeyPopperPrefPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */; };
+ 15E014B226C7749100A432BD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E014B126C7749100A432BD /* AppDelegate.swift */; };
+ 15E014B626C7749A00A432BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 15E014B526C7749A00A432BD /* Assets.xcassets */; };
+ 15E014B926C7749A00A432BD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 15E014B726C7749A00A432BD /* Main.storyboard */; };
+ 15E014BF26C77BAC00A432BD /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; };
/* End PBXBuildFile section */
+/* Begin PBXContainerItemProxy section */
+ 151BCD9A26C8485F00F1EA89 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 1587083126B89C720082DB8F /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 15E014AE26C7749100A432BD;
+ remoteInfo = "KeyPopper Catcher";
+ };
+ 151BCDB526C870BB00F1EA89 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 1587083126B89C720082DB8F /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 151BCDA626C86FBF00F1EA89;
+ remoteInfo = PoppingService;
+ };
+ 1525B07626BA270600A504EB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 1587083126B89C720082DB8F /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 1525B06626BA208000A504EB;
+ remoteInfo = KettleCornService;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 151BCD9826C8484200F1EA89 /* Copy Catcher */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 12;
+ files = (
+ 151BCD9926C8485900F1EA89 /* KeyPopper Catcher.app in Copy Catcher */,
+ );
+ name = "Copy Catcher";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 151BCDB726C870C600F1EA89 /* Copy PoppingService */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 15;
+ files = (
+ 151BCDB826C870CD00F1EA89 /* PoppingService in Copy PoppingService */,
+ );
+ name = "Copy PoppingService";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 151BCDCB26C87DE900F1EA89 /* Copy Sounds */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 7;
+ files = (
+ 151BCDCC26C87E0200F1EA89 /* pop.mp3 in Copy Sounds */,
+ 151BCDCD26C87E0200F1EA89 /* moo.mp3 in Copy Sounds */,
+ 151BCDCE26C87E0200F1EA89 /* frog.mp3 in Copy Sounds */,
+ );
+ name = "Copy Sounds";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 1525B07926BA27B600A504EB /* Copy Services to Bundle */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices";
+ dstSubfolderSpec = 16;
+ files = (
+ 1525B07A26BA27E000A504EB /* KettleCornService in Copy Services to Bundle */,
+ );
+ name = "Copy Services to Bundle";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
/* Begin PBXFileReference section */
+ 151BCD9426C7846000F1EA89 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
+ 151BCD9526C7846000F1EA89 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+ 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = PrefPane.tiff; path = ../../../../../var/folders/zx/4cfp_v_x17ggn7g72zl77sk40000gn/T/632003889/PrefPane.tiff; sourceTree = ""; };
+ 151BCDA226C8566700F1EA89 /* KeyPopperCatcher.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = KeyPopperCatcher.plist; sourceTree = ""; };
+ 151BCDA726C86FBF00F1EA89 /* PoppingService */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = PoppingService; sourceTree = BUILT_PRODUCTS_DIR; };
+ 151BCDA926C86FBF00F1EA89 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
+ 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingServiceDelegate.swift; sourceTree = ""; };
+ 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingServiceProtocol.swift; sourceTree = ""; };
+ 151BCDB226C8701100F1EA89 /* PoppingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingService.swift; sourceTree = ""; };
+ 151BCDB426C870A200F1EA89 /* PoppingService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PoppingService.entitlements; sourceTree = ""; };
+ 151BCDB926C8711000F1EA89 /* pop.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = pop.mp3; sourceTree = ""; };
+ 151BCDBC26C873B600F1EA89 /* moo.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = moo.mp3; sourceTree = ""; };
+ 151BCDBE26C874C900F1EA89 /* frog.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = frog.mp3; sourceTree = ""; };
+ 151BCDC026C874DB00F1EA89 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
+ 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFAudio.framework; path = System/Library/Frameworks/AVFAudio.framework; sourceTree = SDKROOT; };
+ 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+ 151BCDC626C8765600F1EA89 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+ 151BCDC926C87BB900F1EA89 /* PoppingService.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = PoppingService.plist; sourceTree = ""; };
+ 1525B06726BA208000A504EB /* KettleCornService */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KettleCornService; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1525B06926BA208000A504EB /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
+ 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornServiceDelegate.swift; sourceTree = ""; };
+ 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornServiceProtocol.swift; sourceTree = ""; };
+ 1525B07226BA22AD00A504EB /* KettleCornService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornService.swift; sourceTree = ""; };
+ 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = KeyPopperPreferencesTerms.searchTerms; sourceTree = ""; };
+ 1542150A26C05E02007E4A08 /* PoppingSounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingSounds.swift; sourceTree = ""; };
+ 1542150D26C06836007E4A08 /* KettleCornSerivce.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = KettleCornSerivce.plist; sourceTree = ""; };
+ 1542150F26C0FB37007E4A08 /* KettleCornService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = KettleCornService.entitlements; sourceTree = ""; };
1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "KeyPopper PrefPane.prefPane"; sourceTree = BUILT_PRODUCTS_DIR; };
- 1587085726B89CC50082DB8F /* PrefPane.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = PrefPane.tiff; sourceTree = ""; };
1587085A26B89CC50082DB8F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/KeyPopper.xib; sourceTree = ""; };
1587085C26B89CC50082DB8F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPopperPrefPane.swift; sourceTree = ""; };
+ 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "KeyPopper Catcher.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 15E014B126C7749100A432BD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 15E014B526C7749A00A432BD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 15E014B826C7749A00A432BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 15E014BD26C7750100A432BD /* KeyPopper Catcher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "KeyPopper Catcher.entitlements"; sourceTree = ""; };
+ 15E014BE26C7784600A432BD /* KeyPopper-Catcher-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "KeyPopper-Catcher-Info.plist"; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 151BCD9326C7844A00F1EA89 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 151BCDA426C86FBF00F1EA89 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 151BCDC326C874DB00F1EA89 /* AVKit.framework in Frameworks */,
+ 151BCDC726C8765600F1EA89 /* AppKit.framework in Frameworks */,
+ 151BCDC426C874DB00F1EA89 /* AVFAudio.framework in Frameworks */,
+ 151BCDC526C874DB00F1EA89 /* AVFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 1525B06426BA208000A504EB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
1587084E26B89CC50082DB8F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -31,33 +188,97 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 1587083026B89C710082DB8F = {
+ 151BCDA826C86FBF00F1EA89 /* PoppingService */ = {
isa = PBXGroup;
children = (
- 1587085226B89CC50082DB8F /* PrefPane */,
- 15F9C8D326B8BCC300BF23AA /* Products */,
+ 151BCDB426C870A200F1EA89 /* PoppingService.entitlements */,
+ 151BCDA926C86FBF00F1EA89 /* main.swift */,
+ 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */,
+ 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */,
+ 151BCDB226C8701100F1EA89 /* PoppingService.swift */,
+ 151BCDB926C8711000F1EA89 /* pop.mp3 */,
+ 151BCDBC26C873B600F1EA89 /* moo.mp3 */,
+ 151BCDBE26C874C900F1EA89 /* frog.mp3 */,
+ 151BCDC926C87BB900F1EA89 /* PoppingService.plist */,
);
+ path = PoppingService;
sourceTree = "";
};
- 15F9C8D326B8BCC300BF23AA /* Products */ = {
+ 1525B06826BA208000A504EB /* KettleCornService */ = {
isa = PBXGroup;
children = (
- 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */,
+ 1542150F26C0FB37007E4A08 /* KettleCornService.entitlements */,
+ 1542150D26C06836007E4A08 /* KettleCornSerivce.plist */,
+ 1525B06926BA208000A504EB /* main.swift */,
+ 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */,
+ 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */,
+ 1525B07226BA22AD00A504EB /* KettleCornService.swift */,
+ );
+ path = KettleCornService;
+ sourceTree = "";
+ };
+ 1587083026B89C710082DB8F = {
+ isa = PBXGroup;
+ children = (
+ 1587085226B89CC50082DB8F /* PrefPane */,
+ 15E014B026C7749100A432BD /* KeyPopper Catcher */,
+ 1525B06826BA208000A504EB /* KettleCornService */,
+ 151BCDA826C86FBF00F1EA89 /* PoppingService */,
+ 15F9C8D326B8BCC300BF23AA /* Products */,
+ 15E014C026C77EF000A432BD /* Frameworks */,
);
- name = Products;
sourceTree = "";
};
1587085226B89CC50082DB8F /* PrefPane */ = {
isa = PBXGroup;
children = (
1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */,
- 1587085726B89CC50082DB8F /* PrefPane.tiff */,
+ 1542150A26C05E02007E4A08 /* PoppingSounds.swift */,
+ 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */,
1587085926B89CC50082DB8F /* KeyPopper.xib */,
1587085C26B89CC50082DB8F /* Info.plist */,
+ 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */,
);
path = PrefPane;
sourceTree = "";
};
+ 15E014B026C7749100A432BD /* KeyPopper Catcher */ = {
+ isa = PBXGroup;
+ children = (
+ 15E014BE26C7784600A432BD /* KeyPopper-Catcher-Info.plist */,
+ 151BCDA226C8566700F1EA89 /* KeyPopperCatcher.plist */,
+ 15E014BD26C7750100A432BD /* KeyPopper Catcher.entitlements */,
+ 15E014B126C7749100A432BD /* AppDelegate.swift */,
+ 15E014B526C7749A00A432BD /* Assets.xcassets */,
+ 15E014B726C7749A00A432BD /* Main.storyboard */,
+ );
+ path = "KeyPopper Catcher";
+ sourceTree = "";
+ };
+ 15E014C026C77EF000A432BD /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 151BCDC626C8765600F1EA89 /* AppKit.framework */,
+ 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */,
+ 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */,
+ 151BCDC026C874DB00F1EA89 /* AVKit.framework */,
+ 151BCD9526C7846000F1EA89 /* CoreFoundation.framework */,
+ 151BCD9426C7846000F1EA89 /* CoreServices.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 15F9C8D326B8BCC300BF23AA /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */,
+ 1525B06726BA208000A504EB /* KettleCornService */,
+ 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */,
+ 151BCDA726C86FBF00F1EA89 /* PoppingService */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -71,6 +292,38 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
+ 151BCDA626C86FBF00F1EA89 /* PoppingService */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 151BCDAB26C86FBF00F1EA89 /* Build configuration list for PBXNativeTarget "PoppingService" */;
+ buildPhases = (
+ 151BCDA326C86FBF00F1EA89 /* Sources */,
+ 151BCDA426C86FBF00F1EA89 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PoppingService;
+ productName = PoppingService;
+ productReference = 151BCDA726C86FBF00F1EA89 /* PoppingService */;
+ productType = "com.apple.product-type.tool";
+ };
+ 1525B06626BA208000A504EB /* KettleCornService */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1525B06B26BA208000A504EB /* Build configuration list for PBXNativeTarget "KettleCornService" */;
+ buildPhases = (
+ 1525B06326BA208000A504EB /* Sources */,
+ 1525B06426BA208000A504EB /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KettleCornService;
+ productName = KettleCornService;
+ productReference = 1525B06726BA208000A504EB /* KettleCornService */;
+ productType = "com.apple.product-type.tool";
+ };
1587085026B89CC50082DB8F /* KeyPopper PrefPane */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1587085D26B89CC50082DB8F /* Build configuration list for PBXNativeTarget "KeyPopper PrefPane" */;
@@ -79,16 +332,40 @@
1587084D26B89CC50082DB8F /* Sources */,
1587084E26B89CC50082DB8F /* Frameworks */,
1587084F26B89CC50082DB8F /* Resources */,
+ 1525B07926BA27B600A504EB /* Copy Services to Bundle */,
+ 151BCD9826C8484200F1EA89 /* Copy Catcher */,
+ 151BCDB726C870C600F1EA89 /* Copy PoppingService */,
+ 151BCDCB26C87DE900F1EA89 /* Copy Sounds */,
);
buildRules = (
);
dependencies = (
+ 151BCDB626C870BB00F1EA89 /* PBXTargetDependency */,
+ 151BCD9B26C8485F00F1EA89 /* PBXTargetDependency */,
+ 1525B07726BA270600A504EB /* PBXTargetDependency */,
);
name = "KeyPopper PrefPane";
productName = PrefPane;
productReference = 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */;
productType = "com.apple.product-type.bundle";
};
+ 15E014AE26C7749100A432BD /* KeyPopper Catcher */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 15E014BA26C7749A00A432BD /* Build configuration list for PBXNativeTarget "KeyPopper Catcher" */;
+ buildPhases = (
+ 15E014AB26C7749100A432BD /* Sources */,
+ 151BCD9326C7844A00F1EA89 /* Frameworks */,
+ 15E014AD26C7749100A432BD /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "KeyPopper Catcher";
+ productName = "KeyPopper Catcher";
+ productReference = 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -96,12 +373,22 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1300;
LastUpgradeCheck = 1300;
TargetAttributes = {
+ 151BCDA626C86FBF00F1EA89 = {
+ CreatedOnToolsVersion = 13.0;
+ };
+ 1525B06626BA208000A504EB = {
+ CreatedOnToolsVersion = 13.0;
+ };
1587085026B89CC50082DB8F = {
CreatedOnToolsVersion = 13.0;
LastSwiftMigration = 1300;
};
+ 15E014AE26C7749100A432BD = {
+ CreatedOnToolsVersion = 13.0;
+ };
};
};
buildConfigurationList = 1587083426B89C720082DB8F /* Build configuration list for PBXProject "KeyPopper" */;
@@ -113,11 +400,13 @@
Base,
);
mainGroup = 1587083026B89C710082DB8F;
- productRefGroup = 1587083B26B89C720082DB8F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
1587085026B89CC50082DB8F /* KeyPopper PrefPane */,
+ 15E014AE26C7749100A432BD /* KeyPopper Catcher */,
+ 1525B06626BA208000A504EB /* KettleCornService */,
+ 151BCDA626C86FBF00F1EA89 /* PoppingService */,
);
};
/* End PBXProject section */
@@ -127,24 +416,87 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 154214B626BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms in Resources */,
1587085B26B89CC50082DB8F /* KeyPopper.xib in Resources */,
- 1587085826B89CC50082DB8F /* PrefPane.tiff in Resources */,
+ 151BCD9E26C853E800F1EA89 /* PrefPane.tiff in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 15E014AD26C7749100A432BD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 15E014B626C7749A00A432BD /* Assets.xcassets in Resources */,
+ 15E014B926C7749A00A432BD /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 151BCDA326C86FBF00F1EA89 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 151BCDAF26C86FFD00F1EA89 /* PoppingServiceDelegate.swift in Sources */,
+ 151BCDB326C8701100F1EA89 /* PoppingService.swift in Sources */,
+ 151BCDB126C8700800F1EA89 /* PoppingServiceProtocol.swift in Sources */,
+ 151BCDAA26C86FBF00F1EA89 /* main.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 1525B06326BA208000A504EB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1525B07126BA227700A504EB /* KettleCornServiceProtocol.swift in Sources */,
+ 151BCDC826C8771E00F1EA89 /* PoppingServiceProtocol.swift in Sources */,
+ 1542150C26C05E02007E4A08 /* PoppingSounds.swift in Sources */,
+ 1525B06A26BA208000A504EB /* main.swift in Sources */,
+ 1525B07326BA22AD00A504EB /* KettleCornService.swift in Sources */,
+ 1525B06F26BA21FF00A504EB /* KettleCornServiceDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
1587084D26B89CC50082DB8F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1542150E26C068FF007E4A08 /* KettleCornServiceProtocol.swift in Sources */,
1587086226B8A04B0082DB8F /* KeyPopperPrefPane.swift in Sources */,
+ 1542150B26C05E02007E4A08 /* PoppingSounds.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 15E014AB26C7749100A432BD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 15E014BF26C77BAC00A432BD /* KettleCornServiceProtocol.swift in Sources */,
+ 15E014B226C7749100A432BD /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXTargetDependency section */
+ 151BCD9B26C8485F00F1EA89 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 15E014AE26C7749100A432BD /* KeyPopper Catcher */;
+ targetProxy = 151BCD9A26C8485F00F1EA89 /* PBXContainerItemProxy */;
+ };
+ 151BCDB626C870BB00F1EA89 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 151BCDA626C86FBF00F1EA89 /* PoppingService */;
+ targetProxy = 151BCDB526C870BB00F1EA89 /* PBXContainerItemProxy */;
+ };
+ 1525B07726BA270600A504EB /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 1525B06626BA208000A504EB /* KettleCornService */;
+ targetProxy = 1525B07626BA270600A504EB /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
/* Begin PBXVariantGroup section */
1587085926B89CC50082DB8F /* KeyPopper.xib */ = {
isa = PBXVariantGroup;
@@ -154,9 +506,81 @@
name = KeyPopper.xib;
sourceTree = "";
};
+ 15E014B726C7749A00A432BD /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 15E014B826C7749A00A432BD /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
+ 151BCDAC26C86FBF00F1EA89 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = PoppingService/PoppingService.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_HARDENED_RUNTIME = YES;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PoppingService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 151BCDAD26C86FBF00F1EA89 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = PoppingService/PoppingService.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_HARDENED_RUNTIME = YES;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PoppingService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 1525B06C26BA208000A504EB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = KettleCornService/KettleCornService.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_HARDENED_RUNTIME = YES;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.KettleCornService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 1525B06D26BA208000A504EB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = KettleCornService/KettleCornService.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_HARDENED_RUNTIME = YES;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.KettleCornService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
1587084726B89C720082DB8F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -208,7 +632,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.15;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@@ -261,7 +685,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.15;
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
@@ -289,6 +713,7 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PrefPane;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -322,6 +747,7 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PrefPane;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -333,9 +759,115 @@
};
name = Release;
};
+ 15E014BB26C7749A00A432BD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "KeyPopper Catcher/KeyPopper Catcher.entitlements";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_USER_SELECTED_FILES = readonly;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "KeyPopper-Catcher-Info.plist";
+ INFOPLIST_KEY_CFBundleExecutable = "KeyPopper Catcher";
+ INFOPLIST_KEY_CFBundleName = "KeyPopper Catcher";
+ INFOPLIST_KEY_CFBundleVersion = 1;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INFOPLIST_KEY_NSMainStoryboardFile = Main;
+ INFOPLIST_KEY_NSPrincipalClass = NSApplication;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/usr/lib/system",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(SDKROOT)/usr/lib/log",
+ "$(SDKROOT)/usr/lib/updaters",
+ "$(SDKROOT)/usr/lib/system/introspection",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "sh.linus.keypopper.KeyPopper-Catcher";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 15E014BC26C7749A00A432BD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "KeyPopper Catcher/KeyPopper Catcher.entitlements";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_USER_SELECTED_FILES = readonly;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "KeyPopper-Catcher-Info.plist";
+ INFOPLIST_KEY_CFBundleExecutable = "KeyPopper Catcher";
+ INFOPLIST_KEY_CFBundleName = "KeyPopper Catcher";
+ INFOPLIST_KEY_CFBundleVersion = 1;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INFOPLIST_KEY_NSMainStoryboardFile = Main;
+ INFOPLIST_KEY_NSPrincipalClass = NSApplication;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/usr/lib/system",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(SDKROOT)/usr/lib/log",
+ "$(SDKROOT)/usr/lib/updaters",
+ "$(SDKROOT)/usr/lib/system/introspection",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "sh.linus.keypopper.KeyPopper-Catcher";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ 151BCDAB26C86FBF00F1EA89 /* Build configuration list for PBXNativeTarget "PoppingService" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 151BCDAC26C86FBF00F1EA89 /* Debug */,
+ 151BCDAD26C86FBF00F1EA89 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1525B06B26BA208000A504EB /* Build configuration list for PBXNativeTarget "KettleCornService" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1525B06C26BA208000A504EB /* Debug */,
+ 1525B06D26BA208000A504EB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
1587083426B89C720082DB8F /* Build configuration list for PBXProject "KeyPopper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -354,6 +886,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 15E014BA26C7749A00A432BD /* Build configuration list for PBXNativeTarget "KeyPopper Catcher" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 15E014BB26C7749A00A432BD /* Debug */,
+ 15E014BC26C7749A00A432BD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 1587083126B89C720082DB8F /* Project object */;
diff --git a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme
new file mode 100644
index 0000000..7833205
--- /dev/null
+++ b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme
index cb7284a..e4d5ad0 100644
--- a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme
+++ b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme
@@ -40,6 +40,15 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PoppingService/PoppingService.entitlements b/PoppingService/PoppingService.entitlements
new file mode 100644
index 0000000..49ad0bb
--- /dev/null
+++ b/PoppingService/PoppingService.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.automation.apple-events
+
+
+
diff --git a/PoppingService/PoppingService.plist b/PoppingService/PoppingService.plist
new file mode 100644
index 0000000..e155310
--- /dev/null
+++ b/PoppingService/PoppingService.plist
@@ -0,0 +1,15 @@
+
+
+
+
+ Label
+ sh.linus.keypopper.PoppingService
+ Program
+ /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/Java/PoppingService
+ MachServices
+
+ sh.linus.keypopper.PoppingService.mach
+
+
+
+
diff --git a/PoppingService/PoppingService.swift b/PoppingService/PoppingService.swift
new file mode 100644
index 0000000..dec8eea
--- /dev/null
+++ b/PoppingService/PoppingService.swift
@@ -0,0 +1,50 @@
+//
+// PoppingService.swift
+// PoppingService
+//
+// Created by Linus Skucas on 8/14/21.
+//
+
+import Foundation
+import AVFoundation
+
+@objc class PoppingService: NSObject, PoppingServiceProtocol {
+ var popSound: AVAudioPlayer!
+ var frogSound: AVAudioPlayer!
+ var mooSound: AVAudioPlayer!
+
+ override init() {
+ super.init()
+ let poppingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/pop.mp3")
+ let mooingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/moo.mp3")
+ let frogingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/frog.mp3")
+
+ popSound = try! AVAudioPlayer(contentsOf: poppingURL)
+ popSound.volume = 1.00
+ popSound.prepareToPlay()
+ mooSound = try! AVAudioPlayer(contentsOf: mooingURL)
+ mooSound.volume = 1.00
+ mooSound.prepareToPlay()
+ frogSound = try! AVAudioPlayer(contentsOf: frogingURL)
+ frogSound.volume = 1.00
+ frogSound.prepareToPlay()
+ }
+
+ func pop() {
+ DispatchQueue.main.async {
+ self.popSound.play()
+ }
+ }
+
+ func frog() {
+ DispatchQueue.main.async {
+ self.frogSound.play()
+ }
+ }
+
+ func moo() {
+ DispatchQueue.main.async {
+ self.mooSound.play()
+ }
+ }
+}
diff --git a/PoppingService/PoppingServiceDelegate.swift b/PoppingService/PoppingServiceDelegate.swift
new file mode 100644
index 0000000..3d4a10a
--- /dev/null
+++ b/PoppingService/PoppingServiceDelegate.swift
@@ -0,0 +1,19 @@
+//
+// PoppingServiceDelegate.swift
+// PoppingService
+//
+// Created by Linus Skucas on 8/14/21.
+//
+
+import Foundation
+
+class PoppingServiceDelegate: NSObject, NSXPCListenerDelegate {
+ func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
+ let exportedObject = PoppingService()
+ newConnection.exportedInterface = NSXPCInterface(with: PoppingServiceProtocol.self)
+ newConnection.exportedObject = exportedObject
+
+ newConnection.resume()
+ return true
+ }
+}
diff --git a/PoppingService/PoppingServiceProtocol.swift b/PoppingService/PoppingServiceProtocol.swift
new file mode 100644
index 0000000..c4874b1
--- /dev/null
+++ b/PoppingService/PoppingServiceProtocol.swift
@@ -0,0 +1,14 @@
+//
+// PoppingServiceProtocol.swift
+// PoppingService
+//
+// Created by Linus Skucas on 8/14/21.
+//
+
+import Foundation
+
+@objc(PoppingService) protocol PoppingServiceProtocol {
+ func pop()
+ func frog()
+ func moo()
+}
diff --git a/PoppingService/frog.mp3 b/PoppingService/frog.mp3
new file mode 100644
index 0000000..abf2d78
Binary files /dev/null and b/PoppingService/frog.mp3 differ
diff --git a/PoppingService/main.swift b/PoppingService/main.swift
new file mode 100644
index 0000000..5dcd855
--- /dev/null
+++ b/PoppingService/main.swift
@@ -0,0 +1,14 @@
+//
+// main.swift
+// PoppingService
+//
+// Created by Linus Skucas on 8/14/21.
+//
+
+import Foundation
+
+let delegate = PoppingServiceDelegate()
+let listener = NSXPCListener(machServiceName: "sh.linus.keypopper.PoppingService.mach")
+listener.delegate = delegate
+listener.resume()
+RunLoop.main.run()
diff --git a/PoppingService/moo.mp3 b/PoppingService/moo.mp3
new file mode 100644
index 0000000..b84c7a8
Binary files /dev/null and b/PoppingService/moo.mp3 differ
diff --git a/PoppingService/pop.mp3 b/PoppingService/pop.mp3
new file mode 100644
index 0000000..0824577
Binary files /dev/null and b/PoppingService/pop.mp3 differ
diff --git a/PrefPane/Info.plist b/PrefPane/Info.plist
index c47e554..bca694a 100644
--- a/PrefPane/Info.plist
+++ b/PrefPane/Info.plist
@@ -2,11 +2,15 @@
+ NSPrefPaneAllowsXAppleSystemPreferencesURLScheme
+
CFBundleName
KeyPopper
NSPrefPaneIconFile
PrefPane.tiff
NSPrefPaneIconLabel
KeyPopper
+ NSPrefPaneSearchParameters
+ KeyPopperPreferencesTerms
diff --git a/PrefPane/KeyPopperPrefPane.swift b/PrefPane/KeyPopperPrefPane.swift
index 361765b..c745d2a 100644
--- a/PrefPane/KeyPopperPrefPane.swift
+++ b/PrefPane/KeyPopperPrefPane.swift
@@ -7,9 +7,90 @@
import Foundation
import PreferencePanes
+import SwiftUI
+import AppKit
+
+struct KettleCommunication {
+ static let shared = KettleCommunication()
+ var service: KettleCornServiceProtocol!
+
+ init() {
+ let connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach")
+ connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self)
+ connection.resume()
+
+ service = connection.remoteObjectProxyWithErrorHandler { error in
+ fatalError("Error: \(error.localizedDescription)")
+ } as! KettleCornServiceProtocol
+ }
+}
+
+struct KeyPopperPrefPaneView: View {
+ let communication = KettleCommunication.shared
+ @AppStorage("enabled", store: UserDefaults.init(suiteName: "sh.linus.keypopper")!) var enabled: Bool = false
+ @State var sound: PoppingSounds = .pop
+ @AppStorage("sound", store: UserDefaults.init(suiteName: "sh.linus.keypopper")!) var soundInt: Int = 0
+
+ var body: some View {
+ Group {
+ Group {
+ Form {
+ Picker(selection: $sound, label:
+ VStack(alignment: .trailing, spacing: 2) {
+ Text("Sound")
+ Image(nsImage: NSImage(named: NSImage.Name("NXHelpIndex"))!)
+ }, content: {
+ Text("Popping")
+ .tag(PoppingSounds.pop)
+ Text("Mooing")
+ .tag(PoppingSounds.moo)
+ Text("Frog Thingying")
+ .tag(PoppingSounds.frog)
+ })
+ .pickerStyle(.radioGroup)
+ .padding(.top)
+ .onChange(of: sound) { newValue in
+ soundInt = newValue.rawValue
+ communication.service.changeSoundTo(newValue.rawValue)
+ }
+ .onAppear {
+ sound = PoppingSounds(rawValue: soundInt)!
+ }
+
+ Toggle(isOn: $enabled) {
+ HStack {
+ Text("Enable Sounds")
+ Image(nsImage: NSImage(named: NSImage.Name("NXFollow"))!)
+ .resizable()
+ .frame(width: 30, height: 30, alignment: .center)
+ }
+ }
+ .toggleStyle(.switch)
+ .onChange(of: enabled) { newValue in
+ communication.service.changeSoundState(shouldPlaySound: newValue)
+ }
+ }
+
+ GroupBox {
+ HStack(alignment: .center) {
+ Image(nsImage: NSImage(named: NSImage.Name("NSSecurity"))!)
+ .resizable()
+ .scaledToFit()
+ Text("KeyPopper does not record or send your keystrokes anywhere.")
+ }
+ }
+ .padding(.bottom)
+ }
+ .frame(width: 480)
+ }
+ .frame(width: 500, height: 200)
+ }
+}
+
class KeyPopperPrefPane: NSPreferencePane {
override func mainViewDidLoad() {
-
+ let keyView = KeyPopperPrefPaneView()
+ self.mainView = NSHostingView(rootView: keyView)
}
}
diff --git a/PrefPane/KeyPopperPreferencesTerms.searchTerms b/PrefPane/KeyPopperPreferencesTerms.searchTerms
new file mode 100644
index 0000000..6233974
--- /dev/null
+++ b/PrefPane/KeyPopperPreferencesTerms.searchTerms
@@ -0,0 +1,35 @@
+
+
+
+
+ KeyPopper
+
+ localizableStrings
+
+
+ comments
+ Localizable index words
+ index
+ keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, popping, mooing, frog, froggying, frog thingying, enable
+ title
+ KeyPopper
+
+ comments
+ Localizable index words
+ index
+ keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, enable
+ title
+ Enable KeyPopper Sounds
+
+
+ comments
+ Localizable index words
+ index
+ keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, popping, mooing, frog, froggying, frog thingying, enable
+ title
+ Change KeyPopper Sound
+
+
+
+
+
diff --git a/PrefPane/PoppingSounds.swift b/PrefPane/PoppingSounds.swift
new file mode 100644
index 0000000..5400748
--- /dev/null
+++ b/PrefPane/PoppingSounds.swift
@@ -0,0 +1,17 @@
+//
+// PoppingSounds.swift
+// KeyPopper
+//
+// Created by Linus Skucas on 8/8/21.
+//
+
+import Foundation
+
+@objc enum PoppingSounds: Int, Identifiable {
+ var id: Int {
+ return self.rawValue
+ }
+ case pop = 0
+ case moo = 1
+ case frog = 2
+}
diff --git a/PrefPane/PrefPane.tiff b/PrefPane/PrefPane.tiff
deleted file mode 100644
index e69de29..0000000