[
  {
    "path": ".gitignore",
    "content": "BuildTools/.build\nBuildTools/.swiftpm\nxcuserdata/\n"
  },
  {
    "path": "BuildTools/Empty.swift",
    "content": ""
  },
  {
    "path": "BuildTools/Package.resolved",
    "content": "{\n  \"object\": {\n    \"pins\": [\n      {\n        \"package\": \"SwiftFormat\",\n        \"repositoryURL\": \"https://github.com/nicklockwood/SwiftFormat\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"16e7dd37937af0f9adf7d8cfb35e97146ce1875f\",\n          \"version\": \"0.49.7\"\n        }\n      }\n    ]\n  },\n  \"version\": 1\n}\n"
  },
  {
    "path": "BuildTools/Package.swift",
    "content": "// swift-tools-version:5.1\nimport PackageDescription\n\nlet package = Package(\n    name: \"BuildTools\",\n    platforms: [.macOS(.v10_11)],\n    dependencies: [\n        .package(url: \"https://github.com/nicklockwood/SwiftFormat\", from: \"0.47.12\"),\n    ],\n    targets: [.target(name: \"BuildTools\", path: \"\")]\n)\n"
  },
  {
    "path": "DeskPad/AppDelegate.swift",
    "content": "import Cocoa\nimport ReSwift\n\nenum AppDelegateAction: Action {\n    case didFinishLaunching\n}\n\nclass AppDelegate: NSObject, NSApplicationDelegate {\n    var window: NSWindow!\n\n    func applicationDidFinishLaunching(_: Notification) {\n        let viewController = ScreenViewController()\n        window = NSWindow(contentViewController: viewController)\n        window.delegate = viewController\n        window.title = \"DeskPad\"\n        window.makeKeyAndOrderFront(nil)\n        window.titlebarAppearsTransparent = true\n        window.isMovableByWindowBackground = true\n        window.titleVisibility = .hidden\n        window.backgroundColor = .white\n        window.contentMinSize = CGSize(width: 400, height: 300)\n        window.contentMaxSize = CGSize(width: 5120, height: 2160)\n        window.styleMask.insert(.resizable)\n        window.collectionBehavior.insert(.fullScreenNone)\n\n        let mainMenu = NSMenu()\n        let mainMenuItem = NSMenuItem()\n        let subMenu = NSMenu(title: \"MainMenu\")\n        let quitMenuItem = NSMenuItem(\n            title: \"Quit\",\n            action: #selector(NSApp.terminate),\n            keyEquivalent: \"q\"\n        )\n        subMenu.addItem(quitMenuItem)\n        mainMenuItem.submenu = subMenu\n        mainMenu.items = [mainMenuItem]\n        NSApplication.shared.mainMenu = mainMenu\n\n        store.dispatch(AppDelegateAction.didFinishLaunching)\n    }\n\n    func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {\n        return true\n    }\n}\n"
  },
  {
    "path": "DeskPad/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DeskPad/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Icon-16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"Icon-32.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"Icon-33.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"Icon-64.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"Icon-128.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"Icon-256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"Icon-257.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"Icon-512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"Icon-513.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"512x512\"\n    },\n    {\n      \"filename\" : \"Icon-1024.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"512x512\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DeskPad/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DeskPad/Assets.xcassets/TitleBarActive.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"color\" : {\n        \"platform\" : \"osx\",\n        \"reference\" : \"selectedContentBackgroundColor\"\n      },\n      \"idiom\" : \"universal\"\n    },\n    {\n      \"appearances\" : [\n        {\n          \"appearance\" : \"luminosity\",\n          \"value\" : \"dark\"\n        }\n      ],\n      \"color\" : {\n        \"platform\" : \"osx\",\n        \"reference\" : \"selectedContentBackgroundColor\"\n      },\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DeskPad/Assets.xcassets/TitleBarInactive.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"color\" : {\n        \"platform\" : \"osx\",\n        \"reference\" : \"windowBackgroundColor\"\n      },\n      \"idiom\" : \"universal\"\n    },\n    {\n      \"appearances\" : [\n        {\n          \"appearance\" : \"luminosity\",\n          \"value\" : \"dark\"\n        }\n      ],\n      \"color\" : {\n        \"platform\" : \"osx\",\n        \"reference\" : \"windowBackgroundColor\"\n      },\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DeskPad/Backend/AppState.swift",
    "content": "import ReSwift\n\nstruct AppState: Equatable {\n    let mouseLocationState: MouseLocationState\n    let screenConfigurationState: ScreenConfigurationState\n\n    static var initialState: AppState {\n        return AppState(\n            mouseLocationState: .initialState,\n            screenConfigurationState: .initialState\n        )\n    }\n}\n\nfunc appReducer(action: Action, state: AppState?) -> AppState {\n    let state = state ?? .initialState\n\n    return AppState(\n        mouseLocationState: mouseLocationReducer(action: action, state: state.mouseLocationState),\n        screenConfigurationState: screenConfigurationReducer(action: action, state: state.screenConfigurationState)\n    )\n}\n"
  },
  {
    "path": "DeskPad/Backend/MouseLocation/MouseLocationSideEffect.swift",
    "content": "import Foundation\nimport ReSwift\n\nprivate var timer: Timer?\n\nenum MouseLocationAction: Action {\n    case located(isWithinScreen: Bool)\n    case requestMove(toPoint: NSPoint)\n}\n\nfunc mouseLocationSideEffect() -> SideEffect {\n    return { action, dispatch, getState in\n        if timer == nil {\n            timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { _ in\n                let mouseLocation = NSEvent.mouseLocation\n                let screens = NSScreen.screens\n                let screenContainingMouse = (screens.first { NSMouseInRect(mouseLocation, $0.frame, false) })\n                let isWithinScreen = screenContainingMouse?.displayID == getState()?.screenConfigurationState.displayID\n                dispatch(MouseLocationAction.located(isWithinScreen: isWithinScreen))\n            }\n        }\n        switch action {\n        case let MouseLocationAction.requestMove(point):\n            guard let displayID = getState()?.screenConfigurationState.displayID else {\n                return\n            }\n            CGDisplayMoveCursorToPoint(displayID, point)\n        default:\n            return\n        }\n    }\n}\n"
  },
  {
    "path": "DeskPad/Backend/MouseLocation/MouseLocationState.swift",
    "content": "import Foundation\nimport ReSwift\n\nstruct MouseLocationState: Equatable {\n    let isWithinScreen: Bool\n\n    static var initialState: MouseLocationState {\n        return MouseLocationState(isWithinScreen: false)\n    }\n}\n\nfunc mouseLocationReducer(action: Action, state: MouseLocationState) -> MouseLocationState {\n    switch action {\n    case let MouseLocationAction.located(isWithinScreen):\n        return MouseLocationState(isWithinScreen: isWithinScreen)\n\n    default:\n        return state\n    }\n}\n"
  },
  {
    "path": "DeskPad/Backend/ScreenConfiguration/ScreenConfigurationSideEffect.swift",
    "content": "import Foundation\nimport ReSwift\n\nprivate var isObserving = false\n\nenum ScreenConfigurationAction: Action {\n    case set(resolution: CGSize, scaleFactor: CGFloat)\n}\n\nfunc screenConfigurationSideEffect() -> SideEffect {\n    return { _, dispatch, getState in\n        if isObserving == false {\n            isObserving = true\n            NotificationCenter.default.addObserver(\n                forName: NSApplication.didChangeScreenParametersNotification,\n                object: NSApplication.shared,\n                queue: .main\n            ) { _ in\n                guard let screen = NSScreen.screens.first(where: {\n                    $0.displayID == getState()?.screenConfigurationState.displayID\n                }) else {\n                    return\n                }\n                dispatch(ScreenConfigurationAction.set(\n                    resolution: screen.frame.size,\n                    scaleFactor: screen.backingScaleFactor\n                ))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "DeskPad/Backend/ScreenConfiguration/ScreenConfigurationState.swift",
    "content": "import Foundation\nimport ReSwift\n\nstruct ScreenConfigurationState: Equatable {\n    let resolution: CGSize\n    let scaleFactor: CGFloat\n    let displayID: CGDirectDisplayID?\n\n    static var initialState: ScreenConfigurationState {\n        return ScreenConfigurationState(\n            resolution: .zero,\n            scaleFactor: 1,\n            displayID: nil\n        )\n    }\n}\n\nfunc screenConfigurationReducer(action: Action, state: ScreenConfigurationState) -> ScreenConfigurationState {\n    switch action {\n    case let ScreenConfigurationAction.set(resolution, scaleFactor):\n        return ScreenConfigurationState(\n            resolution: resolution,\n            scaleFactor: scaleFactor,\n            displayID: state.displayID\n        )\n\n    case let ScreenViewAction.setDisplayID(displayID):\n        return ScreenConfigurationState(\n            resolution: state.resolution,\n            scaleFactor: state.scaleFactor,\n            displayID: displayID\n        )\n\n    default:\n        return state\n    }\n}\n"
  },
  {
    "path": "DeskPad/Backend/SideEffectsMiddleware.swift",
    "content": "import Foundation\nimport ReSwift\n\ntypealias SideEffect = (Action, @escaping DispatchFunction, @escaping () -> AppState?) -> Void\n\nprivate let sideEffects: [SideEffect] = [\n    mouseLocationSideEffect(),\n    screenConfigurationSideEffect(),\n]\n\nlet sideEffectsMiddleware: Middleware<AppState> = { dispatch, getState in\n    { originalDispatch in\n        { action in\n            originalDispatch(action)\n            for sideEffect in sideEffects {\n                sideEffect(action, dispatch, getState)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "DeskPad/Backend/Store.swift",
    "content": "import Foundation\nimport ReSwift\n\nlet store = Store<AppState>(\n    reducer: appReducer,\n    state: AppState.initialState,\n    middleware: [\n        sideEffectsMiddleware,\n    ]\n)\n"
  },
  {
    "path": "DeskPad/CGVirtualDisplayPrivate.h",
    "content": "//\n//  CGVirtualDisplayPrivate.h\n//  VirtualDisplayExp\n//\n//  Created by Khaos Tian on 2/17/21.\n//\n\n#import <Cocoa/Cocoa.h>\n#import <CoreGraphics/CoreGraphics.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class CGVirtualDisplayDescriptor;\n\n@interface CGVirtualDisplayMode : NSObject\n\n@property(readonly, nonatomic) CGFloat refreshRate;\n@property(readonly, nonatomic) NSUInteger width;\n@property(readonly, nonatomic) NSUInteger height;\n\n- (instancetype)initWithWidth:(NSUInteger)arg1 height:(NSUInteger)arg2 refreshRate:(CGFloat)arg3;\n\n@end\n\n@interface CGVirtualDisplaySettings : NSObject\n\n@property(retain, nonatomic) NSArray<CGVirtualDisplayMode *> *modes;\n@property(nonatomic) unsigned int hiDPI;\n\n- (instancetype)init;\n\n@end\n\n@interface CGVirtualDisplay : NSObject\n\n@property(readonly, nonatomic) NSArray *modes; // @synthesize modes=_modes;\n@property(readonly, nonatomic) unsigned int hiDPI; // @synthesize hiDPI=_hiDPI;\n@property(readonly, nonatomic) CGDirectDisplayID displayID; // @synthesize displayID=_displayID;\n@property(readonly, nonatomic) id terminationHandler; // @synthesize terminationHandler=_terminationHandler;\n@property(readonly, nonatomic) dispatch_queue_t queue; // @synthesize queue=_queue;\n@property(readonly, nonatomic) unsigned int maxPixelsHigh; // @synthesize maxPixelsHigh=_maxPixelsHigh;\n@property(readonly, nonatomic) unsigned int maxPixelsWide; // @synthesize maxPixelsWide=_maxPixelsWide;\n@property(readonly, nonatomic) CGSize sizeInMillimeters; // @synthesize sizeInMillimeters=_sizeInMillimeters;\n@property(readonly, nonatomic) NSString *name; // @synthesize name=_name;\n@property(readonly, nonatomic) unsigned int serialNum; // @synthesize serialNum=_serialNum;\n@property(readonly, nonatomic) unsigned int productID; // @synthesize productID=_productID;\n@property(readonly, nonatomic) unsigned int vendorID; // @synthesize vendorID=_vendorID;\n\n- (instancetype)initWithDescriptor:(CGVirtualDisplayDescriptor *)arg1;\n- (BOOL)applySettings:(CGVirtualDisplaySettings *)arg1;\n\n@end\n\n@interface CGVirtualDisplayDescriptor : NSObject\n\n@property(retain, nonatomic) dispatch_queue_t queue; // @synthesize queue=_queue;\n@property(retain, nonatomic) NSString *name; // @synthesize name=_name;\n@property(nonatomic) unsigned int maxPixelsHigh; // @synthesize maxPixelsHigh=_maxPixelsHigh;\n@property(nonatomic) unsigned int maxPixelsWide; // @synthesize maxPixelsWide=_maxPixelsWide;\n@property(nonatomic) CGSize sizeInMillimeters; // @synthesize sizeInMillimeters=_sizeInMillimeters;\n@property(nonatomic) unsigned int serialNum; // @synthesize serialNum=_serialNum;\n@property(nonatomic) unsigned int productID; // @synthesize productID=_productID;\n@property(nonatomic) unsigned int vendorID; // @synthesize vendorID=_vendorID;\n@property(copy, nonatomic) void (^terminationHandler)(id, CGVirtualDisplay*);\n\n- (instancetype)init;\n- (nullable dispatch_queue_t)dispatchQueue;\n- (void)setDispatchQueue:(dispatch_queue_t)arg1;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "DeskPad/DeskPad-Bridging-Header.h",
    "content": "#import \"CGVirtualDisplayPrivate.h\"\n"
  },
  {
    "path": "DeskPad/DeskPad.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.app-sandbox</key>\n\t<true/>\n\t<key>com.apple.security.files.user-selected.read-only</key>\n\t<true/>\n\t<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>\n\t<array>\n\t\t<string>com.apple.VirtualDisplay</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "DeskPad/Frontend/Screen/ScreenViewController.swift",
    "content": "import Cocoa\nimport ReSwift\n\nenum ScreenViewAction: Action {\n    case setDisplayID(CGDirectDisplayID)\n}\n\nclass ScreenViewController: SubscriberViewController<ScreenViewData>, NSWindowDelegate {\n    override func loadView() {\n        view = NSView()\n        view.wantsLayer = true\n        view.addGestureRecognizer(NSClickGestureRecognizer(target: self, action: #selector(didClickOnScreen)))\n    }\n\n    private var display: CGVirtualDisplay!\n    private var stream: CGDisplayStream?\n    private var isWindowHighlighted = false\n    private var previousResolution: CGSize?\n    private var previousScaleFactor: CGFloat?\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        let descriptor = CGVirtualDisplayDescriptor()\n        descriptor.setDispatchQueue(DispatchQueue.main)\n        descriptor.name = \"DeskPad Display\"\n        descriptor.maxPixelsWide = 5120\n        descriptor.maxPixelsHigh = 2160\n        descriptor.sizeInMillimeters = CGSize(width: 1600, height: 1000)\n        descriptor.productID = 0x1234\n        descriptor.vendorID = 0x3456\n        descriptor.serialNum = 0x0001\n\n        let display = CGVirtualDisplay(descriptor: descriptor)\n        store.dispatch(ScreenViewAction.setDisplayID(display.displayID))\n        self.display = display\n\n        let settings = CGVirtualDisplaySettings()\n        settings.hiDPI = 1\n        settings.modes = [\n            // 32:9\n            CGVirtualDisplayMode(width: 5120, height: 1440, refreshRate: 60),\n            // 21:9 (239:100, 12:5)\n            CGVirtualDisplayMode(width: 5120, height: 2160, refreshRate: 60),\n            CGVirtualDisplayMode(width: 3840, height: 1600, refreshRate: 60),\n            CGVirtualDisplayMode(width: 3440, height: 1440, refreshRate: 60),\n            // 16:9\n            CGVirtualDisplayMode(width: 3840, height: 2160, refreshRate: 60),\n            CGVirtualDisplayMode(width: 2560, height: 1440, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1920, height: 1080, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1600, height: 900, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1366, height: 768, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1280, height: 720, refreshRate: 60),\n            // 16:10\n            CGVirtualDisplayMode(width: 2560, height: 1600, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1920, height: 1200, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1680, height: 1050, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1440, height: 900, refreshRate: 60),\n            CGVirtualDisplayMode(width: 1280, height: 800, refreshRate: 60),\n        ]\n        display.apply(settings)\n    }\n\n    override func update(with viewData: ScreenViewData) {\n        if viewData.isWindowHighlighted != isWindowHighlighted {\n            isWindowHighlighted = viewData.isWindowHighlighted\n            view.window?.backgroundColor = isWindowHighlighted\n                ? NSColor(named: \"TitleBarActive\")\n                : NSColor(named: \"TitleBarInactive\")\n            if isWindowHighlighted {\n                view.window?.orderFrontRegardless()\n            }\n        }\n\n        if\n            viewData.resolution != .zero,\n            viewData.resolution != previousResolution\n            || viewData.scaleFactor != previousScaleFactor\n        {\n            previousResolution = viewData.resolution\n            previousScaleFactor = viewData.scaleFactor\n            stream = nil\n            view.window?.setContentSize(viewData.resolution)\n            view.window?.contentAspectRatio = viewData.resolution\n            view.window?.center()\n            let stream = CGDisplayStream(\n                dispatchQueueDisplay: display.displayID,\n                outputWidth: Int(viewData.resolution.width * viewData.scaleFactor),\n                outputHeight: Int(viewData.resolution.height * viewData.scaleFactor),\n                pixelFormat: 1_111_970_369,\n                properties: [\n                    CGDisplayStream.showCursor: true,\n                ] as CFDictionary,\n                queue: .main,\n                handler: { [weak self] _, _, frameSurface, _ in\n                    if let surface = frameSurface {\n                        self?.view.layer?.contents = surface\n                    }\n                }\n            )\n            self.stream = stream\n            stream?.start()\n        }\n    }\n\n    func windowWillResize(_ window: NSWindow, to frameSize: NSSize) -> NSSize {\n        let snappingOffset: CGFloat = 30\n        let contentSize = window.contentRect(forFrameRect: NSRect(origin: .zero, size: frameSize)).size\n        guard\n            let screenResolution = previousResolution,\n            abs(contentSize.width - screenResolution.width) < snappingOffset\n        else {\n            return frameSize\n        }\n        return window.frameRect(forContentRect: NSRect(origin: .zero, size: screenResolution)).size\n    }\n\n    @objc private func didClickOnScreen(_ gestureRecognizer: NSGestureRecognizer) {\n        guard let screenResolution = previousResolution else {\n            return\n        }\n        let clickedPoint = gestureRecognizer.location(in: view)\n        let onScreenPoint = NSPoint(\n            x: clickedPoint.x / view.frame.width * screenResolution.width,\n            y: (view.frame.height - clickedPoint.y) / view.frame.height * screenResolution.height\n        )\n        store.dispatch(MouseLocationAction.requestMove(toPoint: onScreenPoint))\n    }\n}\n"
  },
  {
    "path": "DeskPad/Frontend/Screen/ScreenViewData.swift",
    "content": "import Foundation\n\nstruct ScreenViewData: ViewDataType {\n    struct StateFragment: Equatable {\n        let mouseLocationState: MouseLocationState\n        let screenConfiguration: ScreenConfigurationState\n    }\n\n    static func fragment(of appState: AppState) -> StateFragment {\n        return StateFragment(\n            mouseLocationState: appState.mouseLocationState,\n            screenConfiguration: appState.screenConfigurationState\n        )\n    }\n\n    let isWindowHighlighted: Bool\n    let resolution: CGSize\n    let scaleFactor: CGFloat\n\n    init(for fragment: StateFragment) {\n        isWindowHighlighted = fragment.mouseLocationState.isWithinScreen\n        resolution = fragment.screenConfiguration.resolution\n        scaleFactor = fragment.screenConfiguration.scaleFactor\n    }\n}\n"
  },
  {
    "path": "DeskPad/Helpers/NSScreen+Extensions.swift",
    "content": "import Foundation\n\nextension NSScreen {\n    var displayID: CGDirectDisplayID {\n        return deviceDescription[NSDeviceDescriptionKey(rawValue: \"NSScreenNumber\")] as! CGDirectDisplayID\n    }\n}\n"
  },
  {
    "path": "DeskPad/SubscriberViewController.swift",
    "content": "import AppKit\nimport ReSwift\n\nclass SubscriberViewController<ViewData: ViewDataType>: NSViewController, StoreSubscriber {\n    typealias StoreSubscriberStateType = ViewData.StateFragment\n\n    override func viewWillAppear() {\n        super.viewWillAppear()\n\n        store.subscribe(self) { subscription in\n            subscription\n                .select(ViewData.fragment(of:))\n                .skipRepeats()\n        }\n    }\n\n    override func viewWillDisappear() {\n        super.viewWillDisappear()\n\n        store.unsubscribe(self)\n    }\n\n    func newState(state: ViewData.StateFragment) {\n        DispatchQueue.main.async { [weak self] in\n            self?.update(with: ViewData(for: state))\n        }\n    }\n\n    func update(with _: ViewData) {\n        fatalError(\"Please override the SubscriberViewController update method.\")\n    }\n}\n\nprotocol ViewDataType {\n    associatedtype StateFragment: Equatable\n\n    static func fragment(of appState: AppState) -> StateFragment\n\n    init(for fragment: StateFragment)\n}\n"
  },
  {
    "path": "DeskPad/main.swift",
    "content": "import AppKit\n\nlet app = NSApplication.shared\nlet delegate = AppDelegate()\napp.delegate = delegate\n\n_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)\n"
  },
  {
    "path": "DeskPad.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 55;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t6D2F1482280C1F9200A3A2E5 /* ReSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 6D2F1481280C1F9200A3A2E5 /* ReSwift */; };\n\t\t6D2F1486280C20C800A3A2E5 /* SubscriberViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2F1485280C20C800A3A2E5 /* SubscriberViewController.swift */; };\n\t\t6D2F148A280C20D000A3A2E5 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2F1487280C20D000A3A2E5 /* AppState.swift */; };\n\t\t6D2F148B280C20D000A3A2E5 /* SideEffectsMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2F1488280C20D000A3A2E5 /* SideEffectsMiddleware.swift */; };\n\t\t6D2F148C280C20D000A3A2E5 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2F1489280C20D000A3A2E5 /* Store.swift */; };\n\t\t6D2F148E280C211E00A3A2E5 /* ScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2F148D280C211E00A3A2E5 /* ScreenViewController.swift */; };\n\t\t6D41B09F2879FAB6007CEB2F /* MouseLocationSideEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D41B09E2879FAB6007CEB2F /* MouseLocationSideEffect.swift */; };\n\t\t6D41B0A12879FABE007CEB2F /* MouseLocationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D41B0A02879FABE007CEB2F /* MouseLocationState.swift */; };\n\t\t6D41B0A42879FBA8007CEB2F /* ScreenViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D41B0A32879FBA8007CEB2F /* ScreenViewData.swift */; };\n\t\t6D68E1AF287ABB9900CD574A /* ScreenConfigurationSideEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D68E1AE287ABB9900CD574A /* ScreenConfigurationSideEffect.swift */; };\n\t\t6D68E1B2287ABDB900CD574A /* NSScreen+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D68E1B1287ABDB900CD574A /* NSScreen+Extensions.swift */; };\n\t\t6D68E1B4287ABFC800CD574A /* ScreenConfigurationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D68E1B3287ABFC800CD574A /* ScreenConfigurationState.swift */; };\n\t\t6DC044522801877F00281728 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC044512801877F00281728 /* AppDelegate.swift */; };\n\t\t6DC044562801878100281728 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6DC044552801878100281728 /* Assets.xcassets */; };\n\t\t6DC04461280191EB00281728 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC04460280191EB00281728 /* main.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t6D2F1485280C20C800A3A2E5 /* SubscriberViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriberViewController.swift; sourceTree = \"<group>\"; };\n\t\t6D2F1487280C20D000A3A2E5 /* AppState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = \"<group>\"; };\n\t\t6D2F1488280C20D000A3A2E5 /* SideEffectsMiddleware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideEffectsMiddleware.swift; sourceTree = \"<group>\"; };\n\t\t6D2F1489280C20D000A3A2E5 /* Store.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = \"<group>\"; };\n\t\t6D2F148D280C211E00A3A2E5 /* ScreenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScreenViewController.swift; sourceTree = \"<group>\"; };\n\t\t6D36BEB92801A39200EAB869 /* CGVirtualDisplayPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CGVirtualDisplayPrivate.h; sourceTree = \"<group>\"; };\n\t\t6D36BEBA2801A40600EAB869 /* DeskPad-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"DeskPad-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t6D41B09E2879FAB6007CEB2F /* MouseLocationSideEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MouseLocationSideEffect.swift; sourceTree = \"<group>\"; };\n\t\t6D41B0A02879FABE007CEB2F /* MouseLocationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MouseLocationState.swift; sourceTree = \"<group>\"; };\n\t\t6D41B0A32879FBA8007CEB2F /* ScreenViewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenViewData.swift; sourceTree = \"<group>\"; };\n\t\t6D68E1AE287ABB9900CD574A /* ScreenConfigurationSideEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenConfigurationSideEffect.swift; sourceTree = \"<group>\"; };\n\t\t6D68E1B1287ABDB900CD574A /* NSScreen+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"NSScreen+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\t6D68E1B3287ABFC800CD574A /* ScreenConfigurationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenConfigurationState.swift; sourceTree = \"<group>\"; };\n\t\t6DC0444E2801877F00281728 /* DeskPad.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DeskPad.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6DC044512801877F00281728 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t6DC044552801878100281728 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t6DC0445A2801878100281728 /* DeskPad.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DeskPad.entitlements; sourceTree = \"<group>\"; };\n\t\t6DC04460280191EB00281728 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t6DC0444B2801877F00281728 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6D2F1482280C1F9200A3A2E5 /* ReSwift in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t6D2F1483280C201B00A3A2E5 /* Backend */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D2F1487280C20D000A3A2E5 /* AppState.swift */,\n\t\t\t\t6D2F1488280C20D000A3A2E5 /* SideEffectsMiddleware.swift */,\n\t\t\t\t6D2F1489280C20D000A3A2E5 /* Store.swift */,\n\t\t\t\t6D68E1AD287ABB6F00CD574A /* ScreenConfiguration */,\n\t\t\t\t6D41B09D2879FA87007CEB2F /* MouseLocation */,\n\t\t\t);\n\t\t\tpath = Backend;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6D2F1484280C202700A3A2E5 /* Frontend */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D41B0A22879FB88007CEB2F /* Screen */,\n\t\t\t);\n\t\t\tpath = Frontend;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6D41B09D2879FA87007CEB2F /* MouseLocation */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D41B09E2879FAB6007CEB2F /* MouseLocationSideEffect.swift */,\n\t\t\t\t6D41B0A02879FABE007CEB2F /* MouseLocationState.swift */,\n\t\t\t);\n\t\t\tpath = MouseLocation;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6D41B0A22879FB88007CEB2F /* Screen */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D2F148D280C211E00A3A2E5 /* ScreenViewController.swift */,\n\t\t\t\t6D41B0A32879FBA8007CEB2F /* ScreenViewData.swift */,\n\t\t\t);\n\t\t\tpath = Screen;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6D68E1AD287ABB6F00CD574A /* ScreenConfiguration */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D68E1AE287ABB9900CD574A /* ScreenConfigurationSideEffect.swift */,\n\t\t\t\t6D68E1B3287ABFC800CD574A /* ScreenConfigurationState.swift */,\n\t\t\t);\n\t\t\tpath = ScreenConfiguration;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6D68E1B0287ABDAB00CD574A /* Helpers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D68E1B1287ABDB900CD574A /* NSScreen+Extensions.swift */,\n\t\t\t);\n\t\t\tpath = Helpers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6DC044452801877F00281728 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6DC044502801877F00281728 /* DeskPad */,\n\t\t\t\t6DC0444F2801877F00281728 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6DC0444F2801877F00281728 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6DC0444E2801877F00281728 /* DeskPad.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6DC044502801877F00281728 /* DeskPad */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6DC04460280191EB00281728 /* main.swift */,\n\t\t\t\t6D2F1485280C20C800A3A2E5 /* SubscriberViewController.swift */,\n\t\t\t\t6DC044512801877F00281728 /* AppDelegate.swift */,\n\t\t\t\t6D2F1483280C201B00A3A2E5 /* Backend */,\n\t\t\t\t6D2F1484280C202700A3A2E5 /* Frontend */,\n\t\t\t\t6D68E1B0287ABDAB00CD574A /* Helpers */,\n\t\t\t\t6D36BEBA2801A40600EAB869 /* DeskPad-Bridging-Header.h */,\n\t\t\t\t6D36BEB92801A39200EAB869 /* CGVirtualDisplayPrivate.h */,\n\t\t\t\t6DC044552801878100281728 /* Assets.xcassets */,\n\t\t\t\t6DC0445A2801878100281728 /* DeskPad.entitlements */,\n\t\t\t);\n\t\t\tpath = DeskPad;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t6DC0444D2801877F00281728 /* DeskPad */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6DC0445D2801878100281728 /* Build configuration list for PBXNativeTarget \"DeskPad\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6D2F147F280C1C1400A3A2E5 /* Run SwiftFormat */,\n\t\t\t\t6DC0444A2801877F00281728 /* Sources */,\n\t\t\t\t6DC0444B2801877F00281728 /* Frameworks */,\n\t\t\t\t6DC0444C2801877F00281728 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = DeskPad;\n\t\t\tpackageProductDependencies = (\n\t\t\t\t6D2F1481280C1F9200A3A2E5 /* ReSwift */,\n\t\t\t);\n\t\t\tproductName = DeskPad;\n\t\t\tproductReference = 6DC0444E2801877F00281728 /* DeskPad.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t6DC044462801877F00281728 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = 1;\n\t\t\t\tLastSwiftUpdateCheck = 1320;\n\t\t\t\tLastUpgradeCheck = 1320;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t6DC0444D2801877F00281728 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 13.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 6DC044492801877F00281728 /* Build configuration list for PBXProject \"DeskPad\" */;\n\t\t\tcompatibilityVersion = \"Xcode 13.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 6DC044452801877F00281728;\n\t\t\tpackageReferences = (\n\t\t\t\t6D2F1480280C1F9200A3A2E5 /* XCRemoteSwiftPackageReference \"ReSwift\" */,\n\t\t\t);\n\t\t\tproductRefGroup = 6DC0444F2801877F00281728 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t6DC0444D2801877F00281728 /* DeskPad */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t6DC0444C2801877F00281728 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6DC044562801878100281728 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t6D2F147F280C1C1400A3A2E5 /* Run SwiftFormat */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run SwiftFormat\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"cd BuildTools\\nSDKROOT=(xcrun --sdk macosx --show-sdk-path)\\n#swift package update #Uncomment this line temporarily to update the version used to the latest matching your BuildTools/Package.swift file\\nswift run -c release swiftformat \\\"$SRCROOT\\\" --swiftversion \\\"5\\\"\\n\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t6DC0444A2801877F00281728 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6D68E1B4287ABFC800CD574A /* ScreenConfigurationState.swift in Sources */,\n\t\t\t\t6D68E1B2287ABDB900CD574A /* NSScreen+Extensions.swift in Sources */,\n\t\t\t\t6D2F148C280C20D000A3A2E5 /* Store.swift in Sources */,\n\t\t\t\t6D2F1486280C20C800A3A2E5 /* SubscriberViewController.swift in Sources */,\n\t\t\t\t6D68E1AF287ABB9900CD574A /* ScreenConfigurationSideEffect.swift in Sources */,\n\t\t\t\t6D41B0A12879FABE007CEB2F /* MouseLocationState.swift in Sources */,\n\t\t\t\t6D2F148A280C20D000A3A2E5 /* AppState.swift in Sources */,\n\t\t\t\t6D2F148B280C20D000A3A2E5 /* SideEffectsMiddleware.swift in Sources */,\n\t\t\t\t6D41B09F2879FAB6007CEB2F /* MouseLocationSideEffect.swift in Sources */,\n\t\t\t\t6D41B0A42879FBA8007CEB2F /* ScreenViewData.swift in Sources */,\n\t\t\t\t6D2F148E280C211E00A3A2E5 /* ScreenViewController.swift in Sources */,\n\t\t\t\t6DC044522801877F00281728 /* AppDelegate.swift in Sources */,\n\t\t\t\t6DC04461280191EB00281728 /* main.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t6DC0445B2801878100281728 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 13.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"DeskPad/DeskPad-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6DC0445C2801878100281728 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 13.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"DeskPad/DeskPad-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6DC0445E2801878100281728 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = DeskPad/DeskPad.entitlements;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 6;\n\t\t\t\tDEVELOPMENT_TEAM = TYPC962S4N;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.utilities\";\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.3.2;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.stengo.DeskPad;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6DC0445F2801878100281728 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = DeskPad/DeskPad.entitlements;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 6;\n\t\t\t\tDEVELOPMENT_TEAM = TYPC962S4N;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.utilities\";\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.3.2;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.stengo.DeskPad;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t6DC044492801877F00281728 /* Build configuration list for PBXProject \"DeskPad\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6DC0445B2801878100281728 /* Debug */,\n\t\t\t\t6DC0445C2801878100281728 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6DC0445D2801878100281728 /* Build configuration list for PBXNativeTarget \"DeskPad\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6DC0445E2801878100281728 /* Debug */,\n\t\t\t\t6DC0445F2801878100281728 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\t6D2F1480280C1F9200A3A2E5 /* XCRemoteSwiftPackageReference \"ReSwift\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/ReSwift/ReSwift.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 6.0.0;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\t6D2F1481280C1F9200A3A2E5 /* ReSwift */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 6D2F1480280C1F9200A3A2E5 /* XCRemoteSwiftPackageReference \"ReSwift\" */;\n\t\t\tproductName = ReSwift;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\t};\n\trootObject = 6DC044462801877F00281728 /* Project object */;\n}\n"
  },
  {
    "path": "DeskPad.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "DeskPad.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "DeskPad.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "content": "{\n  \"object\": {\n    \"pins\": [\n      {\n        \"package\": \"ReSwift\",\n        \"repositoryURL\": \"https://github.com/ReSwift/ReSwift.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"96146a29f394ae4c79be025fcec194e5b0d9c3b6\",\n          \"version\": \"6.1.0\"\n        }\n      }\n    ]\n  },\n  \"version\": 1\n}\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2022 Bastian Andelefski\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h3 align=\"center\">\n  <a href=\"https://github.com/Stengo/DeskPad/blob/main/DeskPad/Assets.xcassets/AppIcon.appiconset/Icon-256.png\">\n  <img src=\"https://github.com/Stengo/DeskPad/blob/main/DeskPad/Assets.xcassets/AppIcon.appiconset/Icon-256.png?raw=true\" alt=\"DeskPad Icon\" width=\"128\">\n  </a>\n</h3>\n\n# DeskPad\nA virtual monitor for screen sharing\n\n<h3 align=\"center\">\n  <a href=\"https://github.com/Stengo/DeskPad/blob/main/screenshot.jpg\">\n  <img src=\"https://github.com/Stengo/DeskPad/blob/main/screenshot.jpg?raw=true\" alt=\"DeskPad Screenshot\">\n  </a>\n</h3>\n\nCertain workflows require sharing the entire screen (usually due to switching through multiple applications), but if the presenter has a much larger display than the audience it can be hard to see what is happening.\n\nDeskPad creates a virtual display that is mirrored within its application window so that you can create a dedicated, easily shareable workspace.\n\n# Installation\nYou can either download the [latest release binary](https://github.com/Stengo/DeskPad/releases) or install via [Homebrew](https://brew.sh) by calling `brew install --cask deskpad`.\n\n# Usage\nDeskPad behaves like any other display. Launching the app is equivalent to plugging in a monitor, so macOS will take care of properly arranging your windows to their previous configuration.\n\nYou can change the display resolution through the system preferences and the application window will adjust accordingly.\n\nWhenever you move your mouse cursor to the virtual display, DeskPad will highlight its title bar in blue and move the application window to the front to let you know where you are.\n\n<h3 align=\"center\">\n  <a href=\"https://github.com/Stengo/DeskPad/blob/main/demonstration.gif\">\n  <img src=\"https://github.com/Stengo/DeskPad/blob/main/demonstration.gif?raw=true\" alt=\"DeskPad Demonstration\">\n  </a>\n</h3>\n\n# Troubleshooting\nDeskPad may need screen recording permissions to display properly. Follow these steps:\n\n1. **Open System Settings** → **Privacy & Security** → **Screen Recording**\n2. **Enable DeskPad** by checking the box next to it\n3. **If DeskPad appears but isn't working:**\n   - Uncheck the DeskPad option\n   - Check it again to re-enable\n4. **Restart DeskPad** for changes to take effect\n"
  }
]