[
  {
    "path": ".gitignore",
    "content": "# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n*.xccheckout\n*.moved-aside\nDerivedData\n*.hmap\n*.ipa\n*.xcuserstate\n\nCarthage/Build\nCarthage/Checkouts\n"
  },
  {
    "path": ".travis.yml",
    "content": "osx_image: xcode8.2\nlanguage: objective-c\nxcode_project: Spectacle.xcodeproj\nxcode_scheme: Spectacle\n\nbefore_install:\n  - brew update\n  - brew outdated carthage || brew upgrade carthage\n  - carthage bootstrap --platform Mac\n\nscript:\n  - set -o pipefail && xcodebuild -project Spectacle.xcodeproj -scheme Spectacle test | xcpretty\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nContributions come in many forms. Creating an issue that documents a previously unreported defect is just as important as sending a pull request. Spectacle can only be great when the folks that use it are passionate about its quality.\n\nBefore you start working on your contribution to Spectacle please keep reading. For even more information read [Contributing to Open Source on GitHub][1].\n\n## Issues\n\nBefore creating a new issue check and make sure somebody hasn't already beat you to it. _Please take this time to also review Spectacle's [common issues][2]_. If your defect or feature request doesn't already exist feel free to create a new issue. When creating a new issue take the time to be as clear and descriptive as possible.\n\nHere are a few things to keep in mind when creating an issue for a potential defect:\n\n* What version of Spectacle did you use when encountering the defect?\n* What version of OS X did you use when encountering the defect?\n* Was there any relevant Spectacle output in the [Console][3]?\n\nIncluding screenshots or videos are extremely helpful so please include them if you can. Diagrams can also be highly valuable when describing a new feature in a feature request.\n\n## Pull Requests\n\n1. Fork the repository and create your branch from `master`\n2. Add tests if your changes can and should be tested\n3. Run the test suite and confirm that all tests pass\n4. Rebase your changes on top of the most recent changes from `master`\n\n## Coding Style\n\nTo help make it easier maintain Spectacle please match the existing coding style as much as possible. This make it easier to both understand and merge your contributions. Only use two __spaces__ for indentation.\n\n## License\n\nBy contributing to Spectacle you agree that your contributions will be licensed under its MIT license.\n\n[1]: https://guides.github.com/activities/contributing-to-open-source/#contributing\n[2]: https://github.com/eczarny/spectacle#common-issues\n[3]: https://en.wikipedia.org/wiki/Console_(OS_X)\n"
  },
  {
    "path": "Cartfile",
    "content": "github \"hamcrest/OCHamcrest\" ~> 7.1\ngithub \"jonreid/OCMockito\" ~> 5.1\ngithub \"sparkle-project/Sparkle\" ~> 1.22\ngithub \"specta/expecta\" ~> 1.0\ngithub \"specta/specta\" ~> 1.0\n"
  },
  {
    "path": "Cartfile.resolved",
    "content": "github \"hamcrest/OCHamcrest\" \"v7.1.2\"\ngithub \"jonreid/OCMockito\" \"v5.1.2\"\ngithub \"sparkle-project/Sparkle\" \"1.22.0\"\ngithub \"specta/expecta\" \"v1.0.6\"\ngithub \"specta/specta\" \"v1.0.7\"\n"
  },
  {
    "path": "LICENSE.md",
    "content": "# License\n\n## Spectacle is distributed under the MIT License:\n\nCopyright (c) 2017 Eric Czarny <eczarny@gmail.com>\n\nPermission  is hereby granted, free of charge, to any person obtaining a copy of\nthis  software  and  associated documentation files (the \"Software\"), to deal in\nthe  Software  without  restriction,  including without limitation the rights to\nuse,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell copies\nof  the  Software, and to permit persons to whom the Software is furnished to do\nso, 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": "# Spectacle\n\n[![Build Status](https://travis-ci.org/eczarny/spectacle.svg?branch=master)](https://travis-ci.org/eczarny/spectacle)\n\nEasily organize windows without using a mouse.\n\n## Important Note\n\n**This project is not being actively maintained.** Unfortunately, after almost a decade of on-and-off development I can no longer dedicate the time needed to be a responsible maintainer of this project. Spectacle will remain available for download but please use at your own risk. The source code will continue to be free and open to anyone, so feel free to make Spectacle your own.\n\nThanks to all the folks that have made Spectacle the first app they install a new Mac!\n\n_Spectacle users have recommended [Rectangle](https://github.com/rxhanson/Rectangle) as an open source alternative._\n\n## System requirements\n\nSpectacle [0.8.6][1] is the last version to support Mac OS X 10.7; future releases will only support 10.9 or greater. Folks wishing to stay on 10.7 should download [0.8.6][1]. Those looking for a version of Spectacle that supports 10.6 can still download [0.7][2].\n\n## Keyboard Shortcuts\n\nSpectacle makes use of several [keyboard shortcuts][3] that trigger specific _window actions_. A window action is nothing more than a command that tells Spectacle how to change the size and/or position of a particular window.\n\nA keyboard shortcut consists of one or more modifier keys paired with a character key. The common modifier keys Spectacle takes advantage of are:\n\n| Symbol    | Key         |\n|:---------:|:-----------:|\n|  &#8984;  | Command Key |\n|  &#8963;  | Control Key |\n|  &#8997;  | Option Key  |\n|  &#8679;  | Shift Key   |\n\nThe default keyboard shortcuts can be changed at any time. Use new key combinations to trigger window actions, or clear particular keyboard shortcuts to disable window actions entirely.\n\n### Basic window actions\n\nTo move a window to the center of the screen use the &#8997;&#8984;C keyboard shortcut. Centered windows will __not__ have their size altered. Maximize a window using the &#8997;&#8984;F shortcut.\n\nWindows can be moved to a number of predefined regions of the screen:\n\n- _Move to the left half_ &#8212; &#8997;&#8984;&#8592;\n- _Move to the right half_ &#8212; &#8997;&#8984;&#8594;\n- _Move to the top half_ &#8212; &#8997;&#8984;&#8593;\n- _Move to the bottom half_ &#8212; &#8997;&#8984;&#8595;\n<br /><br />\n- _Move to the upper left_ &#8212; &#8963;&#8984;&#8592;\n- _Move to the lower left_ &#8212; &#8963;&#8679;&#8984;&#8592;\n- _Move to the upper right_ &#8212; &#8963;&#8984;&#8594;\n- _Move to the lower right_ &#8212; &#8963;&#8679;&#8984;&#8594;\n\nWindows may also be resized between thirds using any of the shortcuts above. For example, to have a window resized between 1/3 and 2/3 of the left region of the screen simply activate the *left half* &#8997;&#8984;&#8592; keyboard shortcut more than once. Each time the shortcut is activated Spectacle will move the window between 1/3, 2/3, and back to 1/2 of the left side of the screen. This feature also applies to the upper left, lower left, upper right, and lower right shortcuts.\n\nSpectacle can also move windows between horizontal and vertical thirds of the screen. The &#8963;&#8997;&#8594; keyboard shortcut will move a window to the next third of the screen, starting with the horizontal third region on the left of the screen. &#8963;&#8997;&#8592; will move a window to the previous third of the screen.\n\nResizing a window is just as easy. To make a window a bit larger use the &#8963;&#8997;&#8679;&#8594; keyboard shortcut; &#8963;&#8997;&#8679;&#8592; can be used to make a window smaller. Spectacle will always attempt to maintain contact between the edges of a window and the edges of the screen when resizing.\n\n### Multiple displays\n\nThe &#8963;&#8997;&#8984;&#8594; keyboard shortcut will move a window to the next available display. &#8963;&#8997;&#8984;&#8592; can be used to move a window to the previous display.\n\n### Window action history\n\nSpectacle remembers where every window was prior to executing a window action. To undo a window action use the &#8997;&#8984;Z keyboard shortcut. Use the &#8997;&#8679;&#8984;Z shortcut to redo the window action once again.\n\n## Common Issues\n\n### Spectacle is requesting access to use accessibility features\n\nApple's [OS X Accessibility Protocol][4] makes Spectacle possible. This protocol allows assistive applications to _drive the user interface of another application running in OS X_. In order to do its job Spectacle must be granted access to use these accessibility features. Instructions to do so will be displayed if Spectacle determines it does not have sufficient privileges.\n\n### Spectacle does not resize a particular window as expected\n\nOS X allows applications to place constraints on the size of its windows. This allows application developers to design their user interfaces without needing to worry about supporting every possible window dimension. In these cases Spectacle will not be able to resize those windows to fit into the exact dimensions intended by the shortcut used.\n\nAs an example suppose a display has a 2880x1800 resolution and a window is being resized to fit the left half of the display. If the window has specified a minimum allowable width of 1600 pixels Spectacle will not be able to resize the window to fit the expected 1440 pixels. The constraints placed on windows will always be respected despite leading to potentially unexpected results; in this example Spectacle will resize the window's width to 1600 pixels.\n\n### Spectacle behaves strangely with Terminal windows\n\nTerminal (and other terminal emulation applications like iTerm 2) place constraints on how windows are resized so entire rows and columns are always visible. This behavior works great since it guarantees no rows or columns are truncated. Unfortunately it does mean that Spectacle needs to do some extra work to make these windows fit.\n\nTo work around the limitations imposed on Terminal windows Spectacle will first try to resize a window to match the desired dimensions. If a window cannot be resized to fit Spectacle will immediately try to make the window a little smaller. This process is repeated until the window can be made to fit with its constraints still in place. The result is a window that is centered within the desired dimensions at the cost of a slightly jittery experience.\n\n### Spectacle does not work with all applications\n\nMost applications built with the Cocoa frameworks can be readily manipulated via the _OS X Accessibility Protocol_; allowing Spectacle to interact with nearly every window it encounters. Unfortunately this is not always the case. Spectacle will be unable to manipulate the windows of applications that build their user interfaces in unexpected ways.\n\n## Building and running\n\nSpectacle uses [Carthage][5]. Before building Spectacle in Xcode run:\n\n    $ carthage bootstrap --platform Mac\n\nOnce Carthage builds Spectacle's dependencies open the Xcode project:\n\n    $ open Spectacle.xcodeproj\n\nAfter Xcode finishes loading the workspace press &#8984;R to run Spectacle.\n\n# License\n\nCopyright (c) 2017 Eric Czarny.\n\nSpectacle should be accompanied by a LICENSE file containing the license relevant to this distribution.\n\n[1]: https://s3.amazonaws.com/spectacle/downloads/Spectacle+0.8.6.zip\n[2]: https://s3.amazonaws.com/spectacle/downloads/Spectacle+0.7.zip\n[3]: http://support.apple.com/kb/ht1343\n[4]: https://developer.apple.com/library/mac/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXmodel.html\n[5]: https://github.com/Carthage/Carthage\n"
  },
  {
    "path": "Spectacle/Resources/Certificates/dsa_public.pem",
    "content": "-----BEGIN PUBLIC KEY-----\nMIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQCY2D8N/yE2yx4+fpl4m4M2FzaBOcY8\nB/bFN3bExJcapUAn0IpTvUDO0SZCw28WPQuEnu+RAq00UULTtGtO1H6J975csVBC\nKSx5YbSlcui8MzUASHC99+GfccPCSYXNgqzdq72gdQI0/QRZcBA2MrFDFtNOneCZ\n0hCOrROwKB5B2iZ6duITRmcOBkcgx+/3sWPmi3860yCbUymhfIPsvyefJCTwDJbc\nulQm4SxPykseLauJluhbSyU5o82CiN2bohv8qzPGq5X29hO77u10QLuyNdpE6pHc\nI+CmAxY87Z/vgVxf63RbFqZ9HSi3VI3sH9X+imzP8eCrI44I4NS/6o7zAhUArcVK\nGobiXm0fqWZpD7DrcgnEOF8CggEAJLczjeNtMNTRSrhh5SR06FG2sUiCIe1hHPCz\n+3WPK+rPDnoC4gft6QxO9zRlnuvISeqNhv1oge5phdVQDWLhUojAQwAi2DU+/hjn\n7HjZx0PHs+oE568dH9qyB9F9xKLPpzHld2PJB9t1OMQjrbXuqFSjxecx7Y28f5D6\nIaMCS8EwgifS2vMyoPXW8MGpZ6iB5uPHFUZFEvGp6k0+T2V32F5JMgt37DlHA/Ok\nkmEMWU2JF14e3O1zU3h6ERhXdmNeRA9rarETO9mW8qLg95qRCR73I7CdhMSrY7/S\n6s7bPbPR4VKwORP8LJTKbb7bXQpXrso34hZIOPhL/RUuuJqrGQOCAQUAAoIBAFWc\n5KE8FFG8IrA+MG6G1gg0aDOPlrpE4Br/YrivsKlhP+9/jaCW+ESeukJIrNI8uw48\n9e9s/WrqH8N5EH1AhTUd3yOAu9zyvj/FLyMnnfFCwHe36uyRUFE9k0MR4jS9NOA6\nMEGTbPevEyZFwsioJCQOWGmr94LlTfRP1FXkSN7F7xvPqieUG3lMzD5tq+rqKS0R\nG56LWDh2ccbR+HZXtC513HHz4PUUCy/ukcThdND2ca90qCWtqDIw46GxRyROt1wM\nqhACEQqijf1GCzEWxSMibVRtTIF2/AWOOOdi8FMOloLnln1R5o3X6XY5nSQ3bj4m\nZvUkmWLQi6tvBv98A6Q=\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "Spectacle/Resources/Images.xcassets/10.9 Crash Fix.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-1.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-4.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-7.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-10.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-2.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-5.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-8.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-11.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-3.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-6.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-9.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-12.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-13.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-16.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-19.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-22.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-14.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-17.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-20.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-23.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-15.png\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-18.png\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-21.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-24.png\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-25.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-28.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-31.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-34.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-26.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-29.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-32.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-35.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-27.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-30.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-33.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"left-to-right\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-36.png\",\n      \"width-class\" : \"regular\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"language-direction\" : \"right-to-left\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-37.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-40.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"language-direction\" : \"left-to-right\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-43.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"language-direction\" : \"right-to-left\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-46.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-38.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-41.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"language-direction\" : \"left-to-right\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-44.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"language-direction\" : \"right-to-left\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-47.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-39.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"left-to-right\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Spectacle-42.png\",\n      \"width-class\" : \"regular\",\n      \"language-direction\" : \"right-to-left\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"language-direction\" : \"left-to-right\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-45.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"language-direction\" : \"right-to-left\",\n      \"graphics-feature-set\" : \"metal1v2\",\n      \"idiom\" : \"universal\",\n      \"width-class\" : \"regular\",\n      \"filename\" : \"Spectacle-48.png\",\n      \"height-class\" : \"regular\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Spectacle/Resources/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Spectacle/Resources/Images.xcassets/Security & Privacy.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"filename\" : \"Security & Privacy.png\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"filename\" : \"Security & Privacy@2x.png\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Spectacle/Resources/Images.xcassets/Spectacle Status Item.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"filename\" : \"Spectacle Status Item.png\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"filename\" : \"Spectacle Status Item@2x.png\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Spectacle/Resources/Images.xcassets/Spectacle.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 16.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 16@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 32.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 32@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 128.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 128@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 256.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 256@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 512.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Spectacle 512@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/Base.lproj/Spectacle.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"10117\" systemVersion=\"15E65\" targetRuntime=\"MacOSX.Cocoa\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"10117\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\" customClass=\"NSApplication\">\n            <connections>\n                <outlet property=\"delegate\" destination=\"tMJ-JP-XRD\" id=\"RCY-rC-CyW\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customObject id=\"GWn-WU-GEH\" customClass=\"NSFontManager\"/>\n        <customObject id=\"tMJ-JP-XRD\" customClass=\"SpectacleAppDelegate\">\n            <connections>\n                <outlet property=\"accessiblityAccessDialogWindow\" destination=\"aH5-eW-ySa\" id=\"u6t-Fq-cCp\"/>\n                <outlet property=\"disableShortcutsForAnHourMenuItem\" destination=\"qpo-5w-ZIY\" id=\"9Bo-Nc-w85\"/>\n                <outlet property=\"disableShortcutsForApplicationMenuItem\" destination=\"msZ-id-Pvw\" id=\"4dY-PO-sgY\"/>\n                <outlet property=\"makeLargerShortcutMenuItem\" destination=\"Yun-AA-OVD\" id=\"7P4-V3-6Yd\"/>\n                <outlet property=\"makeSmallerShortcutMenuItem\" destination=\"gTe-ym-DB0\" id=\"Qj6-FS-ebO\"/>\n                <outlet property=\"moveToBottomShortcutMenuItem\" destination=\"huV-Gw-lbX\" id=\"R2l-hx-4hT\"/>\n                <outlet property=\"moveToCenterShortcutMenuItem\" destination=\"xJu-Uo-nZw\" id=\"TUY-VV-2gn\"/>\n                <outlet property=\"moveToFullscreenShortcutMenuItem\" destination=\"dwQ-Bl-nEL\" id=\"bbv-zr-yKB\"/>\n                <outlet property=\"moveToLeftShortcutMenuItem\" destination=\"Jae-vx-7ZC\" id=\"CBd-QJ-Ojw\"/>\n                <outlet property=\"moveToLowerLeftShortcutMenuItem\" destination=\"eN5-A6-iho\" id=\"g7a-5S-hng\"/>\n                <outlet property=\"moveToLowerRightShortcutMenuItem\" destination=\"oDU-J0-NkJ\" id=\"XpK-S2-fel\"/>\n                <outlet property=\"moveToNextDisplayShortcutMenuItem\" destination=\"I4U-jL-hXq\" id=\"EBQ-xh-fXk\"/>\n                <outlet property=\"moveToNextThirdShortcutMenuItem\" destination=\"7HO-L3-O6Q\" id=\"yrD-z7-Yzl\"/>\n                <outlet property=\"moveToPreviousDisplayShortcutMenuItem\" destination=\"aPo-Rp-A1X\" id=\"LFz-As-pEk\"/>\n                <outlet property=\"moveToPreviousThirdShortcutMenuItem\" destination=\"bV9-Ga-jDG\" id=\"1k3-S5-1pz\"/>\n                <outlet property=\"moveToRightShortcutMenuItem\" destination=\"cae-26-Oab\" id=\"dya-ai-hmk\"/>\n                <outlet property=\"moveToTopShortcutMenuItem\" destination=\"yh0-ik-weD\" id=\"7Et-V2-jDL\"/>\n                <outlet property=\"moveToUpperLeftShortcutMenuItem\" destination=\"ldc-QO-Cq6\" id=\"cDG-Fx-IhZ\"/>\n                <outlet property=\"moveToUpperRightShortcutMenuItem\" destination=\"C7t-Sf-kOI\" id=\"w51-Xe-ZMs\"/>\n                <outlet property=\"redoLastMoveShortcutMenuItem\" destination=\"187-7k-0Ct\" id=\"TFE-uS-twj\"/>\n                <outlet property=\"statusItemMenu\" destination=\"KsA-8w-wcl\" id=\"76U-gs-viQ\"/>\n                <outlet property=\"undoLastMoveShortcutMenuItem\" destination=\"l9O-0B-fjp\" id=\"gns-Zw-ZVc\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"qZ6-IG-VBZ\" customClass=\"SUUpdater\"/>\n        <menu title=\"Spectacle Status Item\" id=\"KsA-8w-wcl\" propertyAccessControl=\"localizable\">\n            <items>\n                <menuItem title=\"About Spectacle\" tag=\"-1\" id=\"EA9-dx-Qfg\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"orderFrontStandardAboutPanel:\" target=\"-2\" id=\"P8D-am-ldh\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Check for Updates...\" tag=\"-1\" id=\"2sj-vF-eSL\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"checkForUpdates:\" target=\"qZ6-IG-VBZ\" id=\"cII-hj-ws3\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"880\"/>\n                <menuItem title=\"Disable\" id=\"eZT-Mm-qSc\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Disable\" id=\"flL-B2-XIP\">\n                        <items>\n                            <menuItem title=\"for an hour\" id=\"qpo-5w-ZIY\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"disableOrEnableShortcutsForAnHour:\" target=\"tMJ-JP-XRD\" id=\"tWY-vQ-3Ub\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"for APPLICATION\" id=\"msZ-id-Pvw\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"disableOrEnableShortcutsForApplication:\" target=\"tMJ-JP-XRD\" id=\"0P1-RI-4Px\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"b3s-Pm-hAJ\"/>\n                <menuItem title=\"Preferences...\" tag=\"-1\" id=\"ME4-Br-HLT\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"showPreferencesWindow:\" target=\"tMJ-JP-XRD\" id=\"XiZ-6k-zpx\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"1165\"/>\n                <menuItem title=\"Center\" id=\"xJu-Uo-nZw\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToCenter:\" target=\"tMJ-JP-XRD\" id=\"8bQ-2O-zty\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Fullscreen\" id=\"dwQ-Bl-nEL\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToFullscreen:\" target=\"tMJ-JP-XRD\" id=\"P6T-cu-7lj\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"Nmj-XX-uaG\"/>\n                <menuItem title=\"Left Half\" id=\"Jae-vx-7ZC\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToLeftHalf:\" target=\"tMJ-JP-XRD\" id=\"Jyu-pQ-sNE\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Right Half\" id=\"cae-26-Oab\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToRightHalf:\" target=\"tMJ-JP-XRD\" id=\"jr6-2X-ZAa\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Top Half\" id=\"yh0-ik-weD\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToTopHalf:\" target=\"tMJ-JP-XRD\" id=\"dG6-Fy-O40\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Bottom Half\" id=\"huV-Gw-lbX\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToBottomHalf:\" target=\"tMJ-JP-XRD\" id=\"7i6-Gr-Jug\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"gbv-tO-TvK\"/>\n                <menuItem title=\"Upper Left\" id=\"ldc-QO-Cq6\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToUpperLeft:\" target=\"tMJ-JP-XRD\" id=\"XAq-dc-yRG\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Lower Left\" id=\"eN5-A6-iho\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToLowerLeft:\" target=\"tMJ-JP-XRD\" id=\"e4K-PQ-wlb\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Upper Right\" id=\"C7t-Sf-kOI\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToUpperRight:\" target=\"tMJ-JP-XRD\" id=\"3W6-0L-5h1\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Lower Right\" id=\"oDU-J0-NkJ\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToLowerRight:\" target=\"tMJ-JP-XRD\" id=\"mBh-Kx-JVT\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"0li-21-m4g\"/>\n                <menuItem title=\"Next Display\" id=\"I4U-jL-hXq\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToNextDisplay:\" target=\"tMJ-JP-XRD\" id=\"8Jf-bY-L7R\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Previous Display\" id=\"aPo-Rp-A1X\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToPreviousDisplay:\" target=\"tMJ-JP-XRD\" id=\"wjA-mg-3rC\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"2VE-eu-Tv6\"/>\n                <menuItem title=\"Next Third\" id=\"7HO-L3-O6Q\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToNextThird:\" target=\"tMJ-JP-XRD\" id=\"tOU-2B-5ca\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Previous Third\" id=\"bV9-Ga-jDG\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"moveFrontmostWindowToPreviousThird:\" target=\"tMJ-JP-XRD\" id=\"8oD-A9-mUX\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"dDR-EJ-dud\"/>\n                <menuItem title=\"Make Larger\" id=\"Yun-AA-OVD\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"makeFrontmostWindowLarger:\" target=\"tMJ-JP-XRD\" id=\"twG-Hu-ZQM\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Make Smaller\" id=\"gTe-ym-DB0\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"makeFrontmostWindowSmaller:\" target=\"tMJ-JP-XRD\" id=\"6lw-fW-wPN\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"nH8-Kx-TCA\"/>\n                <menuItem title=\"Undo\" id=\"l9O-0B-fjp\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"undoLastWindowAction:\" target=\"tMJ-JP-XRD\" id=\"M8P-vs-ajH\"/>\n                    </connections>\n                </menuItem>\n                <menuItem title=\"Redo\" id=\"187-7k-0Ct\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"redoLastWindowAction:\" target=\"tMJ-JP-XRD\" id=\"WIv-TD-23d\"/>\n                    </connections>\n                </menuItem>\n                <menuItem isSeparatorItem=\"YES\" id=\"OfT-IK-7NI\"/>\n                <menuItem title=\"Quit Spectacle\" id=\"Isn-Og-AEv\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <connections>\n                        <action selector=\"terminate:\" target=\"-2\" id=\"V4u-Ow-d6l\"/>\n                    </connections>\n                </menuItem>\n            </items>\n            <connections>\n                <outlet property=\"delegate\" destination=\"tMJ-JP-XRD\" id=\"eao-lV-3w3\"/>\n            </connections>\n        </menu>\n        <window allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" oneShot=\"NO\" releasedWhenClosed=\"NO\" showsToolbarButton=\"NO\" visibleAtLaunch=\"NO\" animationBehavior=\"default\" id=\"aH5-eW-ySa\" propertyAccessControl=\"none\">\n            <rect key=\"contentRect\" x=\"422\" y=\"199\" width=\"780\" height=\"360\"/>\n            <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"1680\" height=\"1028\"/>\n            <value key=\"minSize\" type=\"size\" width=\"780\" height=\"360\"/>\n            <value key=\"maxSize\" type=\"size\" width=\"780\" height=\"360\"/>\n            <view key=\"contentView\" id=\"wR6-GU-kdb\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"780\" height=\"360\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"q8H-wi-KU2\">\n                        <rect key=\"frame\" x=\"129\" y=\"321\" width=\"522\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Spectacle would like to control your windows using accessibility features.\" id=\"HRo-tn-M1V\">\n                            <font key=\"font\" metaFont=\"systemBold\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"MM0-lm-06Y\">\n                        <rect key=\"frame\" x=\"129\" y=\"295\" width=\"522\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Grant access to this application in System Preferences.\" id=\"ruu-yJ-Q1F\">\n                            <font key=\"font\" metaFont=\"smallSystem\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <button verticalHuggingPriority=\"750\" id=\"9dg-wQ-O5z\">\n                        <rect key=\"frame\" x=\"213\" y=\"251\" width=\"212\" height=\"32\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <buttonCell key=\"cell\" type=\"push\" title=\"Open System Preferences\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"iPl-AT-Pei\">\n                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <connections>\n                                <action selector=\"openSystemPreferences:\" target=\"tMJ-JP-XRD\" id=\"xfa-vh-epH\"/>\n                            </connections>\n                        </buttonCell>\n                    </button>\n                    <button verticalHuggingPriority=\"750\" id=\"nIS-kz-1R7\">\n                        <rect key=\"frame\" x=\"425\" y=\"251\" width=\"147\" height=\"32\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <buttonCell key=\"cell\" type=\"push\" title=\"Quit Spectacle\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"gMV-vD-CUe\">\n                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                            <font key=\"font\" metaFont=\"system\"/>\n                        </buttonCell>\n                        <connections>\n                            <action selector=\"terminate:\" target=\"-2\" id=\"bAO-EW-SfZ\"/>\n                        </connections>\n                    </button>\n                    <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" id=\"he4-Bj-XB4\" propertyAccessControl=\"localizable\">\n                        <rect key=\"frame\" x=\"-27\" y=\"-383\" width=\"835\" height=\"653\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" image=\"Security &amp; Privacy\" id=\"zQN-Oe-PPv\"/>\n                    </imageView>\n                </subviews>\n            </view>\n        </window>\n    </objects>\n    <resources>\n        <image name=\"Security &amp; Privacy\" width=\"780\" height=\"654\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/Base.lproj/SpectaclePreferencesWindow.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"11762\" systemVersion=\"16C67\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"localizable\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"11762\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\" customClass=\"SpectaclePreferencesController\">\n            <connections>\n                <outlet property=\"footerView\" destination=\"wNg-Ru-1aI\" id=\"a3s-Yg-9AT\"/>\n                <outlet property=\"loginItemEnabled\" destination=\"P6j-bi-KoE\" id=\"Bfa-gg-4G7\"/>\n                <outlet property=\"makeLargerShortcutRecorder\" destination=\"iwx-0m-WUf\" id=\"lUC-P6-Vv0\"/>\n                <outlet property=\"makeSmallerShortcutRecorder\" destination=\"0jH-Zh-PgG\" id=\"KIO-62-XGL\"/>\n                <outlet property=\"moveToBottomShortcutRecorder\" destination=\"hzO-eo-G8F\" id=\"DJU-MT-61C\"/>\n                <outlet property=\"moveToCenterShortcutRecorder\" destination=\"mbr-Cs-whm\" id=\"aZl-2a-crG\"/>\n                <outlet property=\"moveToFullscreenShortcutRecorder\" destination=\"Wxa-6e-lyM\" id=\"RBe-8y-feS\"/>\n                <outlet property=\"moveToLeftShortcutRecorder\" destination=\"4na-E1-mUM\" id=\"mcM-bw-uWP\"/>\n                <outlet property=\"moveToLowerLeftShortcutRecorder\" destination=\"u0O-yW-0g8\" id=\"fDR-cZ-vdk\"/>\n                <outlet property=\"moveToLowerRightShortcutRecorder\" destination=\"lJh-dh-K7C\" id=\"CCg-we-Urp\"/>\n                <outlet property=\"moveToNextDisplayShortcutRecorder\" destination=\"lLw-FX-nqn\" id=\"l2e-tq-Xkb\"/>\n                <outlet property=\"moveToNextThirdShortcutRecorder\" destination=\"kGL-qW-2Cn\" id=\"tvD-Rn-p2o\"/>\n                <outlet property=\"moveToPreviousDisplayShortcutRecorder\" destination=\"OsP-Gv-gJI\" id=\"v05-17-4dU\"/>\n                <outlet property=\"moveToPreviousThirdShortcutRecorder\" destination=\"NdL-ul-8LW\" id=\"WYV-Hd-UOn\"/>\n                <outlet property=\"moveToRightShortcutRecorder\" destination=\"eCb-ZU-egY\" id=\"iW0-K6-OeV\"/>\n                <outlet property=\"moveToTopShortcutRecorder\" destination=\"rN1-zt-f9E\" id=\"Mw9-c9-b8O\"/>\n                <outlet property=\"moveToUpperLeftShortcutRecorder\" destination=\"wLj-pQ-b7w\" id=\"fvL-bO-rKZ\"/>\n                <outlet property=\"moveToUpperRightShortcutRecorder\" destination=\"44s-Ps-tmn\" id=\"Kbc-Pj-hti\"/>\n                <outlet property=\"optionsFooterView\" destination=\"tke-O4-mlo\" id=\"WfN-Qq-nH6\"/>\n                <outlet property=\"redoLastMoveShortcutRecorder\" destination=\"pPP-7U-GSg\" id=\"AYn-wB-Yo2\"/>\n                <outlet property=\"shortcutModifierLegendFooterView\" destination=\"t2T-pB-nn6\" id=\"WSX-7H-Osj\"/>\n                <outlet property=\"statusItemEnabled\" destination=\"cf8-TV-Yjp\" id=\"0xU-vc-q02\"/>\n                <outlet property=\"undoLastMoveShortcutRecorder\" destination=\"au4-Gr-KF9\" id=\"ecz-fA-ywO\"/>\n                <outlet property=\"window\" destination=\"JW4-q9-L7q\" id=\"3he-NT-S7L\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <window title=\"Spectacle X.Y.Z\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" oneShot=\"NO\" showsToolbarButton=\"NO\" visibleAtLaunch=\"NO\" animationBehavior=\"default\" id=\"JW4-q9-L7q\">\n            <windowStyleMask key=\"styleMask\" titled=\"YES\" closable=\"YES\" miniaturizable=\"YES\"/>\n            <rect key=\"contentRect\" x=\"283\" y=\"311\" width=\"616\" height=\"513\"/>\n            <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"1440\" height=\"877\"/>\n            <view key=\"contentView\" id=\"ry3-8n-Juf\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"616\" height=\"513\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <textField verticalHuggingPriority=\"750\" id=\"Nwx-2P-V9U\">\n                        <rect key=\"frame\" x=\"18\" y=\"451\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Center:\" id=\"oqf-7z-BFa\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"mbr-Cs-whm\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"449\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"guf-X1-Beb\">\n                        <rect key=\"frame\" x=\"18\" y=\"422\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Fullscreen:\" id=\"tKr-XE-DEU\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"Wxa-6e-lyM\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"420\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"uY3-hc-TbA\">\n                        <rect key=\"frame\" x=\"18\" y=\"364\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Left Half:\" id=\"IWj-rc-Kvi\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"4na-E1-mUM\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"362\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"Gsd-o4-KTI\">\n                        <rect key=\"frame\" x=\"18\" y=\"335\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Right Half:\" id=\"WeK-fS-mRh\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"eCb-ZU-egY\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"333\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"edj-pC-f1Z\">\n                        <rect key=\"frame\" x=\"17\" y=\"306\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Top Half:\" id=\"AnP-Lv-Hbd\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"rN1-zt-f9E\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"304\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"Dcf-0q-9fG\">\n                        <rect key=\"frame\" x=\"18\" y=\"277\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Bottom Half:\" id=\"Awn-mO-sht\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"hzO-eo-G8F\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"275\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"jQx-Df-xE5\">\n                        <rect key=\"frame\" x=\"18\" y=\"219\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Upper Left:\" id=\"ldH-1E-mKW\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"wLj-pQ-b7w\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"217\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"b4f-8J-iOX\">\n                        <rect key=\"frame\" x=\"18\" y=\"190\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Lower Left:\" id=\"dQP-TR-GMx\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"u0O-yW-0g8\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"188\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"Q8S-XZ-uUw\">\n                        <rect key=\"frame\" x=\"18\" y=\"161\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Upper Right:\" id=\"gSY-Au-xOH\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"44s-Ps-tmn\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"159\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"NRc-if-7b9\">\n                        <rect key=\"frame\" x=\"18\" y=\"132\" width=\"117\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Lower Right:\" id=\"Vul-FT-BbB\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"lJh-dh-K7C\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"140\" y=\"130\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"4P4-9k-sEd\">\n                        <rect key=\"frame\" x=\"286\" y=\"451\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Next Display:\" id=\"lw7-Ap-kJO\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"lLw-FX-nqn\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"449\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"aQq-n4-9FK\">\n                        <rect key=\"frame\" x=\"286\" y=\"422\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Previous Display:\" id=\"hmL-EC-pro\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"OsP-Gv-gJI\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"420\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"sBC-FW-cjv\">\n                        <rect key=\"frame\" x=\"286\" y=\"364\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Next Third:\" id=\"Tze-mR-IV4\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"kGL-qW-2Cn\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"362\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"FjH-Ke-3MT\">\n                        <rect key=\"frame\" x=\"286\" y=\"335\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Previous Third:\" id=\"s3E-Lp-mJ4\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"NdL-ul-8LW\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"333\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"sIx-hc-eUS\">\n                        <rect key=\"frame\" x=\"286\" y=\"277\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Make Larger:\" id=\"0f9-kj-bro\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"iwx-0m-WUf\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"275\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"Iw5-TM-YRu\">\n                        <rect key=\"frame\" x=\"286\" y=\"248\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Make Smaller:\" id=\"SDM-U5-yUR\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"0jH-Zh-PgG\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"246\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"lYA-bE-Cvq\">\n                        <rect key=\"frame\" x=\"286\" y=\"190\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Undo:\" id=\"CJs-az-eG7\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"au4-Gr-KF9\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"188\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <textField verticalHuggingPriority=\"750\" id=\"paN-Mc-McA\">\n                        <rect key=\"frame\" x=\"286\" y=\"161\" width=\"131\" height=\"17\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Redo:\" id=\"y7M-cR-DF2\">\n                            <font key=\"font\" metaFont=\"system\"/>\n                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        </textFieldCell>\n                    </textField>\n                    <customView id=\"pPP-7U-GSg\" customClass=\"SpectacleShortcutRecorder\">\n                        <rect key=\"frame\" x=\"422\" y=\"159\" width=\"140\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </customView>\n                    <box verticalHuggingPriority=\"750\" boxType=\"separator\" id=\"vWw-ws-BgW\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"60\" width=\"616\" height=\"5\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    </box>\n                    <customView id=\"wNg-Ru-1aI\" userLabel=\"Footer View\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"616\" height=\"63\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <subviews>\n                            <customView id=\"t2T-pB-nn6\" userLabel=\"Shortcut Modifer Legend Footer View\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"616\" height=\"63\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <subviews>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"t8o-hT-IQi\">\n                                        <rect key=\"frame\" x=\"191\" y=\"25\" width=\"28\" height=\"29\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"⌃\" id=\"806-S1-nYH\">\n                                            <font key=\"font\" metaFont=\"system\" size=\"24\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"dj1-Cv-cGv\">\n                                        <rect key=\"frame\" x=\"174\" y=\"9\" width=\"63\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Control\" id=\"7Fe-Da-fYB\">\n                                            <font key=\"font\" metaFont=\"smallSystem\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"l4c-Va-boE\">\n                                        <rect key=\"frame\" x=\"258\" y=\"25\" width=\"32\" height=\"29\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"⌥\" id=\"YQm-Kc-fYF\">\n                                            <font key=\"font\" metaFont=\"system\" size=\"24\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"T1t-0q-VR1\">\n                                        <rect key=\"frame\" x=\"243\" y=\"9\" width=\"63\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Option\" id=\"U0H-hG-KAQ\">\n                                            <font key=\"font\" metaFont=\"smallSystem\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"dWs-aZ-UsN\">\n                                        <rect key=\"frame\" x=\"325\" y=\"25\" width=\"32\" height=\"29\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"⇧\" id=\"Ir0-AJ-ldj\">\n                                            <font key=\"font\" metaFont=\"system\" size=\"24\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"T2K-sG-8h4\">\n                                        <rect key=\"frame\" x=\"310\" y=\"9\" width=\"63\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Shift\" id=\"dww-8Q-sa1\">\n                                            <font key=\"font\" metaFont=\"smallSystem\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"ePN-Nc-cy9\">\n                                        <rect key=\"frame\" x=\"394\" y=\"25\" width=\"32\" height=\"29\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"⌘\" id=\"SQM-4e-yFd\">\n                                            <font key=\"font\" metaFont=\"system\" size=\"24\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" id=\"Xwv-Yf-TxZ\">\n                                        <rect key=\"frame\" x=\"379\" y=\"9\" width=\"63\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Command\" id=\"jdf-Yu-zrq\">\n                                            <font key=\"font\" metaFont=\"smallSystem\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <button id=\"iUO-l8-726\" userLabel=\"Next Button\">\n                                        <rect key=\"frame\" x=\"575\" y=\"9\" width=\"32\" height=\"45\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                        <buttonCell key=\"cell\" type=\"bevel\" bezelStyle=\"rounded\" image=\"NSGoRightTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"iYb-kS-yHQ\">\n                                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                        </buttonCell>\n                                        <connections>\n                                            <action selector=\"swapFooterViews:\" target=\"-2\" id=\"JNg-Dc-I7P\"/>\n                                        </connections>\n                                    </button>\n                                </subviews>\n                            </customView>\n                        </subviews>\n                    </customView>\n                    <button verticalHuggingPriority=\"750\" id=\"nKt-CG-zVj\">\n                        <rect key=\"frame\" x=\"446\" y=\"74\" width=\"150\" height=\"25\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <buttonCell key=\"cell\" type=\"roundTextured\" title=\"Restore Defaults...\" bezelStyle=\"texturedRounded\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"NT7-Sd-Ofw\">\n                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                            <font key=\"font\" metaFont=\"system\"/>\n                        </buttonCell>\n                        <connections>\n                            <action selector=\"restoreDefaults:\" target=\"-2\" id=\"6ui-XF-TPy\"/>\n                        </connections>\n                    </button>\n                    <button misplaced=\"YES\" id=\"P6j-bi-KoE\">\n                        <rect key=\"frame\" x=\"18\" y=\"78\" width=\"246\" height=\"18\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMinX=\"YES\" widthSizable=\"YES\" flexibleMinY=\"YES\" flexibleMaxY=\"YES\"/>\n                        <buttonCell key=\"cell\" type=\"check\" title=\"Launch Spectacle at login\" bezelStyle=\"regularSquare\" imagePosition=\"left\" alignment=\"left\" inset=\"2\" id=\"cEj-mH-kie\">\n                            <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                            <font key=\"font\" metaFont=\"system\"/>\n                        </buttonCell>\n                        <connections>\n                            <action selector=\"toggleLoginItem:\" target=\"-2\" id=\"pwr-Q6-dvi\"/>\n                        </connections>\n                    </button>\n                </subviews>\n            </view>\n        </window>\n        <customView id=\"tke-O4-mlo\" userLabel=\"Options Footer View\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"616\" height=\"63\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <button id=\"g4V-DY-GoG\" userLabel=\"Previous Button\">\n                    <rect key=\"frame\" x=\"9\" y=\"9\" width=\"32\" height=\"45\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    <buttonCell key=\"cell\" type=\"bevel\" bezelStyle=\"rounded\" image=\"NSGoLeftTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"0vX-x3-M6H\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"swapFooterViews:\" target=\"-2\" id=\"U7e-9q-8hA\"/>\n                    </connections>\n                </button>\n                <textField verticalHuggingPriority=\"750\" id=\"U91-cx-ccf\">\n                    <rect key=\"frame\" x=\"297\" y=\"23\" width=\"74\" height=\"17\"/>\n                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\" flexibleMaxY=\"YES\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Run...\" id=\"eYU-TH-wcO\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"controlShadowColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <popUpButton verticalHuggingPriority=\"750\" id=\"cf8-TV-Yjp\">\n                    <rect key=\"frame\" x=\"372\" y=\"17\" width=\"227\" height=\"26\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                    <popUpButtonCell key=\"cell\" type=\"push\" title=\"in the status menu\" bezelStyle=\"rounded\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"borderAndBezel\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"in4-v8-tIm\" id=\"6fN-BB-g3d\">\n                        <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"menu\"/>\n                        <menu key=\"menu\" title=\"OtherViews\" id=\"W2t-KP-bYJ\">\n                            <items>\n                                <menuItem title=\"in the status menu\" state=\"on\" id=\"in4-v8-tIm\">\n                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                </menuItem>\n                                <menuItem title=\"as a background application\" tag=\"1\" id=\"aWf-FC-J1j\">\n                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                </menuItem>\n                            </items>\n                        </menu>\n                    </popUpButtonCell>\n                    <connections>\n                        <action selector=\"toggleStatusItem:\" target=\"-2\" id=\"UbE-2H-Bsc\"/>\n                    </connections>\n                </popUpButton>\n            </subviews>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSGoLeftTemplate\" width=\"9\" height=\"12\"/>\n        <image name=\"NSGoRightTemplate\" width=\"9\" height=\"12\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/en.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1348\\cocoasubrtf170\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\n\n\\f0\\b\\fs24 \\cf0 Credits\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Icons and other artwork: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Source code available on {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHub}}\n\\b \\\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/es.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1404\\cocoasubrtf470\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\paperw12240\\paperh15840\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\\partightenfactor0\n\n\\f0\\b\\fs24 \\cf0 Credits\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 Iconos y dise\\'f1o gr\\'e1fico: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 C\\'f3digo fuente disponible en {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHub}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt \\cf0 @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/es.lproj/Spectacle.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"187-7k-0Ct\"; */\n\"187-7k-0Ct.title\" = \"Rehacer\";\n\n/* Class = \"NSMenuItem\"; title = \"Check for Updates...\"; ObjectID = \"2sj-vF-eSL\"; */\n\"2sj-vF-eSL.title\" = \"Chequear actualizaciones...\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Third\"; ObjectID = \"7HO-L3-O6Q\"; */\n\"7HO-L3-O6Q.title\" = \"Tercer próximo\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Right\"; ObjectID = \"C7t-Sf-kOI\"; */\n\"C7t-Sf-kOI.title\" = \"Superior derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"About Spectacle\"; ObjectID = \"EA9-dx-Qfg\"; */\n\"EA9-dx-Qfg.title\" = \"Acerca de Spectacle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Spectacle would like to control your windows using accessibility features.\"; ObjectID = \"HRo-tn-M1V\"; */\n\"HRo-tn-M1V.title\" = \"Spectacle necesita tener control de las funcionalidades de accesibilidad.\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Display\"; ObjectID = \"I4U-jL-hXq\"; */\n\"I4U-jL-hXq.title\" = \"Siguiente monitor\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit Spectacle\"; ObjectID = \"Isn-Og-AEv\"; */\n\"Isn-Og-AEv.title\" = \"Salir Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Left Half\"; ObjectID = \"Jae-vx-7ZC\"; */\n\"Jae-vx-7ZC.title\" = \"La mitad izquierda\";\n\n/* Class = \"NSMenu\"; title = \"Spectacle Status Item\"; ObjectID = \"KsA-8w-wcl\"; */\n\"KsA-8w-wcl.title\" = \"Spectacle estado del elemento\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences...\"; ObjectID = \"ME4-Br-HLT\"; */\n\"ME4-Br-HLT.title\" = \"Configuración...\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Larger\"; ObjectID = \"Yun-AA-OVD\"; */\n\"Yun-AA-OVD.title\" = \"Hacer más grande\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Display\"; ObjectID = \"aPo-Rp-A1X\"; */\n\"aPo-Rp-A1X.title\" = \"Monitor anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Third\"; ObjectID = \"bV9-Ga-jDG\"; */\n\"bV9-Ga-jDG.title\" = \"Tercer anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Right Half\"; ObjectID = \"cae-26-Oab\"; */\n\"cae-26-Oab.title\" = \"Mitad derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"Fullscreen\"; ObjectID = \"dwQ-Bl-nEL\"; */\n\"dwQ-Bl-nEL.title\" = \"Pantalla completa\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Left\"; ObjectID = \"eN5-A6-iho\"; */\n\"eN5-A6-iho.title\" = \"Abajo a la izquierda\";\n\n/* Class = \"NSMenuItem\"; title = \"Disable\"; ObjectID = \"eZT-Mm-qSc\"; */\n\"eZT-Mm-qSc.title\" = \"Deshabilitado\";\n\n/* Class = \"NSMenu\"; title = \"Disable\"; ObjectID = \"flL-B2-XIP\"; */\n\"flL-B2-XIP.title\" = \"Deshabilitado\";\n\n/* Class = \"NSButtonCell\"; title = \"Quit Spectacle\"; ObjectID = \"gMV-vD-CUe\"; */\n\"gMV-vD-CUe.title\" = \"Salir Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Smaller\"; ObjectID = \"gTe-ym-DB0\"; */\n\"gTe-ym-DB0.title\" = \"Hacer mas pequeño\";\n\n/* Class = \"NSMenuItem\"; title = \"Bottom Half\"; ObjectID = \"huV-Gw-lbX\"; */\n\"huV-Gw-lbX.title\" = \"Mitad inferior\";\n\n/* Class = \"NSButtonCell\"; title = \"Open System Preferences\"; ObjectID = \"iPl-AT-Pei\"; */\n\"iPl-AT-Pei.title\" = \"Abrir preferencias de sistema\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"l9O-0B-fjp\"; */\n\"l9O-0B-fjp.title\" = \"Deshacer\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Left\"; ObjectID = \"ldc-QO-Cq6\"; */\n\"ldc-QO-Cq6.title\" = \"Arriba a la izquierda\";\n\n/* Class = \"NSMenuItem\"; title = \"for APPLICATION\"; ObjectID = \"msZ-id-Pvw\"; */\n\"msZ-id-Pvw.title\" = \"para la aplicación\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Right\"; ObjectID = \"oDU-J0-NkJ\"; */\n\"oDU-J0-NkJ.title\" = \"Inferior derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"for an hour\"; ObjectID = \"qpo-5w-ZIY\"; */\n\"qpo-5w-ZIY.title\" = \"Por una hora\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Grant access to this application in System Preferences.\"; ObjectID = \"ruu-yJ-Q1F\"; */\n\"ruu-yJ-Q1F.title\" = \"Permitir el acceso a esta aplicación en Preferencias del sistema.\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"xJu-Uo-nZw\"; */\n\"xJu-Uo-nZw.title\" = \"Centro\";\n\n/* Class = \"NSMenuItem\"; title = \"Top Half\"; ObjectID = \"yh0-ik-weD\"; */\n\"yh0-ik-weD.title\" = \"Mitad superior\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/es.lproj/SpectaclePreferencesWindow.strings",
    "content": "\n/* Class = \"NSTextFieldCell\"; title = \"Make Larger:\"; ObjectID = \"0f9-kj-bro\"; */\n\"0f9-kj-bro.title\" = \"Hacer más grande:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Control\"; ObjectID = \"7Fe-Da-fYB\"; */\n\"7Fe-Da-fYB.title\" = \"Control\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌃\"; ObjectID = \"806-S1-nYH\"; */\n\"806-S1-nYH.title\" = \"⌃\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Top Half:\"; ObjectID = \"AnP-Lv-Hbd\"; */\n\"AnP-Lv-Hbd.title\" = \"Mitad superior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Bottom Half:\"; ObjectID = \"Awn-mO-sht\"; */\n\"Awn-mO-sht.title\" = \"Mitad inferior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Undo:\"; ObjectID = \"CJs-az-eG7\"; */\n\"CJs-az-eG7.title\" = \"Deshacer:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Left Half:\"; ObjectID = \"IWj-rc-Kvi\"; */\n\"IWj-rc-Kvi.title\" = \"Mitad izquierda:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⇧\"; ObjectID = \"Ir0-AJ-ldj\"; */\n\"Ir0-AJ-ldj.title\" = \"⇧\";\n\n/* Class = \"NSWindow\"; title = \"Spectacle X.Y.Z\"; ObjectID = \"JW4-q9-L7q\"; */\n\"JW4-q9-L7q.title\" = \"Spectacle X.Y.Z\";\n\n/* Class = \"NSButtonCell\"; title = \"Restore Defaults...\"; ObjectID = \"NT7-Sd-Ofw\"; */\n\"NT7-Sd-Ofw.title\" = \"Restaurar por defecto...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Make Smaller:\"; ObjectID = \"SDM-U5-yUR\"; */\n\"SDM-U5-yUR.title\" = \"Hacer más pequeño:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌘\"; ObjectID = \"SQM-4e-yFd\"; */\n\"SQM-4e-yFd.title\" = \"⌘\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Third:\"; ObjectID = \"Tze-mR-IV4\"; */\n\"Tze-mR-IV4.title\" = \"Siguiente tercero:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Option\"; ObjectID = \"U0H-hG-KAQ\"; */\n\"U0H-hG-KAQ.title\" = \"Opciones\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Right:\"; ObjectID = \"Vul-FT-BbB\"; */\n\"Vul-FT-BbB.title\" = \"Inferior derecho:\";\n\n/* Class = \"NSMenu\"; title = \"OtherViews\"; ObjectID = \"W2t-KP-bYJ\"; */\n\"W2t-KP-bYJ.title\" = \"Otras vistas\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Right Half:\"; ObjectID = \"WeK-fS-mRh\"; */\n\"WeK-fS-mRh.title\" = \"Mitad derecha:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌥\"; ObjectID = \"YQm-Kc-fYF\"; */\n\"YQm-Kc-fYF.title\" = \"⌥\";\n\n/* Class = \"NSMenuItem\"; title = \"as a background application\"; ObjectID = \"aWf-FC-J1j\"; */\n\"aWf-FC-J1j.title\" = \"aplicación en segundo plano\";\n\n/* Class = \"NSButtonCell\"; title = \"Launch Spectacle at login\"; ObjectID = \"cEj-mH-kie\"; */\n\"cEj-mH-kie.title\" = \"Ejecutar Spectacle al iniciar\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Left:\"; ObjectID = \"dQP-TR-GMx\"; */\n\"dQP-TR-GMx.title\" = \"Abajo a la izquierda:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Shift\"; ObjectID = \"dww-8Q-sa1\"; */\n\"dww-8Q-sa1.title\" = \"Shift\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Run...\"; ObjectID = \"eYU-TH-wcO\"; */\n\"eYU-TH-wcO.title\" = \"Ejecutar...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Right:\"; ObjectID = \"gSY-Au-xOH\"; */\n\"gSY-Au-xOH.title\" = \"Superior derecha:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Display:\"; ObjectID = \"hmL-EC-pro\"; */\n\"hmL-EC-pro.title\" = \"Monitor anterior:\";\n\n/* Class = \"NSMenuItem\"; title = \"in the status menu\"; ObjectID = \"in4-v8-tIm\"; */\n\"in4-v8-tIm.title\" = \"en menu de estado\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Command\"; ObjectID = \"jdf-Yu-zrq\"; */\n\"jdf-Yu-zrq.title\" = \"Command\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Left:\"; ObjectID = \"ldH-1E-mKW\"; */\n\"ldH-1E-mKW.title\" = \"Superior izquierdo:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Display:\"; ObjectID = \"lw7-Ap-kJO\"; */\n\"lw7-Ap-kJO.title\" = \"Monitor siguiente:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Center:\"; ObjectID = \"oqf-7z-BFa\"; */\n\"oqf-7z-BFa.title\" = \"Centro:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Third:\"; ObjectID = \"s3E-Lp-mJ4\"; */\n\"s3E-Lp-mJ4.title\" = \"Tercer anterior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Fullscreen:\"; ObjectID = \"tKr-XE-DEU\"; */\n\"tKr-XE-DEU.title\" = \"Pantalla completa:\";\n\n/* Class = \"NSBox\"; title = \"Box\"; ObjectID = \"vWw-ws-BgW\"; */\n\"vWw-ws-BgW.title\" = \"Caja\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Redo:\"; ObjectID = \"y7M-cR-DF2\"; */\n\"y7M-cR-DF2.title\" = \"Rehacer:\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/fi.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1404\\cocoasubrtf420\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\\partightenfactor0\n\n\\f0\\b\\fs24 \\cf0 Tekij\\'e4t\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 Kuvakkeet ja muut grafiikat: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 L\\'e4hdekoodi saatavilla {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHubissa}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt \\cf0 @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/fi.lproj/Spectacle.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"187-7k-0Ct\"; */\n\"187-7k-0Ct.title\" = \"Tee uudelleen\";\n\n/* Class = \"NSMenuItem\"; title = \"Check for Updates...\"; ObjectID = \"2sj-vF-eSL\"; */\n\"2sj-vF-eSL.title\" = \"Tarkista päivitykset...\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Third\"; ObjectID = \"7HO-L3-O6Q\"; */\n\"7HO-L3-O6Q.title\" = \"Seuraava kolmasosa\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Right\"; ObjectID = \"C7t-Sf-kOI\"; */\n\"C7t-Sf-kOI.title\" = \"Yläoikea\";\n\n/* Class = \"NSMenuItem\"; title = \"About Spectacle\"; ObjectID = \"EA9-dx-Qfg\"; */\n\"EA9-dx-Qfg.title\" = \"Tietoja Spectaclesta\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Spectacle would like to control your windows using accessibility features.\"; ObjectID = \"HRo-tn-M1V\"; */\n\"HRo-tn-M1V.title\" = \"Spectacle haluaisi hallita ikkunoita käyttöaputoimintojen avulla.\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Display\"; ObjectID = \"I4U-jL-hXq\"; */\n\"I4U-jL-hXq.title\" = \"Seuraava ikkuna\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit Spectacle\"; ObjectID = \"Isn-Og-AEv\"; */\n\"Isn-Og-AEv.title\" = \"Sulje Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Left Half\"; ObjectID = \"Jae-vx-7ZC\"; */\n\"Jae-vx-7ZC.title\" = \"Vasen puoli\";\n\n/* Class = \"NSMenu\"; title = \"Spectacle Status Item\"; ObjectID = \"KsA-8w-wcl\"; */\n\"KsA-8w-wcl.title\" = \"Spectacle Status Item\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences...\"; ObjectID = \"ME4-Br-HLT\"; */\n\"ME4-Br-HLT.title\" = \"Asetukset...\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Larger\"; ObjectID = \"Yun-AA-OVD\"; */\n\"Yun-AA-OVD.title\" = \"Suurenna\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Display\"; ObjectID = \"aPo-Rp-A1X\"; */\n\"aPo-Rp-A1X.title\" = \"Edellinen näyttö\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Third\"; ObjectID = \"bV9-Ga-jDG\"; */\n\"bV9-Ga-jDG.title\" = \"Edellinen kolmasosa\";\n\n/* Class = \"NSMenuItem\"; title = \"Right Half\"; ObjectID = \"cae-26-Oab\"; */\n\"cae-26-Oab.title\" = \"Oikea puoli\";\n\n/* Class = \"NSMenuItem\"; title = \"Fullscreen\"; ObjectID = \"dwQ-Bl-nEL\"; */\n\"dwQ-Bl-nEL.title\" = \"Koko näyttö\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Left\"; ObjectID = \"eN5-A6-iho\"; */\n\"eN5-A6-iho.title\" = \"Alavasen\";\n\n/* Class = \"NSMenuItem\"; title = \"Disable\"; ObjectID = \"eZT-Mm-qSc\"; */\n\"eZT-Mm-qSc.title\" = \"Poista käytöstä\";\n\n/* Class = \"NSMenu\"; title = \"Disable\"; ObjectID = \"flL-B2-XIP\"; */\n\"flL-B2-XIP.title\" = \"Poista käytöstä\";\n\n/* Class = \"NSButtonCell\"; title = \"Quit Spectacle\"; ObjectID = \"gMV-vD-CUe\"; */\n\"gMV-vD-CUe.title\" = \"Sulje Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Smaller\"; ObjectID = \"gTe-ym-DB0\"; */\n\"gTe-ym-DB0.title\" = \"Pienennä\";\n\n/* Class = \"NSMenuItem\"; title = \"Bottom Half\"; ObjectID = \"huV-Gw-lbX\"; */\n\"huV-Gw-lbX.title\" = \"Alapuoli\";\n\n/* Class = \"NSButtonCell\"; title = \"Open System Preferences\"; ObjectID = \"iPl-AT-Pei\"; */\n\"iPl-AT-Pei.title\" = \"Avaa järjestelmäasetukset\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"l9O-0B-fjp\"; */\n\"l9O-0B-fjp.title\" = \"Kumoa\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Left\"; ObjectID = \"ldc-QO-Cq6\"; */\n\"ldc-QO-Cq6.title\" = \"Ylävasen\";\n\n/* Class = \"NSMenuItem\"; title = \"for APPLICATION\"; ObjectID = \"msZ-id-Pvw\"; */\n\"msZ-id-Pvw.title\" = \"ohjelmassa APPLICATION\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Right\"; ObjectID = \"oDU-J0-NkJ\"; */\n\"oDU-J0-NkJ.title\" = \"Alaoikea\";\n\n/* Class = \"NSMenuItem\"; title = \"for an hour\"; ObjectID = \"qpo-5w-ZIY\"; */\n\"qpo-5w-ZIY.title\" = \"tunniksi\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Grant access to this application in System Preferences.\"; ObjectID = \"ruu-yJ-Q1F\"; */\n\"ruu-yJ-Q1F.title\" = \"Salli pääsy tälle ohjelmalle järjestelmäasetuksissa.\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"xJu-Uo-nZw\"; */\n\"xJu-Uo-nZw.title\" = \"Keskitä\";\n\n/* Class = \"NSMenuItem\"; title = \"Top Half\"; ObjectID = \"yh0-ik-weD\"; */\n\"yh0-ik-weD.title\" = \"Yläpuoli\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/fi.lproj/SpectaclePreferencesWindow.strings",
    "content": "\n/* Class = \"NSTextFieldCell\"; title = \"Make Larger:\"; ObjectID = \"0f9-kj-bro\"; */\n\"0f9-kj-bro.title\" = \"Suurenna:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Control\"; ObjectID = \"7Fe-Da-fYB\"; */\n\"7Fe-Da-fYB.title\" = \"Ctrl\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌃\"; ObjectID = \"806-S1-nYH\"; */\n\"806-S1-nYH.title\" = \"⌃\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Top Half:\"; ObjectID = \"AnP-Lv-Hbd\"; */\n\"AnP-Lv-Hbd.title\" = \"Yläpuoli:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Bottom Half:\"; ObjectID = \"Awn-mO-sht\"; */\n\"Awn-mO-sht.title\" = \"Alapuoli:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Undo:\"; ObjectID = \"CJs-az-eG7\"; */\n\"CJs-az-eG7.title\" = \"Kumoa:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Left Half:\"; ObjectID = \"IWj-rc-Kvi\"; */\n\"IWj-rc-Kvi.title\" = \"Vasen puoli:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⇧\"; ObjectID = \"Ir0-AJ-ldj\"; */\n\"Ir0-AJ-ldj.title\" = \"⇧\";\n\n/* Class = \"NSWindow\"; title = \"Spectacle X.Y.Z\"; ObjectID = \"JW4-q9-L7q\"; */\n\"JW4-q9-L7q.title\" = \"Spectacle X.Y.Z\";\n\n/* Class = \"NSButtonCell\"; title = \"Restore Defaults...\"; ObjectID = \"NT7-Sd-Ofw\"; */\n\"NT7-Sd-Ofw.title\" = \"Palauta oletukset...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Make Smaller:\"; ObjectID = \"SDM-U5-yUR\"; */\n\"SDM-U5-yUR.title\" = \"Pienennä:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌘\"; ObjectID = \"SQM-4e-yFd\"; */\n\"SQM-4e-yFd.title\" = \"⌘\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Third:\"; ObjectID = \"Tze-mR-IV4\"; */\n\"Tze-mR-IV4.title\" = \"Seuraava kolmasosa:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Option\"; ObjectID = \"U0H-hG-KAQ\"; */\n\"U0H-hG-KAQ.title\" = \"Optio\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Right:\"; ObjectID = \"Vul-FT-BbB\"; */\n\"Vul-FT-BbB.title\" = \"Alaoikea:\";\n\n/* Class = \"NSMenu\"; title = \"OtherViews\"; ObjectID = \"W2t-KP-bYJ\"; */\n\"W2t-KP-bYJ.title\" = \"MuutNäkymät\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Right Half:\"; ObjectID = \"WeK-fS-mRh\"; */\n\"WeK-fS-mRh.title\" = \"Oikea puoli:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌥\"; ObjectID = \"YQm-Kc-fYF\"; */\n\"YQm-Kc-fYF.title\" = \"⌥\";\n\n/* Class = \"NSMenuItem\"; title = \"as a background application\"; ObjectID = \"aWf-FC-J1j\"; */\n\"aWf-FC-J1j.title\" = \"taustaohjelmana\";\n\n/* Class = \"NSButtonCell\"; title = \"Launch Spectacle at login\"; ObjectID = \"cEj-mH-kie\"; */\n\"cEj-mH-kie.title\" = \"Käynnistä Spectacle kirjauduttaessa\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Left:\"; ObjectID = \"dQP-TR-GMx\"; */\n\"dQP-TR-GMx.title\" = \"Alavasen:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Shift\"; ObjectID = \"dww-8Q-sa1\"; */\n\"dww-8Q-sa1.title\" = \"Vaihto\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Run...\"; ObjectID = \"eYU-TH-wcO\"; */\n\"eYU-TH-wcO.title\" = \"Suorita...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Right:\"; ObjectID = \"gSY-Au-xOH\"; */\n\"gSY-Au-xOH.title\" = \"Yläoikea:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Display:\"; ObjectID = \"hmL-EC-pro\"; */\n\"hmL-EC-pro.title\" = \"Edellinen näyttö:\";\n\n/* Class = \"NSMenuItem\"; title = \"in the status menu\"; ObjectID = \"in4-v8-tIm\"; */\n\"in4-v8-tIm.title\" = \"valikkopalkissa\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Command\"; ObjectID = \"jdf-Yu-zrq\"; */\n\"jdf-Yu-zrq.title\" = \"Komento\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Left:\"; ObjectID = \"ldH-1E-mKW\"; */\n\"ldH-1E-mKW.title\" = \"Ylävasen:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Display:\"; ObjectID = \"lw7-Ap-kJO\"; */\n\"lw7-Ap-kJO.title\" = \"Seuraava näyttö:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Center:\"; ObjectID = \"oqf-7z-BFa\"; */\n\"oqf-7z-BFa.title\" = \"Keskitys:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Third:\"; ObjectID = \"s3E-Lp-mJ4\"; */\n\"s3E-Lp-mJ4.title\" = \"Edellinen kolmasosa:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Fullscreen:\"; ObjectID = \"tKr-XE-DEU\"; */\n\"tKr-XE-DEU.title\" = \"Koko näyttö:\";\n\n/* Class = \"NSBox\"; title = \"Box\"; ObjectID = \"vWw-ws-BgW\"; */\n\"vWw-ws-BgW.title\" = \"Box\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Redo:\"; ObjectID = \"y7M-cR-DF2\"; */\n\"y7M-cR-DF2.title\" = \"Tee uudelleen:\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/fr.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1348\\cocoasubrtf170\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\n\n\\f0\\b\\fs24 \\cf0 Cr\\'e9dits\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Ic\\'f4nes et autres \\'9cuvres: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Code source disponible sur {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHub}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt \\cf0 @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/fr.lproj/Spectacle.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"187-7k-0Ct\"; */\n\"187-7k-0Ct.title\" = \"Rétablir\";\n\n/* Class = \"NSMenuItem\"; title = \"Check for Updates...\"; ObjectID = \"2sj-vF-eSL\"; */\n\"2sj-vF-eSL.title\" = \"Vérifier les mises à jour...\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Third\"; ObjectID = \"7HO-L3-O6Q\"; */\n\"7HO-L3-O6Q.title\" = \"Tiers suivant\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Right\"; ObjectID = \"C7t-Sf-kOI\"; */\n\"C7t-Sf-kOI.title\" = \"En haut à droite\";\n\n/* Class = \"NSMenuItem\"; title = \"About Spectacle\"; ObjectID = \"EA9-dx-Qfg\"; */\n\"EA9-dx-Qfg.title\" = \"À propos de Spectacle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Spectacle would like to control your windows using accessibility features.\"; ObjectID = \"HRo-tn-M1V\"; */\n\"HRo-tn-M1V.title\" = \"Spectacle souhaite contrôler vos fenêtres à l'aide des fonctionnalités d'accessibilité.\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Display\"; ObjectID = \"I4U-jL-hXq\"; */\n\"I4U-jL-hXq.title\" = \"Écran suivant\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit Spectacle\"; ObjectID = \"Isn-Og-AEv\"; */\n\"Isn-Og-AEv.title\" = \"Quitter Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Left Half\"; ObjectID = \"Jae-vx-7ZC\"; */\n\"Jae-vx-7ZC.title\" = \"Moitié gauche\";\n\n/* Class = \"NSMenu\"; title = \"Spectacle Status Item\"; ObjectID = \"KsA-8w-wcl\"; */\n\"KsA-8w-wcl.title\" = \"Spectacle Status Item\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences...\"; ObjectID = \"ME4-Br-HLT\"; */\n\"ME4-Br-HLT.title\" = \"Préférences...\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Larger\"; ObjectID = \"Yun-AA-OVD\"; */\n\"Yun-AA-OVD.title\" = \"Agrandir\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Display\"; ObjectID = \"aPo-Rp-A1X\"; */\n\"aPo-Rp-A1X.title\" = \"Écran précédent\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Third\"; ObjectID = \"bV9-Ga-jDG\"; */\n\"bV9-Ga-jDG.title\" = \"Tiers précédent\";\n\n/* Class = \"NSMenuItem\"; title = \"Right Half\"; ObjectID = \"cae-26-Oab\"; */\n\"cae-26-Oab.title\" = \"Moitié droit\";\n\n/* Class = \"NSMenuItem\"; title = \"Fullscreen\"; ObjectID = \"dwQ-Bl-nEL\"; */\n\"dwQ-Bl-nEL.title\" = \"Plein écran\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Left\"; ObjectID = \"eN5-A6-iho\"; */\n\"eN5-A6-iho.title\" = \"En bas à gauche\";\n\n/* Class = \"NSMenuItem\"; title = \"Disable\"; ObjectID = \"eZT-Mm-qSc\"; */\n\"eZT-Mm-qSc.title\" = \"Désactiver\";\n\n/* Class = \"NSMenu\"; title = \"Disable\"; ObjectID = \"flL-B2-XIP\"; */\n\"flL-B2-XIP.title\" = \"Désactiver\";\n\n/* Class = \"NSButtonCell\"; title = \"Quit Spectacle\"; ObjectID = \"gMV-vD-CUe\"; */\n\"gMV-vD-CUe.title\" = \"Quitter Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Smaller\"; ObjectID = \"gTe-ym-DB0\"; */\n\"gTe-ym-DB0.title\" = \"Réduire\";\n\n/* Class = \"NSMenuItem\"; title = \"Bottom Half\"; ObjectID = \"huV-Gw-lbX\"; */\n\"huV-Gw-lbX.title\" = \"Moitié bas\";\n\n/* Class = \"NSButtonCell\"; title = \"Open System Preferences\"; ObjectID = \"iPl-AT-Pei\"; */\n\"iPl-AT-Pei.title\" = \"Ouvrir Préférences Système\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"l9O-0B-fjp\"; */\n\"l9O-0B-fjp.title\" = \"Annuler\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Left\"; ObjectID = \"ldc-QO-Cq6\"; */\n\"ldc-QO-Cq6.title\" = \"En haut à gauche\";\n\n/* Class = \"NSMenuItem\"; title = \"for APPLICATION\"; ObjectID = \"msZ-id-Pvw\"; */\n\"msZ-id-Pvw.title\" = \"for APPLICATION\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Right\"; ObjectID = \"oDU-J0-NkJ\"; */\n\"oDU-J0-NkJ.title\" = \"En bas à droite\";\n\n/* Class = \"NSMenuItem\"; title = \"for an hour\"; ObjectID = \"qpo-5w-ZIY\"; */\n\"qpo-5w-ZIY.title\" = \"pour 1 heure\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Grant access to this application in System Preferences.\"; ObjectID = \"ruu-yJ-Q1F\"; */\n\"ruu-yJ-Q1F.title\" = \"Accorder l'accès à cette application dans les Préférences Système.\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"xJu-Uo-nZw\"; */\n\"xJu-Uo-nZw.title\" = \"Centrer\";\n\n/* Class = \"NSMenuItem\"; title = \"Top Half\"; ObjectID = \"yh0-ik-weD\"; */\n\"yh0-ik-weD.title\" = \"Moitié haut\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/fr.lproj/SpectaclePreferencesWindow.strings",
    "content": "\n/* Class = \"NSTextFieldCell\"; title = \"Make Larger:\"; ObjectID = \"0f9-kj-bro\"; */\n\"0f9-kj-bro.title\" = \"Agrandir:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Control\"; ObjectID = \"7Fe-Da-fYB\"; */\n\"7Fe-Da-fYB.title\" = \"Contrôle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌃\"; ObjectID = \"806-S1-nYH\"; */\n\"806-S1-nYH.title\" = \"⌃\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Top Half:\"; ObjectID = \"AnP-Lv-Hbd\"; */\n\"AnP-Lv-Hbd.title\" = \"Moitié haut:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Bottom Half:\"; ObjectID = \"Awn-mO-sht\"; */\n\"Awn-mO-sht.title\" = \"Moitié bas:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Undo:\"; ObjectID = \"CJs-az-eG7\"; */\n\"CJs-az-eG7.title\" = \"Annuler:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Left Half:\"; ObjectID = \"IWj-rc-Kvi\"; */\n\"IWj-rc-Kvi.title\" = \"Moitié gauche:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⇧\"; ObjectID = \"Ir0-AJ-ldj\"; */\n\"Ir0-AJ-ldj.title\" = \"⇧\";\n\n/* Class = \"NSWindow\"; title = \"Spectacle X.Y.Z\"; ObjectID = \"JW4-q9-L7q\"; */\n\"JW4-q9-L7q.title\" = \"Spectacle X.Y.Z\";\n\n/* Class = \"NSButtonCell\"; title = \"Restore Defaults...\"; ObjectID = \"NT7-Sd-Ofw\"; */\n\"NT7-Sd-Ofw.title\" = \"Rétablir par défaut...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Make Smaller:\"; ObjectID = \"SDM-U5-yUR\"; */\n\"SDM-U5-yUR.title\" = \"Réduire:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌘\"; ObjectID = \"SQM-4e-yFd\"; */\n\"SQM-4e-yFd.title\" = \"⌘\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Third:\"; ObjectID = \"Tze-mR-IV4\"; */\n\"Tze-mR-IV4.title\" = \"Tiers suivant:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Option\"; ObjectID = \"U0H-hG-KAQ\"; */\n\"U0H-hG-KAQ.title\" = \"Option\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Right:\"; ObjectID = \"Vul-FT-BbB\"; */\n\"Vul-FT-BbB.title\" = \"En bas à droite:\";\n\n/* Class = \"NSMenu\"; title = \"OtherViews\"; ObjectID = \"W2t-KP-bYJ\"; */\n\"W2t-KP-bYJ.title\" = \"OtherViews\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Right Half:\"; ObjectID = \"WeK-fS-mRh\"; */\n\"WeK-fS-mRh.title\" = \"Moitié droit:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌥\"; ObjectID = \"YQm-Kc-fYF\"; */\n\"YQm-Kc-fYF.title\" = \"⌥\";\n\n/* Class = \"NSMenuItem\"; title = \"as a background application\"; ObjectID = \"aWf-FC-J1j\"; */\n\"aWf-FC-J1j.title\" = \"comme une application d'arrière-plan\";\n\n/* Class = \"NSButtonCell\"; title = \"Launch Spectacle at login\"; ObjectID = \"cEj-mH-kie\"; */\n\"cEj-mH-kie.title\" = \"Ouvrir Spectacle au démarrage\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Left:\"; ObjectID = \"dQP-TR-GMx\"; */\n\"dQP-TR-GMx.title\" = \"En bas à gauche:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Shift\"; ObjectID = \"dww-8Q-sa1\"; */\n\"dww-8Q-sa1.title\" = \"Maj\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Run...\"; ObjectID = \"eYU-TH-wcO\"; */\n\"eYU-TH-wcO.title\" = \"Lancer...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Right:\"; ObjectID = \"gSY-Au-xOH\"; */\n\"gSY-Au-xOH.title\" = \"En haut à droite:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Display:\"; ObjectID = \"hmL-EC-pro\"; */\n\"hmL-EC-pro.title\" = \"Écran précédent:\";\n\n/* Class = \"NSMenuItem\"; title = \"in the status menu\"; ObjectID = \"in4-v8-tIm\"; */\n\"in4-v8-tIm.title\" = \"dans la barre d'état\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Command\"; ObjectID = \"jdf-Yu-zrq\"; */\n\"jdf-Yu-zrq.title\" = \"Commande\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Left:\"; ObjectID = \"ldH-1E-mKW\"; */\n\"ldH-1E-mKW.title\" = \"En haut à gauche:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Display:\"; ObjectID = \"lw7-Ap-kJO\"; */\n\"lw7-Ap-kJO.title\" = \"Écran suivant:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Center:\"; ObjectID = \"oqf-7z-BFa\"; */\n\"oqf-7z-BFa.title\" = \"Centrer:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Third:\"; ObjectID = \"s3E-Lp-mJ4\"; */\n\"s3E-Lp-mJ4.title\" = \"Tiers précédent:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Fullscreen:\"; ObjectID = \"tKr-XE-DEU\"; */\n\"tKr-XE-DEU.title\" = \"Plein écran:\";\n\n/* Class = \"NSBox\"; title = \"Box\"; ObjectID = \"vWw-ws-BgW\"; */\n\"vWw-ws-BgW.title\" = \"Box\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Redo:\"; ObjectID = \"y7M-cR-DF2\"; */\n\"y7M-cR-DF2.title\" = \"Rétablir:\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/it.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1348\\cocoasubrtf170\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\n\n\\f0\\b\\fs24 \\cf0 Riconoscimenti\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Icone ed altri elementi grafici: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n\\cf0 Codice sorgente disponibile su {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHub}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt \\cf0 @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/it.lproj/Spectacle.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"187-7k-0Ct\"; */\n\"187-7k-0Ct.title\" = \"Ripristina\";\n\n/* Class = \"NSMenuItem\"; title = \"Check for Updates...\"; ObjectID = \"2sj-vF-eSL\"; */\n\"2sj-vF-eSL.title\" = \"Verifica aggiornamenti…\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Third\"; ObjectID = \"7HO-L3-O6Q\"; */\n\"7HO-L3-O6Q.title\" = \"Terza successiva\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Right\"; ObjectID = \"C7t-Sf-kOI\"; */\n\"C7t-Sf-kOI.title\" = \"In alto a destra\";\n\n/* Class = \"NSMenuItem\"; title = \"About Spectacle\"; ObjectID = \"EA9-dx-Qfg\"; */\n\"EA9-dx-Qfg.title\" = \"Informazioni su Spectacle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Spectacle would like to control your windows using accessibility features.\"; ObjectID = \"HRo-tn-M1V\"; */\n\"HRo-tn-M1V.title\" = \"Spectacle vorrebbe controllare le tue finestre usando le funzioni di accessibilità.\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Display\"; ObjectID = \"I4U-jL-hXq\"; */\n\"I4U-jL-hXq.title\" = \"Monitor successivo\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit Spectacle\"; ObjectID = \"Isn-Og-AEv\"; */\n\"Isn-Og-AEv.title\" = \"Esci da Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Left Half\"; ObjectID = \"Jae-vx-7ZC\"; */\n\"Jae-vx-7ZC.title\" = \"Metà sinistra\";\n\n/* Class = \"NSMenu\"; title = \"Spectacle Status Item\"; ObjectID = \"KsA-8w-wcl\"; */\n\"KsA-8w-wcl.title\" = \"Spectacle Status Item\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences...\"; ObjectID = \"ME4-Br-HLT\"; */\n\"ME4-Br-HLT.title\" = \"Preferenze…\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Larger\"; ObjectID = \"Yun-AA-OVD\"; */\n\"Yun-AA-OVD.title\" = \"Ingrandisci\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Display\"; ObjectID = \"aPo-Rp-A1X\"; */\n\"aPo-Rp-A1X.title\" = \"Monitor precedente\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Third\"; ObjectID = \"bV9-Ga-jDG\"; */\n\"bV9-Ga-jDG.title\" = \"Terza precedente\";\n\n/* Class = \"NSMenuItem\"; title = \"Right Half\"; ObjectID = \"cae-26-Oab\"; */\n\"cae-26-Oab.title\" = \"Metà destra\";\n\n/* Class = \"NSMenuItem\"; title = \"Fullscreen\"; ObjectID = \"dwQ-Bl-nEL\"; */\n\"dwQ-Bl-nEL.title\" = \"A tutto schermo\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Left\"; ObjectID = \"eN5-A6-iho\"; */\n\"eN5-A6-iho.title\" = \"In basso a sinistra\";\n\n/* Class = \"NSMenuItem\"; title = \"Disable\"; ObjectID = \"eZT-Mm-qSc\"; */\n\"eZT-Mm-qSc.title\" = \"Disattiva\";\n\n/* Class = \"NSMenu\"; title = \"Disable\"; ObjectID = \"flL-B2-XIP\"; */\n\"flL-B2-XIP.title\" = \"Disattiva\";\n\n/* Class = \"NSButtonCell\"; title = \"Quit Spectacle\"; ObjectID = \"gMV-vD-CUe\"; */\n\"gMV-vD-CUe.title\" = \"Esci da Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Smaller\"; ObjectID = \"gTe-ym-DB0\"; */\n\"gTe-ym-DB0.title\" = \"Riduci\";\n\n/* Class = \"NSMenuItem\"; title = \"Bottom Half\"; ObjectID = \"huV-Gw-lbX\"; */\n\"huV-Gw-lbX.title\" = \"Metà bassa\";\n\n/* Class = \"NSButtonCell\"; title = \"Open System Preferences\"; ObjectID = \"iPl-AT-Pei\"; */\n\"iPl-AT-Pei.title\" = \"Apri Preferenze di Sistema\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"l9O-0B-fjp\"; */\n\"l9O-0B-fjp.title\" = \"Annulla\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Left\"; ObjectID = \"ldc-QO-Cq6\"; */\n\"ldc-QO-Cq6.title\" = \"In alto a sinistra\";\n\n/* Class = \"NSMenuItem\"; title = \"for APPLICATION\"; ObjectID = \"msZ-id-Pvw\"; */\n\"msZ-id-Pvw.title\" = \"per APPLICATION\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Right\"; ObjectID = \"oDU-J0-NkJ\"; */\n\"oDU-J0-NkJ.title\" = \"In basso a destra\";\n\n/* Class = \"NSMenuItem\"; title = \"for an hour\"; ObjectID = \"qpo-5w-ZIY\"; */\n\"qpo-5w-ZIY.title\" = \"per un'ora\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Grant access to this application in System Preferences.\"; ObjectID = \"ruu-yJ-Q1F\"; */\n\"ruu-yJ-Q1F.title\" = \"Concedere l'accesso a questa applicazione nelle Preferenze di Sistema.\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"xJu-Uo-nZw\"; */\n\"xJu-Uo-nZw.title\" = \"Centra\";\n\n/* Class = \"NSMenuItem\"; title = \"Top Half\"; ObjectID = \"yh0-ik-weD\"; */\n\"yh0-ik-weD.title\" = \"Metà alta\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/it.lproj/SpectaclePreferencesWindow.strings",
    "content": "\n/* Class = \"NSTextFieldCell\"; title = \"Make Larger:\"; ObjectID = \"0f9-kj-bro\"; */\n\"0f9-kj-bro.title\" = \"Ingrandisci:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Control\"; ObjectID = \"7Fe-Da-fYB\"; */\n\"7Fe-Da-fYB.title\" = \"Control\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌃\"; ObjectID = \"806-S1-nYH\"; */\n\"806-S1-nYH.title\" = \"⌃\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Top Half:\"; ObjectID = \"AnP-Lv-Hbd\"; */\n\"AnP-Lv-Hbd.title\" = \"Metà alta:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Bottom Half:\"; ObjectID = \"Awn-mO-sht\"; */\n\"Awn-mO-sht.title\" = \"Metà bassa:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Undo:\"; ObjectID = \"CJs-az-eG7\"; */\n\"CJs-az-eG7.title\" = \"Annulla:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Left Half:\"; ObjectID = \"IWj-rc-Kvi\"; */\n\"IWj-rc-Kvi.title\" = \"Metà sinistra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⇧\"; ObjectID = \"Ir0-AJ-ldj\"; */\n\"Ir0-AJ-ldj.title\" = \"⇧\";\n\n/* Class = \"NSWindow\"; title = \"Spectacle X.Y.Z\"; ObjectID = \"JW4-q9-L7q\"; */\n\"JW4-q9-L7q.title\" = \"Spectacle X.Y.Z\";\n\n/* Class = \"NSButtonCell\"; title = \"Restore Defaults...\"; ObjectID = \"NT7-Sd-Ofw\"; */\n\"NT7-Sd-Ofw.title\" = \"Ripristina predefiniti…\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Make Smaller:\"; ObjectID = \"SDM-U5-yUR\"; */\n\"SDM-U5-yUR.title\" = \"Riduci:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌘\"; ObjectID = \"SQM-4e-yFd\"; */\n\"SQM-4e-yFd.title\" = \"⌘\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Third:\"; ObjectID = \"Tze-mR-IV4\"; */\n\"Tze-mR-IV4.title\" = \"Terza successiva:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Option\"; ObjectID = \"U0H-hG-KAQ\"; */\n\"U0H-hG-KAQ.title\" = \"Opzione\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Right:\"; ObjectID = \"Vul-FT-BbB\"; */\n\"Vul-FT-BbB.title\" = \"In basso a destra:\";\n\n/* Class = \"NSMenu\"; title = \"OtherViews\"; ObjectID = \"W2t-KP-bYJ\"; */\n\"W2t-KP-bYJ.title\" = \"OtherViews\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Right Half:\"; ObjectID = \"WeK-fS-mRh\"; */\n\"WeK-fS-mRh.title\" = \"Metà destra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌥\"; ObjectID = \"YQm-Kc-fYF\"; */\n\"YQm-Kc-fYF.title\" = \"⌥\";\n\n/* Class = \"NSMenuItem\"; title = \"as a background application\"; ObjectID = \"aWf-FC-J1j\"; */\n\"aWf-FC-J1j.title\" = \"come applicazione in background\";\n\n/* Class = \"NSButtonCell\"; title = \"Launch Spectacle at login\"; ObjectID = \"cEj-mH-kie\"; */\n\"cEj-mH-kie.title\" = \"Apri Spectacle al login\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Left:\"; ObjectID = \"dQP-TR-GMx\"; */\n\"dQP-TR-GMx.title\" = \"In basso a sinistra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Shift\"; ObjectID = \"dww-8Q-sa1\"; */\n\"dww-8Q-sa1.title\" = \"Maiuscole\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Run...\"; ObjectID = \"eYU-TH-wcO\"; */\n\"eYU-TH-wcO.title\" = \"Esegui…\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Right:\"; ObjectID = \"gSY-Au-xOH\"; */\n\"gSY-Au-xOH.title\" = \"In alto a destra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Display:\"; ObjectID = \"hmL-EC-pro\"; */\n\"hmL-EC-pro.title\" = \"Monitor precedente:\";\n\n/* Class = \"NSMenuItem\"; title = \"in the status menu\"; ObjectID = \"in4-v8-tIm\"; */\n\"in4-v8-tIm.title\" = \"nel menu di stato\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Command\"; ObjectID = \"jdf-Yu-zrq\"; */\n\"jdf-Yu-zrq.title\" = \"Comando\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Left:\"; ObjectID = \"ldH-1E-mKW\"; */\n\"ldH-1E-mKW.title\" = \"In alto a sinistra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Display:\"; ObjectID = \"lw7-Ap-kJO\"; */\n\"lw7-Ap-kJO.title\" = \"Monitor successivo:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Center:\"; ObjectID = \"oqf-7z-BFa\"; */\n\"oqf-7z-BFa.title\" = \"Centra:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Third:\"; ObjectID = \"s3E-Lp-mJ4\"; */\n\"s3E-Lp-mJ4.title\" = \"Terza precedente:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Fullscreen:\"; ObjectID = \"tKr-XE-DEU\"; */\n\"tKr-XE-DEU.title\" = \"A tutto schermo:\";\n\n/* Class = \"NSBox\"; title = \"Box\"; ObjectID = \"vWw-ws-BgW\"; */\n\"vWw-ws-BgW.title\" = \"Box\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Redo:\"; ObjectID = \"y7M-cR-DF2\"; */\n\"y7M-cR-DF2.title\" = \"Ripristina:\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/pt.lproj/Credits.rtf",
    "content": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1348\\cocoasubrtf170\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\margl1440\\margr1440\\vieww11300\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\qc\\partightenfactor0\n\n\\f0\\b\\fs24 \\cf0 Cr\\'e9ditos\n\\b0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 \\'cdcones e outras ilustra\\'e7\\'f5es: {\\field{\\*\\fldinst{HYPERLINK \"http://iiro.jappinen.fi\"}}{\\fldrslt \n\\b Iiro J\\'e4ppinen}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\b0 \\cf0 \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\\cf0 C\\'f3digo fonte dispon\\'edvel no {\\field{\\*\\fldinst{HYPERLINK \"https://github.com/eczarny/spectacle\"}}{\\fldrslt \n\\b GitHub}}\n\\b \\\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\n{\\field{\\*\\fldinst{HYPERLINK \"https://twitter.com/spectacleapp\"}}{\\fldrslt \\cf0 @spectacleapp}}\\\n}"
  },
  {
    "path": "Spectacle/Resources/Localizations/pt.lproj/Spectacle.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"187-7k-0Ct\"; */\n\"187-7k-0Ct.title\" = \"Refazer\";\n\n/* Class = \"NSMenuItem\"; title = \"Check for Updates...\"; ObjectID = \"2sj-vF-eSL\"; */\n\"2sj-vF-eSL.title\" = \"Buscar Atualizações...\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Third\"; ObjectID = \"7HO-L3-O6Q\"; */\n\"7HO-L3-O6Q.title\" = \"Terço Seguinte\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Right\"; ObjectID = \"C7t-Sf-kOI\"; */\n\"C7t-Sf-kOI.title\" = \"Direita Superior\";\n\n/* Class = \"NSMenuItem\"; title = \"About Spectacle\"; ObjectID = \"EA9-dx-Qfg\"; */\n\"EA9-dx-Qfg.title\" = \"Sobre o Spectacle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Spectacle would like to control your windows using accessibility features.\"; ObjectID = \"HRo-tn-M1V\"; */\n\"HRo-tn-M1V.title\" = \"O Spectacle deseja controlar as janelas usando recursos de acessibilidade.\";\n\n/* Class = \"NSMenuItem\"; title = \"Next Display\"; ObjectID = \"I4U-jL-hXq\"; */\n\"I4U-jL-hXq.title\" = \"Monitor Seguinte\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit Spectacle\"; ObjectID = \"Isn-Og-AEv\"; */\n\"Isn-Og-AEv.title\" = \"Encerrar Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Left Half\"; ObjectID = \"Jae-vx-7ZC\"; */\n\"Jae-vx-7ZC.title\" = \"Metade Esquerda\";\n\n/* Class = \"NSMenu\"; title = \"Spectacle Status Item\"; ObjectID = \"KsA-8w-wcl\"; */\n\"KsA-8w-wcl.title\" = \"Spectacle Status Item\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences...\"; ObjectID = \"ME4-Br-HLT\"; */\n\"ME4-Br-HLT.title\" = \"Preferências...\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Larger\"; ObjectID = \"Yun-AA-OVD\"; */\n\"Yun-AA-OVD.title\" = \"Aumentar\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Display\"; ObjectID = \"aPo-Rp-A1X\"; */\n\"aPo-Rp-A1X.title\" = \"Monitor Anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Previous Third\"; ObjectID = \"bV9-Ga-jDG\"; */\n\"bV9-Ga-jDG.title\" = \"Terço Anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Right Half\"; ObjectID = \"cae-26-Oab\"; */\n\"cae-26-Oab.title\" = \"Metade Direita\";\n\n/* Class = \"NSMenuItem\"; title = \"Fullscreen\"; ObjectID = \"dwQ-Bl-nEL\"; */\n\"dwQ-Bl-nEL.title\" = \"Preencher Tela\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Left\"; ObjectID = \"eN5-A6-iho\"; */\n\"eN5-A6-iho.title\" = \"Esquerda Inferior\";\n\n/* Class = \"NSMenuItem\"; title = \"Disable\"; ObjectID = \"eZT-Mm-qSc\"; */\n\"eZT-Mm-qSc.title\" = \"Desativar\";\n\n/* Class = \"NSMenu\"; title = \"Disable\"; ObjectID = \"flL-B2-XIP\"; */\n\"flL-B2-XIP.title\" = \"Desativar\";\n\n/* Class = \"NSButtonCell\"; title = \"Quit Spectacle\"; ObjectID = \"gMV-vD-CUe\"; */\n\"gMV-vD-CUe.title\" = \"Encerrar Spectacle\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Smaller\"; ObjectID = \"gTe-ym-DB0\"; */\n\"gTe-ym-DB0.title\" = \"Diminuir\";\n\n/* Class = \"NSMenuItem\"; title = \"Bottom Half\"; ObjectID = \"huV-Gw-lbX\"; */\n\"huV-Gw-lbX.title\" = \"Metade Inferior\";\n\n/* Class = \"NSButtonCell\"; title = \"Open System Preferences\"; ObjectID = \"iPl-AT-Pei\"; */\n\"iPl-AT-Pei.title\" = \"Abrir Preferências do Sistema\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"l9O-0B-fjp\"; */\n\"l9O-0B-fjp.title\" = \"Desfazer\";\n\n/* Class = \"NSMenuItem\"; title = \"Upper Left\"; ObjectID = \"ldc-QO-Cq6\"; */\n\"ldc-QO-Cq6.title\" = \"Esquerda Superior\";\n\n/* Class = \"NSMenuItem\"; title = \"for APPLICATION\"; ObjectID = \"msZ-id-Pvw\"; */\n\"msZ-id-Pvw.title\" = \"no APPLICATION\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower Right\"; ObjectID = \"oDU-J0-NkJ\"; */\n\"oDU-J0-NkJ.title\" = \"Direita Inferior\";\n\n/* Class = \"NSMenuItem\"; title = \"for an hour\"; ObjectID = \"qpo-5w-ZIY\"; */\n\"qpo-5w-ZIY.title\" = \"por uma hora\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Grant access to this application in System Preferences.\"; ObjectID = \"ruu-yJ-Q1F\"; */\n\"ruu-yJ-Q1F.title\" = \"Conceda acesso a este aplicativo nas Preferências do Sistema.\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"xJu-Uo-nZw\"; */\n\"xJu-Uo-nZw.title\" = \"Centralizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Top Half\"; ObjectID = \"yh0-ik-weD\"; */\n\"yh0-ik-weD.title\" = \"Metade Superior\";\n"
  },
  {
    "path": "Spectacle/Resources/Localizations/pt.lproj/SpectaclePreferencesWindow.strings",
    "content": "\n/* Class = \"NSTextFieldCell\"; title = \"Make Larger:\"; ObjectID = \"0f9-kj-bro\"; */\n\"0f9-kj-bro.title\" = \"Aumentar:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Control\"; ObjectID = \"7Fe-Da-fYB\"; */\n\"7Fe-Da-fYB.title\" = \"Controle\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌃\"; ObjectID = \"806-S1-nYH\"; */\n\"806-S1-nYH.title\" = \"⌃\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Top Half:\"; ObjectID = \"AnP-Lv-Hbd\"; */\n\"AnP-Lv-Hbd.title\" = \"Metade Superior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Bottom Half:\"; ObjectID = \"Awn-mO-sht\"; */\n\"Awn-mO-sht.title\" = \"Metade Inferior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Undo:\"; ObjectID = \"CJs-az-eG7\"; */\n\"CJs-az-eG7.title\" = \"Desfazer:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Left Half:\"; ObjectID = \"IWj-rc-Kvi\"; */\n\"IWj-rc-Kvi.title\" = \"Metade Esquerda:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⇧\"; ObjectID = \"Ir0-AJ-ldj\"; */\n\"Ir0-AJ-ldj.title\" = \"⇧\";\n\n/* Class = \"NSWindow\"; title = \"Spectacle X.Y.Z\"; ObjectID = \"JW4-q9-L7q\"; */\n\"JW4-q9-L7q.title\" = \"Spectacle X.Y.Z\";\n\n/* Class = \"NSButtonCell\"; title = \"Restore Defaults...\"; ObjectID = \"NT7-Sd-Ofw\"; */\n\"NT7-Sd-Ofw.title\" = \"Restaurar Padrões...\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Make Smaller:\"; ObjectID = \"SDM-U5-yUR\"; */\n\"SDM-U5-yUR.title\" = \"Diminuir:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌘\"; ObjectID = \"SQM-4e-yFd\"; */\n\"SQM-4e-yFd.title\" = \"⌘\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Third:\"; ObjectID = \"Tze-mR-IV4\"; */\n\"Tze-mR-IV4.title\" = \"Terço Seguinte:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Option\"; ObjectID = \"U0H-hG-KAQ\"; */\n\"U0H-hG-KAQ.title\" = \"Opção\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Right:\"; ObjectID = \"Vul-FT-BbB\"; */\n\"Vul-FT-BbB.title\" = \"Direita Inferior:\";\n\n/* Class = \"NSMenu\"; title = \"OtherViews\"; ObjectID = \"W2t-KP-bYJ\"; */\n\"W2t-KP-bYJ.title\" = \"OtherViews\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Right Half:\"; ObjectID = \"WeK-fS-mRh\"; */\n\"WeK-fS-mRh.title\" = \"Metade Direita:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"⌥\"; ObjectID = \"YQm-Kc-fYF\"; */\n\"YQm-Kc-fYF.title\" = \"⌥\";\n\n/* Class = \"NSMenuItem\"; title = \"as a background application\"; ObjectID = \"aWf-FC-J1j\"; */\n\"aWf-FC-J1j.title\" = \"em 2º plano\";\n\n/* Class = \"NSButtonCell\"; title = \"Launch Spectacle at login\"; ObjectID = \"cEj-mH-kie\"; */\n\"cEj-mH-kie.title\" = \"Abrir ao iniciar a sessão\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Lower Left:\"; ObjectID = \"dQP-TR-GMx\"; */\n\"dQP-TR-GMx.title\" = \"Esquerda Inferior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Shift\"; ObjectID = \"dww-8Q-sa1\"; */\n\"dww-8Q-sa1.title\" = \"Maiúsculas\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Run...\"; ObjectID = \"eYU-TH-wcO\"; */\n\"eYU-TH-wcO.title\" = \"Manter:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Right:\"; ObjectID = \"gSY-Au-xOH\"; */\n\"gSY-Au-xOH.title\" = \"Direita Superior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Display:\"; ObjectID = \"hmL-EC-pro\"; */\n\"hmL-EC-pro.title\" = \"Monitor Anterior:\";\n\n/* Class = \"NSMenuItem\"; title = \"in the status menu\"; ObjectID = \"in4-v8-tIm\"; */\n\"in4-v8-tIm.title\" = \"na barra de menus\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Command\"; ObjectID = \"jdf-Yu-zrq\"; */\n\"jdf-Yu-zrq.title\" = \"Comando\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Upper Left:\"; ObjectID = \"ldH-1E-mKW\"; */\n\"ldH-1E-mKW.title\" = \"Esquerda Superior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Next Display:\"; ObjectID = \"lw7-Ap-kJO\"; */\n\"lw7-Ap-kJO.title\" = \"Monitor Seguinte:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Center:\"; ObjectID = \"oqf-7z-BFa\"; */\n\"oqf-7z-BFa.title\" = \"Centralizar:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Previous Third:\"; ObjectID = \"s3E-Lp-mJ4\"; */\n\"s3E-Lp-mJ4.title\" = \"Terço Anterior:\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Fullscreen:\"; ObjectID = \"tKr-XE-DEU\"; */\n\"tKr-XE-DEU.title\" = \"Preencher Tela:\";\n\n/* Class = \"NSBox\"; title = \"Box\"; ObjectID = \"vWw-ws-BgW\"; */\n\"vWw-ws-BgW.title\" = \"Box\";\n\n/* Class = \"NSTextFieldCell\"; title = \"Redo:\"; ObjectID = \"y7M-cR-DF2\"; */\n\"y7M-cR-DF2.title\" = \"Refazer:\";\n"
  },
  {
    "path": "Spectacle/Resources/Property Lists/Defaults.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>AutomaticUpdateCheckEnabled</key>\n\t<true/>\n\t<key>BackgroundAlertSuppressed</key>\n\t<false/>\n\t<key>BlacklistedApplications</key>\n\t<array>\n\t\t<string>com.adobe.Photoshop</string>\n\t\t<string>com.divisiblebyzero.Spectacle</string>\n\t\t<string>com.valvesoftware.steam</string>\n\t</array>\n\t<key>DisabledApplications</key>\n\t<array/>\n\t<key>StatusItemEnabled</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleBottomHalfWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneHalfRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneHalfRect.height = Math.floor(oneHalfRect.height / 2.0);\n    if (Math.abs(CGRectGetMidX(windowRect) - CGRectGetMidX(oneHalfRect)) <= 1.0) {\n        var twoThirdsRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n        twoThirdsRect.height = Math.floor(visibleFrameOfDestinationScreen.height * 2 / 3.0);\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneHalfRect, windowRect)) {\n            return twoThirdsRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdsRect, windowRect)) {\n            var oneThirdRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n            oneThirdRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 3.0);\n            return oneThirdRect;\n        }\n    }\n    return oneHalfRect;\n}, \"SpectacleWindowActionBottomHalf\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleCenterWindowCalculation.js",
    "content": "var SpectacleCenterWindowCalculation = (function () {\n    var centerWindowRectInVisibleFrameOfScreen = function(windowRect, visibleFrameOfScreen) {\n        var calculatedWindowRect = SpectacleCalculationHelpers.copyRect(windowRect);\n        calculatedWindowRect.x = Math.round((visibleFrameOfScreen.width - windowRect.width) / 2.0) + visibleFrameOfScreen.x;\n        calculatedWindowRect.y = Math.round((visibleFrameOfScreen.height - windowRect.height) / 2.0) + visibleFrameOfScreen.y;\n        return calculatedWindowRect;\n    };\n    return {\n        centerWindowRectInVisibleFrameOfScreen: centerWindowRectInVisibleFrameOfScreen,\n    };\n})();\n\nwindowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleCenterWindowCalculation.centerWindowRectInVisibleFrameOfScreen(windowRect, visibleFrameOfDestinationScreen);\n}, \"SpectacleWindowActionCenter\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleFullscreenWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return visibleFrameOfDestinationScreen;\n}, \"SpectacleWindowActionFullscreen\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleLargerWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleWindowSizeAdjuster.resizeWindowRect(windowRect, visibleFrameOfDestinationScreen, 30.0);\n}, \"SpectacleWindowActionLarger\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleLeftHalfWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneHalfRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneHalfRect.width = Math.floor(oneHalfRect.width / 2.0);\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneHalfRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneHalfRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            return oneThirdsRect;\n        }\n    }\n    return oneHalfRect;\n}, \"SpectacleWindowActionLeftHalf\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleLowerLeftWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneQuarterRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneQuarterRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 2.0);\n    oneQuarterRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 2.0);\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneQuarterRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneQuarterRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            return oneThirdsRect;\n        }\n    }\n    return oneQuarterRect;\n}, \"SpectacleWindowActionLowerLeft\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleLowerRightWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneQuarterRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneQuarterRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 2.0);\n    oneQuarterRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 2.0);\n    oneQuarterRect.x += oneQuarterRect.width;\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneQuarterRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        twoThirdRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - twoThirdRect.width;\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneQuarterRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            oneThirdsRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - oneThirdsRect.width;\n            return oneThirdsRect;\n        }\n    }\n    return oneQuarterRect;\n}, \"SpectacleWindowActionLowerRight\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleNextDisplayWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleNextOrPreviousDisplay.moveWindowRectToDisplay(windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen);\n}, \"SpectacleWindowActionNextDisplay\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleNextOrPreviousDisplay.js",
    "content": "var SpectacleNextOrPreviousDisplay = (function () {\n    var moveWindowRectToDisplay = function(windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n        if (SpectacleCalculationHelpers.rectFitsWithinRect(windowRect, visibleFrameOfDestinationScreen)) {\n            return SpectacleCenterWindowCalculation.centerWindowRectInVisibleFrameOfScreen(windowRect, visibleFrameOfDestinationScreen);\n        } else {\n            return visibleFrameOfDestinationScreen;\n        }\n    };\n    return {\n        moveWindowRectToDisplay: moveWindowRectToDisplay,\n    };\n})();\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleNextOrPreviousThirds.js",
    "content": "var SpectacleNextOrPreviousThirds = (function () {\n    var findNextThird = function(windowRect, visibleFrameOfDestinationScreen) {\n        var thirds = thirdsFromVisibleFrameOfScreen(visibleFrameOfDestinationScreen);\n        var result = thirds[0];\n        for (var i = 0; i < thirds.length; i++) {\n            var third = thirds[i];\n            if (SpectacleCalculationHelpers.rectCenteredWithinRect(third, windowRect)) {\n                var j = i;\n                if (++j >= thirds.length) {\n                    j = 0;\n                }\n                result = thirds[j];\n                break;\n            }\n        }\n        return result;\n    };\n    var findPreviousThird = function(windowRect, visibleFrameOfDestinationScreen) {\n        var thirds = thirdsFromVisibleFrameOfScreen(visibleFrameOfDestinationScreen);\n        var result = thirds[0];\n        for (var i = 0; i < thirds.length; i++) {\n            var third = thirds[i];\n            if (SpectacleCalculationHelpers.rectCenteredWithinRect(third, windowRect)) {\n                var j = i;\n                if (--j < 0) {\n                    j = thirds.length - 1;\n                }\n                result = thirds[j];\n                break;\n            }\n        }\n        return result;\n    };\n    var thirdsFromVisibleFrameOfScreen = function(visibleFrameOfDestinationScreen) {\n        var thirds = [];\n        for (var i = 0; i < 3; i++) {\n            var third = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n            third.x = visibleFrameOfDestinationScreen.x + (Math.floor(visibleFrameOfDestinationScreen.width / 3.0) * i);\n            third.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            thirds.push(third);\n        }\n        for (var i = 0; i < 3; i++) {\n            var third = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n            third.y = visibleFrameOfDestinationScreen.y + visibleFrameOfDestinationScreen.height - (Math.floor(visibleFrameOfDestinationScreen.height / 3.0) * (i + 1));\n            third.height = Math.floor(visibleFrameOfDestinationScreen.height / 3.0);\n            thirds.push(third);\n        }\n        return thirds;\n    };\n    return {\n        findNextThird: findNextThird,\n        findPreviousThird: findPreviousThird,\n    };\n})();\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleNextThirdWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleNextOrPreviousThirds.findNextThird(windowRect, visibleFrameOfDestinationScreen);\n}, \"SpectacleWindowActionNextThird\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectaclePreviousDisplayWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleNextOrPreviousDisplay.moveWindowRectToDisplay(windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen);\n}, \"SpectacleWindowActionPreviousDisplay\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectaclePreviousThirdWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleNextOrPreviousThirds.findPreviousThird(windowRect, visibleFrameOfDestinationScreen);\n}, \"SpectacleWindowActionPreviousThird\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleRightHalfWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneHalfRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneHalfRect.width = Math.floor(oneHalfRect.width / 2.0);\n    oneHalfRect.x += oneHalfRect.width;\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneHalfRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        twoThirdRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - twoThirdRect.width;\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneHalfRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            oneThirdsRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - oneThirdsRect.width;\n            return oneThirdsRect;\n        }\n    }\n    return oneHalfRect;\n}, \"SpectacleWindowActionRightHalf\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleSmallerWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    return SpectacleWindowSizeAdjuster.resizeWindowRect(windowRect, visibleFrameOfDestinationScreen, -30.0);\n}, \"SpectacleWindowActionSmaller\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleTopHalfWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneHalfRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneHalfRect.height = Math.floor(oneHalfRect.height / 2.0);\n    oneHalfRect.y += oneHalfRect.height + (visibleFrameOfDestinationScreen.height % 2.0);\n    if (Math.abs(CGRectGetMidX(windowRect) - CGRectGetMidX(oneHalfRect)) <= 1.0) {\n        var twoThirdsRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n        twoThirdsRect.height = Math.floor(visibleFrameOfDestinationScreen.height * 2 / 3.0);\n        twoThirdsRect.y = visibleFrameOfDestinationScreen.y + visibleFrameOfDestinationScreen.height - twoThirdsRect.height;\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneHalfRect, windowRect)) {\n            return twoThirdsRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdsRect, windowRect)) {\n            var oneThirdRect = SpectacleCalculationHelpers.copyRect(oneHalfRect);\n            oneThirdRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 3.0);\n            oneThirdRect.y = visibleFrameOfDestinationScreen.y + visibleFrameOfDestinationScreen.height - oneThirdRect.height;\n            return oneThirdRect;\n        }\n    }\n    return oneHalfRect;\n}, \"SpectacleWindowActionTopHalf\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleUpperLeftWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneQuarterRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneQuarterRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 2.0);\n    oneQuarterRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 2.0);\n    oneQuarterRect.y = visibleFrameOfDestinationScreen.y + Math.floor(visibleFrameOfDestinationScreen.height / 2.0) + (visibleFrameOfDestinationScreen.height % 2.0);\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneQuarterRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneQuarterRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            return oneThirdsRect;\n        }\n    }\n    return oneQuarterRect;\n}, \"SpectacleWindowActionUpperLeft\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleUpperRightWindowCalculation.js",
    "content": "windowPositionCalculationRegistry.registerWindowPositionCalculationWithAction(function (windowRect, visibleFrameOfSourceScreen, visibleFrameOfDestinationScreen) {\n    var oneQuarterRect = SpectacleCalculationHelpers.copyRect(visibleFrameOfDestinationScreen);\n    oneQuarterRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 2.0);\n    oneQuarterRect.height = Math.floor(visibleFrameOfDestinationScreen.height / 2.0);\n    oneQuarterRect.x += oneQuarterRect.width;\n    oneQuarterRect.y = visibleFrameOfDestinationScreen.y + Math.floor(visibleFrameOfDestinationScreen.height / 2.0) + (visibleFrameOfDestinationScreen.height % 2.0);\n    if (Math.abs(CGRectGetMidY(windowRect) - CGRectGetMidY(oneQuarterRect)) <= 1.0) {\n        var twoThirdRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n        twoThirdRect.width = Math.floor(visibleFrameOfDestinationScreen.width * 2 / 3.0);\n        twoThirdRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - twoThirdRect.width;\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(oneQuarterRect, windowRect)) {\n            return twoThirdRect;\n        }\n        if (SpectacleCalculationHelpers.rectCenteredWithinRect(twoThirdRect, windowRect)) {\n            var oneThirdsRect = SpectacleCalculationHelpers.copyRect(oneQuarterRect);\n            oneThirdsRect.width = Math.floor(visibleFrameOfDestinationScreen.width / 3.0);\n            oneThirdsRect.x = visibleFrameOfDestinationScreen.x + visibleFrameOfDestinationScreen.width - oneThirdsRect.width;\n            return oneThirdsRect;\n        }\n    }\n    return oneQuarterRect;\n}, \"SpectacleWindowActionUpperRight\");\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleWindowCalculationHelpers.js",
    "content": "var SpectacleCalculationHelpers = (function () {\n    var copyRect = function(rect) {\n        return {\n            x: rect.x,\n            y: rect.y,\n            width: rect.width,\n            height: rect.height,\n        };\n    };\n    var rectCenteredWithinRect = function(rect1, rect2) {\n        var centeredMidX = Math.abs(CGRectGetMidX(rect2) - CGRectGetMidX(rect1)) <= 1.0;\n        var centeredMidY = Math.abs(CGRectGetMidY(rect2) - CGRectGetMidY(rect1)) <= 1.0;\n        return CGRectContainsRect(rect1, rect2) && centeredMidX && centeredMidY;\n    };\n    var rectFitsWithinRect = function(rect1, rect2) {\n        return (rect1.width <= rect2.width) && (rect1.height <= rect2.height);\n    };\n    return {\n        copyRect: copyRect,\n        rectCenteredWithinRect: rectCenteredWithinRect,\n        rectFitsWithinRect: rectFitsWithinRect,\n    };\n})();\n"
  },
  {
    "path": "Spectacle/Resources/Window Position Calculations/SpectacleWindowSizeAdjuster.js",
    "content": "var SpectacleWindowSizeAdjuster = (function () {\n    var resizeWindowRect = function(windowRect, visibleFrameOfDestinationScreen, sizeOffset) {\n        var resizedWindowRect = SpectacleCalculationHelpers.copyRect(windowRect);\n        resizedWindowRect.width = resizedWindowRect.width + sizeOffset;\n        resizedWindowRect.x = resizedWindowRect.x - Math.floor(sizeOffset / 2.0);\n        resizedWindowRect = adjustedWindowRectAgainstLeftAndRightEdgesOfScreen(windowRect,\n                                                                               resizedWindowRect,\n                                                                               visibleFrameOfDestinationScreen);\n        if (resizedWindowRect.width >= visibleFrameOfDestinationScreen.width) {\n            resizedWindowRect.width = visibleFrameOfDestinationScreen.width;\n        }\n        resizedWindowRect.height = resizedWindowRect.height + sizeOffset;\n        resizedWindowRect.y = resizedWindowRect.y - Math.floor(sizeOffset / 2.0);\n        resizedWindowRect = adjustedWindowRectAgainstTopAndBottomEdgesOfScreen(windowRect,\n                                                                               resizedWindowRect,\n                                                                               visibleFrameOfDestinationScreen);\n        if (resizedWindowRect.height >= visibleFrameOfDestinationScreen.height) {\n            resizedWindowRect.height = visibleFrameOfDestinationScreen.height;\n            resizedWindowRect.y = windowRect.y;\n        }\n        if (againstAllEdgesOfScreen(windowRect, visibleFrameOfDestinationScreen) && (sizeOffset < 0)) {\n            resizedWindowRect.width = windowRect.width + sizeOffset;\n            resizedWindowRect.x = windowRect.x - Math.floor(sizeOffset / 2.0);\n            resizedWindowRect.height = windowRect.height + sizeOffset;\n            resizedWindowRect.y = windowRect.y - Math.floor(sizeOffset / 2.0);\n        }\n        if (resizedWindowRectIsTooSmall(resizedWindowRect, visibleFrameOfDestinationScreen)) {\n            resizedWindowRect = windowRect;\n        }\n        return resizedWindowRect;\n    };\n    var againstEdgeOfScreen = function(gap) {\n        return Math.abs(gap) <= 5.0;\n    };\n    var againstTheLeftEdgeOfScreen = function(windowRect, visibleFrameOfDestinationScreen) {\n        return againstEdgeOfScreen(windowRect.x - visibleFrameOfDestinationScreen.x);\n    };\n    var againstTheRightEdgeOfScreen = function(windowRect, visibleFrameOfDestinationScreen) {\n        return againstEdgeOfScreen(CGRectGetMaxX(windowRect) - CGRectGetMaxX(visibleFrameOfDestinationScreen));\n    };\n    var againstTheTopEdgeOfScreen = function(windowRect, visibleFrameOfDestinationScreen) {\n        return againstEdgeOfScreen(CGRectGetMaxY(windowRect) - CGRectGetMaxY(visibleFrameOfDestinationScreen));\n    };\n    var againstTheBottomEdgeOfScreen = function(windowRect, visibleFrameOfDestinationScreen) {\n        return againstEdgeOfScreen(windowRect.y - visibleFrameOfDestinationScreen.y);\n    };\n    var againstAllEdgesOfScreen = function(windowRect, visibleFrameOfDestinationScreen) {\n        return (againstTheLeftEdgeOfScreen(windowRect, visibleFrameOfDestinationScreen)\n                && againstTheRightEdgeOfScreen(windowRect, visibleFrameOfDestinationScreen)\n                && againstTheTopEdgeOfScreen(windowRect, visibleFrameOfDestinationScreen)\n                && againstTheBottomEdgeOfScreen(windowRect, visibleFrameOfDestinationScreen));\n    };\n    var adjustedWindowRectAgainstLeftAndRightEdgesOfScreen = function(originalWindowRect, resizedWindowRect, visibleFrameOfDestinationScreen) {\n        var adjustedWindowRect = SpectacleCalculationHelpers.copyRect(resizedWindowRect);\n        if (againstTheRightEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n            adjustedWindowRect.x = CGRectGetMaxX(visibleFrameOfDestinationScreen) - adjustedWindowRect.width;\n            if (againstTheLeftEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n                adjustedWindowRect.width = visibleFrameOfDestinationScreen.width;\n            }\n        }\n        if (againstTheLeftEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n            adjustedWindowRect.x = visibleFrameOfDestinationScreen.x;\n        }\n        return adjustedWindowRect;\n    };\n    var adjustedWindowRectAgainstTopAndBottomEdgesOfScreen = function(originalWindowRect, resizedWindowRect, visibleFrameOfDestinationScreen) {\n        var adjustedWindowRect = SpectacleCalculationHelpers.copyRect(resizedWindowRect);\n        if (againstTheTopEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n            adjustedWindowRect.y = CGRectGetMaxY(visibleFrameOfDestinationScreen) - adjustedWindowRect.height;\n            if (againstTheBottomEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n                adjustedWindowRect.height = visibleFrameOfDestinationScreen.height;\n            }\n        }\n        if (againstTheBottomEdgeOfScreen(originalWindowRect, visibleFrameOfDestinationScreen)) {\n            adjustedWindowRect.y = visibleFrameOfDestinationScreen.y;\n        }\n        return adjustedWindowRect;\n    };\n    var resizedWindowRectIsTooSmall = function(windowRect, visibleFrameOfDestinationScreen) {\n        var minimumWindowRectWidth = Math.floor(visibleFrameOfDestinationScreen.width / 4.0);\n        var minimumWindowRectHeight = Math.floor(visibleFrameOfDestinationScreen.height / 4.0);\n        return (windowRect.width <= minimumWindowRectWidth) || (windowRect.height <= minimumWindowRectHeight);\n    };\n    return {\n        resizeWindowRect: resizeWindowRect,\n    };\n})();\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleAccessibilityElement.h",
    "content": "#import <Carbon/Carbon.h>\n\n@interface SpectacleAccessibilityElement : NSObject\n\n+ (SpectacleAccessibilityElement *)frontmostApplicationElement;\n+ (SpectacleAccessibilityElement *)frontmostWindowElement;\n\n- (SpectacleAccessibilityElement *)elementWithAttribute:(CFStringRef)attribute;\n\n- (NSString *)stringValueOfAttribute:(CFStringRef)attribute;\n\n- (AXValueRef)valueOfAttribute:(CFStringRef)attribute type:(AXValueType)type;\n- (void)setValue:(AXValueRef)value forAttribute:(CFStringRef)attribute;\n\n- (CGRect)rectOfElement;\n- (void)setRectOfElement:(CGRect)rect;\n\n+ (CGRect)normalizeCoordinatesOfRect:(CGRect)rect frameOfScreen:(CGRect)frameOfScreen;\n\n- (BOOL)isSheet;\n- (BOOL)isSystemDialog;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleAccessibilityElement.m",
    "content": "#import \"SpectacleAccessibilityElement.h\"\n\n#import <AppKit/AppKit.h>\n\n@implementation SpectacleAccessibilityElement\n{\n  AXUIElementRef _underlyingElement;\n}\n\n- (instancetype)init\n{\n  if (self = [super init]) {\n    _underlyingElement = NULL;\n  }\n\n  return self;\n}\n\n+ (SpectacleAccessibilityElement *)frontmostApplicationElement\n{\n  NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;\n  SpectacleAccessibilityElement *frontmostApplicationElement = [SpectacleAccessibilityElement new];\n  AXUIElementRef underlyingElement = AXUIElementCreateApplication(frontmostApplication.processIdentifier);\n  frontmostApplicationElement.underlyingElement = underlyingElement;\n  CFRelease(underlyingElement);\n  return frontmostApplicationElement;\n}\n\n+ (SpectacleAccessibilityElement *)frontmostWindowElement\n{\n  SpectacleAccessibilityElement *frontmostApplicationElement = [SpectacleAccessibilityElement frontmostApplicationElement];\n  SpectacleAccessibilityElement *frontmostWindowElement = nil;\n  if (frontmostApplicationElement) {\n    frontmostWindowElement = [frontmostApplicationElement elementWithAttribute:kAXFocusedWindowAttribute];\n    if (!frontmostWindowElement) {\n      NSLog(@\"Invalid accessibility element provided, unable to determine the size and position of the window.\");\n    }\n  } else {\n    NSLog(@\"Failed to find the application that currently has focus.\");\n  }\n  return frontmostWindowElement;\n}\n\n- (SpectacleAccessibilityElement *)elementWithAttribute:(CFStringRef)attribute\n{\n  SpectacleAccessibilityElement *newElement = nil;\n  AXUIElementRef underlyingElement;\n  AXError result = AXUIElementCopyAttributeValue(_underlyingElement, attribute, (CFTypeRef *)&underlyingElement);\n  if (result == kAXErrorSuccess) {\n    newElement = [SpectacleAccessibilityElement new];\n    newElement.underlyingElement = underlyingElement;\n    CFRelease(underlyingElement);\n  } else {\n    NSLog(@\"Unable to obtain the accessibility element with the specified attribute: %@ (error code %d)\", attribute, result);\n  }\n  return newElement;\n}\n\n- (NSString *)stringValueOfAttribute:(CFStringRef)attribute\n{\n  if (CFGetTypeID(_underlyingElement) == AXUIElementGetTypeID()) {\n    CFTypeRef value;\n    AXError result;\n    result = AXUIElementCopyAttributeValue(_underlyingElement, attribute, &value);\n    if (result == kAXErrorSuccess) {\n      return CFBridgingRelease(value);\n    } else {\n      NSLog(@\"There was a problem getting the string value of the specified attribute: %@ (error code %d)\", attribute, result);\n    }\n  }\n  return nil;\n}\n\n- (AXValueRef)valueOfAttribute:(CFStringRef)attribute type:(AXValueType)type\n{\n  if (CFGetTypeID(_underlyingElement) == AXUIElementGetTypeID()) {\n    CFTypeRef value;\n    AXError result;\n    result = AXUIElementCopyAttributeValue(_underlyingElement, attribute, (CFTypeRef *)&value);\n    if ((result == kAXErrorSuccess) && (AXValueGetType(value) == type)) {\n      return value;\n    } else {\n      NSLog(@\"There was a problem getting the value of the specified attribute: %@ (error code %d)\", attribute, result);\n    }\n  }\n  return NULL;\n}\n\n- (void)setValue:(AXValueRef)value forAttribute:(CFStringRef)attribute\n{\n  AXError result = AXUIElementSetAttributeValue(_underlyingElement, attribute, (CFTypeRef *)value);\n  if (result != kAXErrorSuccess) {\n    NSLog(@\"There was a problem setting the value of the specified attribute: %@ (error code %d)\", attribute, result);\n  }\n}\n\n- (CGRect)rectOfElement\n{\n  CGRect result = CGRectNull;\n  CFTypeRef positionValue = [self valueOfAttribute:kAXPositionAttribute type:kAXValueCGPointType];\n  CFTypeRef sizeValue = [self valueOfAttribute:kAXSizeAttribute type:kAXValueCGSizeType];\n  CGPoint position;\n  CGSize size;\n  AXValueGetValue(positionValue, kAXValueCGPointType, (void *)&position);\n  AXValueGetValue(sizeValue, kAXValueCGSizeType, (void *)&size);\n  if ((positionValue != NULL) && (sizeValue != NULL)) {\n    CFRelease(positionValue);\n    CFRelease(sizeValue);\n    result = CGRectMake(position.x, position.y, size.width, size.height);\n  }\n  return result;\n}\n\n- (void)setRectOfElement:(CGRect)rect\n{\n  AXValueRef positionRef;\n  AXValueRef sizeRef;\n  positionRef = AXValueCreate(kAXValueCGPointType, (const void *)&rect.origin);\n  sizeRef = AXValueCreate(kAXValueCGSizeType, (const void *)&rect.size);\n  [self setValue:sizeRef forAttribute:kAXSizeAttribute];\n  [self setValue:positionRef forAttribute:kAXPositionAttribute];\n  [self setValue:sizeRef forAttribute:kAXSizeAttribute];\n  CFRelease(positionRef);\n  CFRelease(sizeRef);\n}\n\n+ (CGRect)normalizeCoordinatesOfRect:(CGRect)rect frameOfScreen:(CGRect)frameOfScreen\n{\n  CGRect frameOfScreenWithMenuBar = [[[NSScreen screens] objectAtIndex:0] frame];\n  rect.origin.y = frameOfScreen.size.height - NSMaxY(rect) + (frameOfScreenWithMenuBar.size.height - frameOfScreen.size.height);\n  return rect;\n}\n\n- (BOOL)isSheet\n{\n  return [[self stringValueOfAttribute:kAXRoleAttribute] isEqualToString:(__bridge NSString *)kAXSheetRole];\n}\n\n- (BOOL)isSystemDialog\n{\n  return [[self stringValueOfAttribute:kAXSubroleAttribute] isEqualToString:(__bridge NSString *)kAXSystemDialogSubrole];\n}\n\n- (void)dealloc\n{\n  if (_underlyingElement != NULL) {\n    CFRelease(_underlyingElement);\n  }\n}\n\n- (void)setUnderlyingElement:(AXUIElementRef)underlyingElement\n{\n  if (_underlyingElement != NULL) {\n    CFRelease(_underlyingElement);\n  }\n  _underlyingElement = CFRetain(underlyingElement);\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleAppDelegate.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n@class SpectaclePreferencesController;\n\n@interface SpectacleAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>\n\n@property (nonatomic, strong) IBOutlet NSMenu *statusItemMenu;\n@property (nonatomic, strong) IBOutlet NSWindow *accessiblityAccessDialogWindow;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToCenterShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToFullscreenShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToLeftShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToRightShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToTopShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToBottomShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToUpperLeftShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToLowerLeftShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToUpperRightShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToLowerRightShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToNextDisplayShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToPreviousDisplayShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToNextThirdShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *moveToPreviousThirdShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *makeLargerShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *makeSmallerShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *undoLastMoveShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *redoLastMoveShortcutMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *disableShortcutsForAnHourMenuItem;\n@property (nonatomic, strong) IBOutlet NSMenuItem *disableShortcutsForApplicationMenuItem;\n\n- (IBAction)showPreferencesWindow:(id)sender;\n\n- (IBAction)moveFrontmostWindowToFullscreen:(id)sender;\n- (IBAction)moveFrontmostWindowToCenter:(id)sender;\n- (IBAction)moveFrontmostWindowToLeftHalf:(id)sender;\n- (IBAction)moveFrontmostWindowToRightHalf:(id)sender;\n- (IBAction)moveFrontmostWindowToTopHalf:(id)sender;\n- (IBAction)moveFrontmostWindowToBottomHalf:(id)sender;\n- (IBAction)moveFrontmostWindowToUpperLeft:(id)sender;\n- (IBAction)moveFrontmostWindowToLowerLeft:(id)sender;\n- (IBAction)moveFrontmostWindowToUpperRight:(id)sender;\n- (IBAction)moveFrontmostWindowToLowerRight:(id)sender;\n- (IBAction)moveFrontmostWindowToNextDisplay:(id)sender;\n- (IBAction)moveFrontmostWindowToPreviousDisplay:(id)sender;\n- (IBAction)moveFrontmostWindowToNextThird:(id)sender;\n- (IBAction)moveFrontmostWindowToPreviousThird:(id)sender;\n- (IBAction)makeFrontmostWindowLarger:(id)sender;\n- (IBAction)makeFrontmostWindowSmaller:(id)sender;\n- (IBAction)undoLastWindowAction:(id)sender;\n- (IBAction)redoLastWindowAction:(id)sender;\n- (IBAction)disableOrEnableShortcutsForAnHour:(id)sender;\n- (IBAction)disableOrEnableShortcutsForApplication:(id)sender;\n\n- (IBAction)openSystemPreferences:(id)sender;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleAppDelegate.m",
    "content": "#import \"SpectacleAppDelegate.h\"\n\n#import <Sparkle/Sparkle.h>\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleDefaultShortcutHelpers.h\"\n#import \"SpectacleMigratingShortcutStorage.h\"\n#import \"SpectaclePreferencesController.h\"\n#import \"SpectacleScreenDetector.h\"\n#import \"SpectacleShortcutJSONStorage.h\"\n#import \"SpectacleShortcutManager.h\"\n#import \"SpectacleShortcutTranslations.h\"\n#import \"SpectacleShortcutUserDefaultsStorage.h\"\n#import \"SpectacleUtilities.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n#import \"SpectacleWindowPositionManager.h\"\n\n@implementation SpectacleAppDelegate\n{\n  NSDictionary<NSString *, NSMenuItem *> *_shortcutMenuItems;\n  NSStatusItem *_statusItem;\n  id<SpectacleShortcutStorage> _shortcutStorage;\n  SpectacleShortcutManager *_shortcutManager;\n  SpectacleWindowPositionManager *_windowPositionManager;\n  SpectaclePreferencesController *_preferencesController;\n  NSTimer *_disableShortcutsForAnHourTimer;\n  NSSet<NSString *> *_blacklistedApplications;\n  NSMutableSet<NSString *> *_disabledApplications;\n  BOOL _shortcutsAreDisabledForAnHour;\n}\n\n- (void)applicationDidFinishLaunching:(NSNotification *)notification\n{\n  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n  NSNotificationCenter *workspaceNotificationCenter = [NSWorkspace sharedWorkspace].notificationCenter;\n  [notificationCenter addObserver:self\n                         selector:@selector(enableStatusItem)\n                             name:@\"SpectacleStatusItemEnabledNotification\"\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(disableStatusItem)\n                             name:@\"SpectacleStatusItemDisabledNotification\"\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(updateShortcutMenuItems)\n                             name:@\"SpectacleShortcutChangedNotification\"\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(updateShortcutMenuItems)\n                             name:@\"SpectacleRestoreDefaultShortcutsNotification\"\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(menuDidSendAction:)\n                             name:NSMenuDidSendActionNotification\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(inputSourceSelectionDidChange)\n                             name:NSTextInputContextKeyboardSelectionDidChangeNotification\n                           object:nil];\n  [workspaceNotificationCenter addObserver:self\n                                  selector:@selector(applicationDidActivate:)\n                                      name:NSWorkspaceDidActivateApplicationNotification\n                                    object:nil];\n  [workspaceNotificationCenter addObserver:self\n                                  selector:@selector(applicationDidDeactivate:)\n                                      name:NSWorkspaceDidDeactivateApplicationNotification\n                                    object:nil];\n  [SpectacleUtilities registerDefaultsForBundle:[NSBundle mainBundle]];\n  _shortcutMenuItems = @{\n                         @\"MoveToCenter\": _moveToCenterShortcutMenuItem,\n                         @\"MoveToFullscreen\": _moveToFullscreenShortcutMenuItem,\n                         @\"MoveToLeftHalf\": _moveToLeftShortcutMenuItem,\n                         @\"MoveToRightHalf\": _moveToRightShortcutMenuItem,\n                         @\"MoveToTopHalf\": _moveToTopShortcutMenuItem,\n                         @\"MoveToBottomHalf\": _moveToBottomShortcutMenuItem,\n                         @\"MoveToUpperLeft\": _moveToUpperLeftShortcutMenuItem,\n                         @\"MoveToLowerLeft\": _moveToLowerLeftShortcutMenuItem,\n                         @\"MoveToUpperRight\": _moveToUpperRightShortcutMenuItem,\n                         @\"MoveToLowerRight\": _moveToLowerRightShortcutMenuItem,\n                         @\"MoveToNextDisplay\": _moveToNextDisplayShortcutMenuItem,\n                         @\"MoveToPreviousDisplay\": _moveToPreviousDisplayShortcutMenuItem,\n                         @\"MoveToNextThird\": _moveToNextThirdShortcutMenuItem,\n                         @\"MoveToPreviousThird\": _moveToPreviousThirdShortcutMenuItem,\n                         @\"MakeLarger\": _makeLargerShortcutMenuItem,\n                         @\"MakeSmaller\": _makeSmallerShortcutMenuItem,\n                         @\"UndoLastMove\": _undoLastMoveShortcutMenuItem,\n                         @\"RedoLastMove\": _redoLastMoveShortcutMenuItem,\n                         };\n  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n  _blacklistedApplications = [NSSet setWithArray:[userDefaults objectForKey:@\"BlacklistedApplications\"]];\n  _disabledApplications = [NSMutableSet setWithArray:[userDefaults objectForKey:@\"DisabledApplications\"]];\n  _shortcutStorage = [[SpectacleMigratingShortcutStorage alloc] initWithShortcutStorage:[SpectacleShortcutUserDefaultsStorage new]\n                                                                   migrationDestination:[SpectacleShortcutJSONStorage new]];\n  _shortcutManager = [[SpectacleShortcutManager alloc] initWithShortcutStorage:_shortcutStorage];\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *errorMessage) {\n    NSAlert *alert = [NSAlert new];\n    alert.alertStyle = NSWarningAlertStyle;\n    alert.messageText = @\"Encountered an unexpected error\";\n    alert.informativeText = errorMessage;\n    [alert runModal];\n  }];\n  _windowPositionManager = [[SpectacleWindowPositionManager alloc] initWithScreenDetector:[SpectacleScreenDetector new]\n                                                                 windowPositionCalculator:windowPositionCalculator\n                                                                          sharedWorkspace:[NSWorkspace sharedWorkspace]];\n  _preferencesController = [[SpectaclePreferencesController alloc] initWithShortcutManager:_shortcutManager\n                                                                     windowPositionManager:_windowPositionManager\n                                                                           shortcutStorage:_shortcutStorage];\n  _shortcutsAreDisabledForAnHour = NO;\n  [self manageShortcuts];\n  [self disableShortcutsIfFrontmostApplicationIsBlacklistedOrDisabled];\n  BOOL automaticallyChecksForUpdates = [userDefaults boolForKey:@\"AutomaticUpdateCheckEnabled\"];\n  BOOL statusItemEnabled = [userDefaults boolForKey:@\"StatusItemEnabled\"];\n  if (statusItemEnabled) {\n    [self enableStatusItem];\n  }\n  [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates:automaticallyChecksForUpdates];\n  [self updateShortcutMenuItems];\n  if (!AXIsProcessTrustedWithOptions(NULL)) {\n    [[NSApplication sharedApplication] runModalForWindow:self.accessiblityAccessDialogWindow];\n  }\n}\n\n- (BOOL)applicationShouldHandleReopen:(NSApplication *)application hasVisibleWindows:(BOOL)visibleWindows\n{\n  [self showPreferencesWindow:self];\n\n  return YES;\n}\n\n- (IBAction)showPreferencesWindow:(id)sender\n{\n  [_preferencesController showWindow:sender];\n}\n\n- (IBAction)moveFrontmostWindowToFullscreen:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionFullscreen];\n}\n\n- (IBAction)moveFrontmostWindowToCenter:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionCenter];\n}\n\n- (IBAction)moveFrontmostWindowToLeftHalf:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionLeftHalf];\n}\n\n- (IBAction)moveFrontmostWindowToRightHalf:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionRightHalf];\n}\n\n- (IBAction)moveFrontmostWindowToTopHalf:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionTopHalf];\n}\n\n- (IBAction)moveFrontmostWindowToBottomHalf:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionBottomHalf];\n}\n\n- (IBAction)moveFrontmostWindowToUpperLeft:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionUpperLeft];\n}\n\n- (IBAction)moveFrontmostWindowToLowerLeft:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionLowerLeft];\n}\n\n- (IBAction)moveFrontmostWindowToUpperRight:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionUpperRight];\n}\n\n- (IBAction)moveFrontmostWindowToLowerRight:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionLowerRight];\n}\n\n- (IBAction)moveFrontmostWindowToNextDisplay:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionNextDisplay];\n}\n\n- (IBAction)moveFrontmostWindowToPreviousDisplay:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionPreviousDisplay];\n}\n\n- (IBAction)moveFrontmostWindowToNextThird:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionNextThird];\n}\n\n- (IBAction)moveFrontmostWindowToPreviousThird:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionPreviousThird];\n}\n\n- (IBAction)makeFrontmostWindowLarger:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionLarger];\n}\n\n- (IBAction)makeFrontmostWindowSmaller:(id)sender\n{\n  [_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                              action:kSpectacleWindowActionSmaller];\n}\n\n- (IBAction)undoLastWindowAction:(id)sender\n{\n  [_windowPositionManager undoLastWindowAction];\n}\n\n- (IBAction)redoLastWindowAction:(id)sender\n{\n  [_windowPositionManager redoLastWindowAction];\n}\n\n- (IBAction)disableOrEnableShortcutsForAnHour:(id)sender\n{\n  NSInteger newMenuItemState = NSMixedState;\n  if (_shortcutsAreDisabledForAnHour) {\n    _shortcutsAreDisabledForAnHour = NO;\n    [_disableShortcutsForAnHourTimer invalidate];\n    [self enableShortcutsIfPermitted];\n    newMenuItemState = NSOffState;\n  } else {\n    _shortcutsAreDisabledForAnHour = YES;\n    _disableShortcutsForAnHourTimer = [NSTimer scheduledTimerWithTimeInterval:3600\n                                                                       target:self\n                                                                     selector:@selector(disableOrEnableShortcutsForAnHour:)\n                                                                     userInfo:nil\n                                                                      repeats:NO];\n    [_shortcutManager unregisterShortcuts];\n    newMenuItemState = NSOnState;\n  }\n  self.disableShortcutsForAnHourMenuItem.state = newMenuItemState;\n}\n\n- (IBAction)disableOrEnableShortcutsForApplication:(id)sender\n{\n  NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;\n  if ([_disabledApplications containsObject:frontmostApplication.bundleIdentifier]) {\n    [_disabledApplications removeObject:frontmostApplication.bundleIdentifier];\n    [self enableShortcutsIfPermitted];\n    self.disableShortcutsForApplicationMenuItem.state = NSOffState;\n  } else {\n    [_disabledApplications addObject:frontmostApplication.bundleIdentifier];\n    [_shortcutManager unregisterShortcuts];\n    self.disableShortcutsForApplicationMenuItem.state = NSOnState;\n  }\n  [NSUserDefaults.standardUserDefaults setObject:_disabledApplications.allObjects forKey:@\"DisabledApplications\"];\n}\n\n- (IBAction)openSystemPreferences:(id)sender\n{\n  NSURL *preferencePaneURL = [NSURL fileURLWithPath:[SpectacleUtilities pathForPreferencePaneNamed:@\"Security\"]];\n  NSBundle *applicationBundle = NSBundle.mainBundle;\n  NSURL *scriptURL = [applicationBundle URLForResource:@\"Security & Privacy System Preferences\" withExtension:@\"scpt\"];\n  [[NSApplication sharedApplication] stopModal];\n  [self.accessiblityAccessDialogWindow orderOut:self];\n  if (![[[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:nil] executeAndReturnError:nil]) {\n    [[NSWorkspace sharedWorkspace] openURL:preferencePaneURL];\n  }\n}\n\n- (void)dealloc\n{\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (void)manageShortcuts\n{\n  SpectacleShortcutAction action = ^(SpectacleShortcut *shortcut) {\n    [self->_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                                      action:shortcut.windowAction];\n  };\n  NSArray<SpectacleShortcut *> *shortcuts = [_shortcutStorage loadShortcutsWithAction:action];\n  if (shortcuts.count != 0) {\n    [_shortcutManager manageShortcuts:shortcuts];\n  } else {\n    [_shortcutManager manageShortcuts:SpectacleDefaultShortcutsWithAction(action)];\n  }\n}\n\n- (void)enableStatusItem\n{\n  _statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];\n  NSImage *statusImage = [NSBundle.mainBundle imageForResource:@\"Spectacle Status Item\"];\n  [statusImage setTemplate:YES];\n  _statusItem.highlightMode = YES;\n  _statusItem.image = statusImage;\n  _statusItem.menu = _statusItemMenu;\n  _statusItem.toolTip = [@\"Spectacle \" stringByAppendingString:SpectacleUtilities.applicationVersion];\n}\n\n- (void)disableStatusItem\n{\n  [NSStatusBar.systemStatusBar removeStatusItem:_statusItem];\n}\n\n- (void)updateShortcutMenuItems\n{\n  for (NSString *shortcutName in _shortcutMenuItems.allKeys) {\n    NSMenuItem *shortcutMenuItem = _shortcutMenuItems[shortcutName];\n    SpectacleShortcut *shortcut = [_shortcutManager shortcutForShortcutName:shortcutName];\n    if (shortcut) {\n      shortcutMenuItem.keyEquivalent = [SpectacleTranslateKeyCode(shortcut.shortcutKeyCode) lowercaseString];\n      shortcutMenuItem.keyEquivalentModifierMask = SpectacleConvertModifiersToCocoaIfNecessary(shortcut.shortcutModifiers);\n    } else {\n      shortcutMenuItem.keyEquivalent = @\"\";\n      shortcutMenuItem.keyEquivalentModifierMask = 0;\n    }\n  }\n}\n\n- (void)enableShortcutsIfPermitted\n{\n  NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;\n  // Do not enable shortcuts if they should remain disabled for an hour.\n  if (_shortcutsAreDisabledForAnHour) {\n    return;\n  }\n  // Do not enable shortcuts if the application is blacklisted or disabled.\n  if ([_blacklistedApplications containsObject:frontmostApplication.bundleIdentifier]\n      || [_disabledApplications containsObject:frontmostApplication.bundleIdentifier]) {\n    return;\n  }\n  [_shortcutManager registerShortcuts];\n  [[NSNotificationCenter defaultCenter] postNotificationName:@\"SpectacleShortcutChangedNotification\" object:self];\n}\n\n- (void)disableShortcutsIfFrontmostApplicationIsBlacklistedOrDisabled\n{\n  NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;\n  // Do not disable shortcuts if the application is not blacklisted or disabled.\n  if (![_blacklistedApplications containsObject:frontmostApplication.bundleIdentifier]\n      && ![_disabledApplications containsObject:frontmostApplication.bundleIdentifier]) {\n    return;\n  }\n  [_shortcutManager unregisterShortcuts];\n}\n\n- (void)applicationDidActivate:(NSNotification *)notification\n{\n  NSRunningApplication *application = notification.userInfo[NSWorkspaceApplicationKey];\n  if ([_blacklistedApplications containsObject:application.bundleIdentifier]\n      || [_disabledApplications containsObject:application.bundleIdentifier]) {\n    [_shortcutManager unregisterShortcuts];\n  }\n}\n\n- (void)applicationDidDeactivate:(NSNotification *)notification\n{\n  NSRunningApplication *application = notification.userInfo[NSWorkspaceApplicationKey];\n  if ([_blacklistedApplications containsObject:application.bundleIdentifier]\n      || [_disabledApplications containsObject:application.bundleIdentifier]) {\n    [self enableShortcutsIfPermitted];\n  }\n}\n\n- (void)menuWillOpen:(NSMenu *)menu\n{\n  NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;\n  self.disableShortcutsForApplicationMenuItem.hidden = NO;\n  if ([_blacklistedApplications containsObject:frontmostApplication.bundleIdentifier]) {\n    self.disableShortcutsForApplicationMenuItem.hidden = YES;\n  } else {\n    self.disableShortcutsForApplicationMenuItem.title =\n      [NSString stringWithFormat:NSLocalizedString(@\"MenuItemTitleDisableShortcutsForApplication\", @\"The menu item title that displays the application to disable shortcuts for\"), frontmostApplication.localizedName];\n  }\n  if ([_disabledApplications containsObject:frontmostApplication.bundleIdentifier]) {\n    self.disableShortcutsForApplicationMenuItem.state = NSOnState;\n  } else {\n    self.disableShortcutsForApplicationMenuItem.state = NSOffState;\n  }\n}\n\n- (void)menuDidSendAction:(NSNotification *)notification\n{\n  NSMenuItem *menuItem = notification.userInfo[@\"MenuItem\"];\n  if (menuItem.tag == -1) {\n    [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];\n  }\n}\n\n- (void)inputSourceSelectionDidChange\n{\n  [_preferencesController loadRegisteredShortcuts];\n  [self updateShortcutMenuItems];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleBestEffortWindowMover.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleWindowMover.h\"\n\n@interface SpectacleBestEffortWindowMover : NSObject <SpectacleWindowMover>\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover NS_DESIGNATED_INITIALIZER;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleBestEffortWindowMover.m",
    "content": "#import \"SpectacleBestEffortWindowMover.h\"\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleWindowPositionManager.h\"\n\n@implementation SpectacleBestEffortWindowMover\n{\n  id<SpectacleWindowMover> _innerWindowMover;\n}\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  if (self = [super init]) {\n    _innerWindowMover = innerWindowMover;\n  }\n  return self;\n}\n\n- (instancetype)init\n{\n  return [self initWithInnerWindowMover:nil];\n}\n\n+ (instancetype)newWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  return [[self alloc] initWithInnerWindowMover:innerWindowMover];\n}\n\n- (void)moveWindowRect:(CGRect)windowRect\n         frameOfScreen:(CGRect)frameOfScreen\n  visibleFrameOfScreen:(CGRect)visibleFrameOfScreen\nfrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                action:(SpectacleWindowAction *)action\n{\n  [_innerWindowMover moveWindowRect:windowRect\n                      frameOfScreen:frameOfScreen\n               visibleFrameOfScreen:visibleFrameOfScreen\n             frontmostWindowElement:frontmostWindowElement\n                             action:action];\n  CGRect movedWindowRect = [frontmostWindowElement rectOfElement];\n  CGRect previouslyMovedWindowRect = movedWindowRect;\n  if (movedWindowRect.origin.x < visibleFrameOfScreen.origin.x) {\n    movedWindowRect.origin.x = visibleFrameOfScreen.origin.x;\n  } else if ((movedWindowRect.origin.x + movedWindowRect.size.width) > (visibleFrameOfScreen.origin.x + visibleFrameOfScreen.size.width)) {\n    movedWindowRect.origin.x = visibleFrameOfScreen.origin.x + visibleFrameOfScreen.size.width - movedWindowRect.size.width;\n  }\n  movedWindowRect = [SpectacleAccessibilityElement normalizeCoordinatesOfRect:movedWindowRect\n                                                                frameOfScreen:frameOfScreen];\n  if (movedWindowRect.origin.y < visibleFrameOfScreen.origin.y) {\n    movedWindowRect.origin.y = visibleFrameOfScreen.origin.y;\n  } else if ((movedWindowRect.origin.y + movedWindowRect.size.height) > (visibleFrameOfScreen.origin.y + visibleFrameOfScreen.size.height)) {\n    movedWindowRect.origin.y = visibleFrameOfScreen.origin.y + visibleFrameOfScreen.size.height - movedWindowRect.size.height;\n  }\n  movedWindowRect = [SpectacleAccessibilityElement normalizeCoordinatesOfRect:movedWindowRect\n                                                                frameOfScreen:frameOfScreen];\n  if (!CGRectEqualToRect(movedWindowRect, previouslyMovedWindowRect)) {\n    [frontmostWindowElement setRectOfElement:movedWindowRect];\n  }\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleDefaultShortcutHelpers.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcut.h\"\n\nNSArray<SpectacleShortcut *> *SpectacleDefaultShortcutsWithAction(SpectacleShortcutAction action);\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleDefaultShortcutHelpers.m",
    "content": "#import \"SpectacleDefaultShortcutHelpers.h\"\n\n#import <Carbon/Carbon.h>\n#import <Cocoa/Cocoa.h>\n\nstatic NSArray<SpectacleShortcut *> *builtinDefaultShortcuts(void);\n\nNSArray<SpectacleShortcut *> *SpectacleDefaultShortcutsWithAction(SpectacleShortcutAction action)\n{\n  NSMutableArray<SpectacleShortcut *> *defaultShortcuts = [NSMutableArray new];\n  for (SpectacleShortcut *defaultShortcut in builtinDefaultShortcuts()) {\n    [defaultShortcuts addObject:[defaultShortcut copyWithShortcutAction:action]];\n  }\n  return defaultShortcuts;\n}\n\nstatic NSArray<SpectacleShortcut *> *builtinDefaultShortcuts(void)\n{\n  return @[\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"          shortcutKeyBinding:@\"alt+cmd+c\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToFullscreen\"      shortcutKeyBinding:@\"alt+cmd+f\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToLeftHalf\"        shortcutKeyBinding:@\"alt+cmd+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToRightHalf\"       shortcutKeyBinding:@\"alt+cmd+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToTopHalf\"         shortcutKeyBinding:@\"alt+cmd+up\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToBottomHalf\"      shortcutKeyBinding:@\"alt+cmd+down\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToUpperLeft\"       shortcutKeyBinding:@\"ctrl+cmd+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToLowerLeft\"       shortcutKeyBinding:@\"ctrl+shift+cmd+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToUpperRight\"      shortcutKeyBinding:@\"ctrl+cmd+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToLowerRight\"      shortcutKeyBinding:@\"ctrl+shift+cmd+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToNextDisplay\"     shortcutKeyBinding:@\"ctrl+alt+cmd+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToPreviousDisplay\" shortcutKeyBinding:@\"ctrl+alt+cmd+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToNextThird\"       shortcutKeyBinding:@\"ctrl+alt+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToPreviousThird\"   shortcutKeyBinding:@\"ctrl+alt+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MakeLarger\"            shortcutKeyBinding:@\"ctrl+alt+shift+right\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"MakeSmaller\"           shortcutKeyBinding:@\"ctrl+alt+shift+left\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"UndoLastMove\"          shortcutKeyBinding:@\"alt+cmd+z\"],\n           [[SpectacleShortcut alloc] initWithShortcutName:@\"RedoLastMove\"          shortcutKeyBinding:@\"alt+shift+cmd+z\"],\n           ];\n}\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleHistory.h",
    "content": "#import <Foundation/Foundation.h>\n\n@class SpectacleHistoryItem;\n\n@interface SpectacleHistory : NSObject\n\n- (void)addHistoryItem:(SpectacleHistoryItem *)historyItem;\n\n- (SpectacleHistoryItem *)nextHistoryItem;\n- (SpectacleHistoryItem *)previousHistoryItem;\n\n- (BOOL)isEmpty;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleHistory.m",
    "content": "#import \"SpectacleHistory.h\"\n\n#import \"SpectacleHistoryItem.h\"\n\n@implementation SpectacleHistory\n{\n  SpectacleHistoryItem *_lastHistoryItem;\n  SpectacleHistoryItem *_currentHistoryItem;\n  NSInteger _size;\n}\n\n- (void)addHistoryItem:(SpectacleHistoryItem *)historyItem\n{\n  if ([self isEmpty]) {\n    _currentHistoryItem = historyItem;\n    _lastHistoryItem = _currentHistoryItem;\n  } else {\n    historyItem.previousHistoryItem = _currentHistoryItem;\n    _currentHistoryItem.nextHistoryItem.previousHistoryItem = historyItem;\n    _currentHistoryItem.nextHistoryItem = historyItem;\n    if (![historyItem previousHistoryItem]) {\n      _lastHistoryItem = historyItem;\n    }\n    _currentHistoryItem = historyItem;\n  }\n  if (++_size > 50) {\n    _lastHistoryItem.nextHistoryItem.previousHistoryItem = nil;\n    _lastHistoryItem = _lastHistoryItem.nextHistoryItem;\n    _size--;\n  }\n}\n\n- (SpectacleHistoryItem *)nextHistoryItem\n{\n  SpectacleHistoryItem *historyItem = _currentHistoryItem.nextHistoryItem;\n  if (historyItem) {\n    _currentHistoryItem = historyItem;\n    _size++;\n  }\n  return historyItem;\n}\n\n- (SpectacleHistoryItem *)previousHistoryItem\n{\n  SpectacleHistoryItem *historyItem = _currentHistoryItem.previousHistoryItem;\n  if (historyItem) {\n    _currentHistoryItem = historyItem;\n    _size--;\n  }\n  return historyItem;\n}\n\n- (BOOL)isEmpty\n{\n  return _size == 0;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleHistoryItem.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n\n@class SpectacleAccessibilityElement;\n\n@interface SpectacleHistoryItem : NSObject\n\n@property (nonatomic, strong) SpectacleAccessibilityElement *accessibilityElement;\n@property (nonatomic, assign) CGRect windowRect;\n@property (nonatomic, strong) SpectacleHistoryItem *nextHistoryItem;\n@property (nonatomic, weak) SpectacleHistoryItem *previousHistoryItem;\n\n- (instancetype)initWithAccessibilityElement:(SpectacleAccessibilityElement *)accessibilityElement\n                                  windowRect:(CGRect)windowRect NS_DESIGNATED_INITIALIZER;\n\n+ (SpectacleHistoryItem *)historyItemFromAccessibilityElement:(SpectacleAccessibilityElement *)accessibilityElement\n                                                   windowRect:(CGRect)windowRect;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleHistoryItem.m",
    "content": "#import \"SpectacleHistoryItem.h\"\n\n@implementation SpectacleHistoryItem\n\n- (instancetype)initWithAccessibilityElement:(SpectacleAccessibilityElement *)accessibilityElement windowRect:(CGRect)windowRect\n{\n  if (self = [super init]) {\n    _accessibilityElement = accessibilityElement;\n    _windowRect = windowRect;\n  }\n  return self;\n}\n\n+ (SpectacleHistoryItem *)historyItemFromAccessibilityElement:(SpectacleAccessibilityElement *)accessibilityElement\n                                                   windowRect:(CGRect)windowRect\n{\n  return [[SpectacleHistoryItem alloc] initWithAccessibilityElement:accessibilityElement windowRect:windowRect];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleJavaScriptEnvironment.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n\n@class JSContext;\n@class JSValue;\n@class SpectacleWindowPositionCalculationResult;\n\n@interface SpectacleJavaScriptEnvironment : NSObject\n\n- (instancetype)initWithContextBuilder:(void(^)(JSContext *))contextBuilder NS_DESIGNATED_INITIALIZER;\n\n- (JSValue *)valueWithRect:(CGRect)rect;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleJavaScriptEnvironment.m",
    "content": "#import \"SpectacleJavaScriptEnvironment.h\"\n\n#import <JavaScriptCore/JavaScriptCore.h>\n\n@implementation SpectacleJavaScriptEnvironment\n{\n  JSContext *_context;\n}\n\n- (instancetype)initWithContextBuilder:(void(^)(JSContext *))contextBuilder\n{\n  if (self = [super init]) {\n    _context = [JSContext new];\n    contextBuilder(_context);\n    [self evaluateBundledScripts];\n  }\n  return self;\n}\n\n- (JSValue *)valueWithRect:(CGRect)rect\n{\n  return [JSValue valueWithRect:rect inContext:_context];\n}\n\n- (void)evaluateBundledScripts\n{\n  NSArray<NSString *> *scriptPaths = [[NSBundle mainBundle] pathsForResourcesOfType:@\"js\"\n                                                                        inDirectory:@\"Window Position Calculations\"];\n  [scriptPaths enumerateObjectsUsingBlock:^(NSString *scriptPath, NSUInteger index, BOOL *stop) {\n    NSString *script = loadScriptAtPath(scriptPath);\n    if (script) {\n      [self->_context evaluateScript:script];\n    }\n  }];\n}\n\nstatic NSString *loadScriptAtPath(NSString *scriptPath)\n{\n  NSError *error;\n  NSString *script = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:&error];\n  if (!script) {\n    NSLog(@\"Unable to load script at path %@; reason %@\", scriptPath, error.localizedDescription);\n  }\n  return script;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleLoginItemHelper.h",
    "content": "#import <Foundation/Foundation.h>\n\n@interface SpectacleLoginItemHelper : NSObject\n\n+ (BOOL)isLoginItemEnabledForBundle:(NSBundle *)bundle;\n\n+ (void)enableLoginItemForBundle:(NSBundle *)bundle;\n+ (void)disableLoginItemForBundle:(NSBundle *)bundle;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleLoginItemHelper.m",
    "content": "#import \"SpectacleLoginItemHelper.h\"\n\n@implementation SpectacleLoginItemHelper\n\n+ (BOOL)isLoginItemEnabledForBundle:(NSBundle *)bundle\n{\n  LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);\n  NSString *applicationPath = bundle.bundlePath;\n  BOOL result = NO;\n  if (sharedFileList) {\n    UInt32 seedValue;\n    NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));\n    for (id sharedFile in sharedFileListArray) {\n      LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;\n      CFURLRef applicationPathURL = NULL;\n      LSSharedFileListItemResolve(sharedFileListItem, 0, (CFURLRef *)&applicationPathURL, NULL);\n      if (applicationPathURL != NULL) {\n        NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];\n        CFRelease(applicationPathURL);\n        if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {\n          result = YES;\n          break;\n        }\n      }\n    }\n    CFRelease(sharedFileList);\n  } else {\n    NSLog(@\"Unable to create the shared file list.\");\n  }\n  return result;\n}\n\n+ (void)enableLoginItemForBundle:(NSBundle *)bundle\n{\n  LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);\n  NSString *applicationPath = bundle.bundlePath;\n  NSURL *applicationPathURL = [NSURL fileURLWithPath:applicationPath];\n  if (sharedFileList) {\n    LSSharedFileListItemRef sharedFileListItem = LSSharedFileListInsertItemURL(sharedFileList,\n                                                                               kLSSharedFileListItemLast,\n                                                                               NULL,\n                                                                               NULL,\n                                                                               (__bridge CFURLRef)applicationPathURL,\n                                                                               NULL,\n                                                                               NULL);\n    if (sharedFileListItem) {\n      CFRelease(sharedFileListItem);\n    }\n    CFRelease(sharedFileList);\n  } else {\n    NSLog(@\"Unable to create the shared file list.\");\n  }\n}\n\n+ (void)disableLoginItemForBundle:(NSBundle *)bundle\n{\n  LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);\n  NSString *applicationPath = bundle.bundlePath;\n  if (sharedFileList) {\n    UInt32 seedValue;\n    NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));\n    for (id sharedFile in sharedFileListArray) {\n      LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;\n      CFURLRef applicationPathURL;\n      if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) {\n        NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];\n        if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {\n          LSSharedFileListItemRemove(sharedFileList, sharedFileListItem);\n        }\n        CFRelease(applicationPathURL);\n      }\n    }\n    CFRelease(sharedFileList);\n  } else {\n    NSLog(@\"Unable to create the shared file list.\");\n  }\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleMacros.h",
    "content": "#pragma once\n\n#ifndef SPECTACLE_INIT_AND_NEW_UNAVAILABLE\n#define SPECTACLE_INIT_AND_NEW_UNAVAILABLE \\\n- (instancetype)init NS_UNAVAILABLE; \\\n+ (instancetype)new NS_UNAVAILABLE;\n#endif // SPECTACLE_INIT_AND_NEW_UNAVAILABLE\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleMigratingShortcutStorage.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n#import \"SpectacleShortcutStorage.h\"\n\n@protocol SpectacleShortcutStorageMigrationDestination;\n\n@interface SpectacleMigratingShortcutStorage : NSObject <SpectacleShortcutStorage>\n\n- (instancetype)initWithShortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage\n                   migrationDestination:(id<SpectacleShortcutStorageMigrationDestination>)migrationDestination NS_DESIGNATED_INITIALIZER;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleMigratingShortcutStorage.m",
    "content": "#import \"SpectacleMigratingShortcutStorage.h\"\n\n#import \"SpectacleShortcutStorageMigrationDestination.h\"\n\n@implementation SpectacleMigratingShortcutStorage\n{\n  id<SpectacleShortcutStorage> _shortcutStorage;\n  id<SpectacleShortcutStorageMigrationDestination> _migrationDestination;\n}\n\n- (instancetype)initWithShortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage\n                   migrationDestination:(id<SpectacleShortcutStorageMigrationDestination>)migrationDestination\n{\n  if (self = [super init]) {\n    _shortcutStorage = shortcutStorage;\n    _migrationDestination = migrationDestination;\n  }\n  return self;\n}\n\n- (NSArray<SpectacleShortcut *> *)loadShortcutsWithAction:(SpectacleShortcutAction)action\n{\n  return _migrationDestination.isMigrationNeeded ? [_shortcutStorage loadShortcutsWithAction:action] : [_migrationDestination loadShortcutsWithAction:action];\n}\n\n- (void)storeShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts\n{\n  [_migrationDestination storeShortcuts:shortcuts];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectaclePreferencesController.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n#import \"SpectacleShortcutRecorderDelegate.h\"\n\n@class SpectacleAppDelegate;\n@class SpectacleShortcutManager;\n@class SpectacleShortcutRecorder;\n@class SpectacleWindowPositionManager;\n\n@protocol SpectacleShortcutStorage;\n\n@interface SpectaclePreferencesController : NSWindowController <SpectacleShortcutRecorderDelegate>\n\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToCenterShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToFullscreenShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToLeftShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToRightShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToTopShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToBottomShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToUpperLeftShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToLowerLeftShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToUpperRightShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToLowerRightShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToNextDisplayShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToPreviousDisplayShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToNextThirdShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *moveToPreviousThirdShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *makeLargerShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *makeSmallerShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *undoLastMoveShortcutRecorder;\n@property (nonatomic, strong) IBOutlet SpectacleShortcutRecorder *redoLastMoveShortcutRecorder;\n\n@property (nonatomic, strong) IBOutlet NSView *footerView;\n@property (nonatomic, strong) IBOutlet NSView *shortcutModifierLegendFooterView;\n@property (nonatomic, strong) IBOutlet NSView *optionsFooterView;\n\n@property (nonatomic, strong) IBOutlet NSButton *loginItemEnabled;\n@property (nonatomic, strong) IBOutlet NSPopUpButton *statusItemEnabled;\n\n- (instancetype)initWithShortcutManager:(SpectacleShortcutManager *)shortcutManager\n                  windowPositionManager:(SpectacleWindowPositionManager *)windowPositionManager\n                        shortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage;\n\n- (void)loadRegisteredShortcuts;\n\n- (IBAction)swapFooterViews:(id)sender;\n\n- (IBAction)restoreDefaults:(id)sender;\n\n- (IBAction)toggleLoginItem:(id)sender;\n- (IBAction)toggleStatusItem:(id)sender;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectaclePreferencesController.m",
    "content": "#import \"SpectaclePreferencesController.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleDefaultShortcutHelpers.h\"\n#import \"SpectacleLoginItemHelper.h\"\n#import \"SpectacleRegisteredShortcutValidator.h\"\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutManager.h\"\n#import \"SpectacleShortcutRecorder.h\"\n#import \"SpectacleShortcutStorage.h\"\n#import \"SpectacleShortcutValidation.h\"\n#import \"SpectacleUtilities.h\"\n#import \"SpectacleWindowPositionManager.h\"\n\n@implementation SpectaclePreferencesController\n{\n  SpectacleShortcutManager *_shortcutManager;\n  SpectacleWindowPositionManager *_windowPositionManager;\n  id<SpectacleShortcutStorage> _shortcutStorage;\n  NSDictionary<NSString *, SpectacleShortcutRecorder *> *_shortcutRecorders;\n}\n\n- (instancetype)initWithShortcutManager:(SpectacleShortcutManager *)shortcutManager\n                  windowPositionManager:(SpectacleWindowPositionManager *)windowPositionManager\n                        shortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage\n{\n  if (self = [super initWithWindowNibName:@\"SpectaclePreferencesWindow\"]) {\n    _shortcutManager = shortcutManager;\n    _windowPositionManager = windowPositionManager;\n    _shortcutStorage = shortcutStorage;\n  }\n  return self;\n}\n\n- (void)windowDidLoad\n{\n  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n  NSInteger loginItemEnabledState = NSOffState;\n  BOOL isStatusItemEnabled = [NSUserDefaults.standardUserDefaults boolForKey:@\"StatusItemEnabled\"];\n  _shortcutRecorders = @{\n                         @\"MoveToCenter\": _moveToCenterShortcutRecorder,\n                         @\"MoveToFullscreen\": _moveToFullscreenShortcutRecorder,\n                         @\"MoveToLeftHalf\": _moveToLeftShortcutRecorder,\n                         @\"MoveToRightHalf\": _moveToRightShortcutRecorder,\n                         @\"MoveToTopHalf\": _moveToTopShortcutRecorder,\n                         @\"MoveToBottomHalf\": _moveToBottomShortcutRecorder,\n                         @\"MoveToUpperLeft\": _moveToUpperLeftShortcutRecorder,\n                         @\"MoveToLowerLeft\": _moveToLowerLeftShortcutRecorder,\n                         @\"MoveToUpperRight\": _moveToUpperRightShortcutRecorder,\n                         @\"MoveToLowerRight\": _moveToLowerRightShortcutRecorder,\n                         @\"MoveToNextDisplay\": _moveToNextDisplayShortcutRecorder,\n                         @\"MoveToPreviousDisplay\": _moveToPreviousDisplayShortcutRecorder,\n                         @\"MoveToNextThird\": _moveToNextThirdShortcutRecorder,\n                         @\"MoveToPreviousThird\": _moveToPreviousThirdShortcutRecorder,\n                         @\"MakeLarger\": _makeLargerShortcutRecorder,\n                         @\"MakeSmaller\": _makeSmallerShortcutRecorder,\n                         @\"UndoLastMove\": _undoLastMoveShortcutRecorder,\n                         @\"RedoLastMove\": _redoLastMoveShortcutRecorder,\n                         };\n  [self loadRegisteredShortcuts];\n  [notificationCenter addObserver:self\n                         selector:@selector(loadRegisteredShortcuts)\n                             name:@\"SpectacleShortcutChangedNotification\"\n                           object:nil];\n  [notificationCenter addObserver:self\n                         selector:@selector(loadRegisteredShortcuts)\n                             name:@\"SpectacleRestoreDefaultShortcutsNotification\"\n                           object:nil];\n  if ([SpectacleLoginItemHelper isLoginItemEnabledForBundle:NSBundle.mainBundle]) {\n    loginItemEnabledState = NSOnState;\n  }\n  self.loginItemEnabled.state = loginItemEnabledState;\n  [self.statusItemEnabled selectItemWithTag:isStatusItemEnabled ? 0 : 1];\n  self.window.title = [@\"Spectacle \" stringByAppendingString:SpectacleUtilities.applicationVersion];\n  self.footerView.wantsLayer = YES;\n}\n\n- (void)shortcutRecorder:(SpectacleShortcutRecorder *)shortcutRecorder\n   didReceiveNewShortcut:(SpectacleShortcut *)shortcut\n{\n  [_shortcutManager updateShortcut:[shortcut copyWithShortcutAction:^(SpectacleShortcut *shortcut) {\n    [self->_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                                      action:shortcut.windowAction];\n  }]];\n  [[NSNotificationCenter defaultCenter] postNotificationName:@\"SpectacleShortcutChangedNotification\" object:self];\n}\n\n- (void)shortcutRecorder:(SpectacleShortcutRecorder *)shortcutRecorder\ndidClearExistingShortcut:(SpectacleShortcut *)shortcut\n{\n  [_shortcutManager clearShortcut:shortcut];\n  [[NSNotificationCenter defaultCenter] postNotificationName:@\"SpectacleShortcutChangedNotification\" object:self];\n}\n\n- (void)loadRegisteredShortcuts\n{\n  for (NSString *shortcutName in _shortcutRecorders.allKeys) {\n    SpectacleShortcutRecorder *shortcutRecorder = _shortcutRecorders[shortcutName];\n    SpectacleShortcut *shortcut = [_shortcutManager shortcutForShortcutName:shortcutName];\n    shortcutRecorder.shortcutName = shortcutName;\n    shortcutRecorder.shortcut = shortcut;\n    shortcutRecorder.delegate = self;\n    shortcutRecorder.shortcutValidation =\n    [[SpectacleShortcutValidation alloc] initWithShortcutManager:_shortcutManager\n                                                      validators:@[\n                                                                   [SpectacleRegisteredShortcutValidator new],\n                                                                   ]];\n  }\n}\n\n- (IBAction)swapFooterViews:(id)sender\n{\n  CATransition *transition = [CATransition animation];\n  NSView *currentFooterView = self.footerView.subviews[0];\n  NSView *nextFooterView = nil;\n  transition.type = kCATransitionPush;\n  if (currentFooterView == self.shortcutModifierLegendFooterView) {\n    nextFooterView = self.optionsFooterView;\n    transition.subtype = kCATransitionFromRight;\n  } else {\n    nextFooterView = self.shortcutModifierLegendFooterView;\n    transition.subtype = kCATransitionFromLeft;\n  }\n  self.footerView.animations = @{@\"subviews\": transition};\n  [self.footerView.animator replaceSubview:currentFooterView\n                                      with:nextFooterView];\n}\n\n- (IBAction)restoreDefaults:(id)sender\n{\n  [SpectacleUtilities displayRestoreDefaultsAlertWithConfirmationCallback:^() {\n    NSArray<SpectacleShortcut *> *shortcuts = SpectacleDefaultShortcutsWithAction(^(SpectacleShortcut *shortcut) {\n      [self->_windowPositionManager moveFrontmostWindowElement:[SpectacleAccessibilityElement frontmostWindowElement]\n                                                        action:shortcut.windowAction];\n    });\n    [self->_shortcutManager updateShortcuts:shortcuts];\n    [[NSNotificationCenter defaultCenter] postNotificationName:@\"SpectacleRestoreDefaultShortcutsNotification\"\n                                                        object:self];\n  }];\n}\n\n- (IBAction)toggleLoginItem:(id)sender\n{\n  NSBundle *applicationBundle = NSBundle.mainBundle;\n  if (self.loginItemEnabled.state == NSOnState) {\n    [SpectacleLoginItemHelper enableLoginItemForBundle:applicationBundle];\n  } else {\n    [SpectacleLoginItemHelper disableLoginItemForBundle:applicationBundle];\n  }\n}\n\n- (IBAction)toggleStatusItem:(id)sender\n{\n  NSString *notificationName = @\"SpectacleStatusItemEnabledNotification\";\n  BOOL isStatusItemEnabled = YES;\n  __block BOOL statusItemStateChanged = YES;\n  NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;\n  if ([userDefaults boolForKey:@\"StatusItemEnabled\"] == ([[sender selectedItem] tag] == 0)) {\n    return;\n  }\n  if ([sender selectedItem].tag != 0) {\n    notificationName = @\"SpectacleStatusItemDisabledNotification\";\n    isStatusItemEnabled = NO;\n    if (![userDefaults boolForKey:@\"BackgroundAlertSuppressed\"]) {\n      [SpectacleUtilities displayRunningInBackgroundAlertWithCallback:^(BOOL isConfirmed, BOOL isSuppressed) {\n        if (!isConfirmed) {\n          statusItemStateChanged = NO;\n          [sender selectItemWithTag:0];\n        }\n        [userDefaults setBool:isSuppressed forKey:@\"BackgroundAlertSuppressed\"];\n      }];\n    }\n  }\n  if (statusItemStateChanged) {\n    [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self];\n    [userDefaults setBool:isStatusItemEnabled forKey:@\"StatusItemEnabled\"];\n  }\n}\n\n- (void)dealloc\n{\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleQuantizedWindowMover.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleWindowMover.h\"\n\n@interface SpectacleQuantizedWindowMover : NSObject <SpectacleWindowMover>\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover NS_DESIGNATED_INITIALIZER;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleQuantizedWindowMover.m",
    "content": "#import \"SpectacleQuantizedWindowMover.h\"\n\n#import \"SpectacleAccessibilityElement.h\"\n\n@implementation SpectacleQuantizedWindowMover\n{\n  id<SpectacleWindowMover> _innerWindowMover;\n}\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  if (self = [super init]) {\n    _innerWindowMover = innerWindowMover;\n  }\n  return self;\n}\n\n- (instancetype)init\n{\n  return [self initWithInnerWindowMover:nil];\n}\n\n+ (instancetype)newWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  return [[self alloc] initWithInnerWindowMover:innerWindowMover];\n}\n\n- (void)moveWindowRect:(CGRect)windowRect\n         frameOfScreen:(CGRect)frameOfScreen\n  visibleFrameOfScreen:(CGRect)visibleFrameOfScreen\nfrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                action:(SpectacleWindowAction *)action\n{\n  CGRect movedWindowRect = [frontmostWindowElement rectOfElement];\n  if (!CGRectEqualToRect(movedWindowRect, windowRect)) {\n    CGRect adjustedWindowRect = windowRect;\n    while (movedWindowRect.size.width > windowRect.size.width || movedWindowRect.size.height > windowRect.size.height) {\n      if (movedWindowRect.size.width > windowRect.size.width) {\n        adjustedWindowRect.size.width -= 2;\n      }\n      if (movedWindowRect.size.height > windowRect.size.height) {\n        adjustedWindowRect.size.height -= 2;\n      }\n      if (adjustedWindowRect.size.width < windowRect.size.width * 0.85f || adjustedWindowRect.size.height < windowRect.size.height * 0.85f) {\n        break;\n      }\n      [frontmostWindowElement setRectOfElement:adjustedWindowRect];\n      movedWindowRect = [frontmostWindowElement rectOfElement];\n    }\n    adjustedWindowRect.origin.x += floor((windowRect.size.width - movedWindowRect.size.width) / 2.0f);\n    adjustedWindowRect.origin.y += floor((windowRect.size.height - movedWindowRect.size.height) / 2.0f);\n    [frontmostWindowElement setRectOfElement:adjustedWindowRect];\n  }\n  [_innerWindowMover moveWindowRect:windowRect\n                      frameOfScreen:frameOfScreen\n               visibleFrameOfScreen:visibleFrameOfScreen\n             frontmostWindowElement:frontmostWindowElement\n                             action:action];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleRegisteredShortcutValidator.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcutValidator.h\"\n\n@interface SpectacleRegisteredShortcutValidator : NSObject <SpectacleShortcutValidator>\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleRegisteredShortcutValidator.m",
    "content": "#import \"SpectacleRegisteredShortcutValidator.h\"\n\n#import \"SpectacleShortcutManager.h\"\n\n@implementation SpectacleRegisteredShortcutValidator\n\n- (BOOL)isShortcutValid:(SpectacleShortcut *)shortcut shortcutManager:(SpectacleShortcutManager *)shortcutManager\n{\n  return ![shortcutManager doesShortcutExist:shortcut];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleScreenDetectionResult.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n\n@class NSScreen;\n\n@interface SpectacleScreenDetectionResult : NSObject\n\n@property (nonatomic, readonly, strong) NSScreen *sourceScreen;\n@property (nonatomic, readonly, strong) NSScreen *destinationScreen;\n\n- (instancetype)initWithSourceScreen:(NSScreen *)sourceScreen\n                   destinationScreen:(NSScreen *)destinationScreen NS_DESIGNATED_INITIALIZER;\n\n+ (instancetype)resultWithSourceScreen:(NSScreen *)sourceScreen\n                     destinationScreen:(NSScreen *)destinationScreen;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleScreenDetectionResult.m",
    "content": "#import \"SpectacleScreenDetectionResult.h\"\n\n@implementation SpectacleScreenDetectionResult\n\n@synthesize sourceScreen = _sourceScreen;\n@synthesize destinationScreen = _destinationScreen;\n\n- (instancetype)initWithSourceScreen:(NSScreen *)sourceScreen\n                   destinationScreen:(NSScreen *)destinationScreen\n{\n  if (self = [super init]) {\n    _sourceScreen = sourceScreen;\n    _destinationScreen = destinationScreen;\n  }\n  return self;\n}\n\n+ (instancetype)resultWithSourceScreen:(NSScreen *)sourceScreen\n                     destinationScreen:(NSScreen *)destinationScreen\n{\n  return [[SpectacleScreenDetectionResult alloc] initWithSourceScreen:sourceScreen destinationScreen:destinationScreen];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleScreenDetector.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n#import \"SpectacleWindowAction.h\"\n\n@class SpectacleAccessibilityElement;\n@class SpectacleScreenDetectionResult;\n\n@interface SpectacleScreenDetector : NSObject\n\n- (SpectacleScreenDetectionResult *)screenWithAction:(SpectacleWindowAction *)action\n                              frontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                                             screens:(NSArray<NSScreen *> *)screens\n                                          mainScreen:(NSScreen *)mainScreen;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleScreenDetector.m",
    "content": "#import \"SpectacleScreenDetector.h\"\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleScreenDetectionResult.h\"\n\n@implementation SpectacleScreenDetector\n\n- (SpectacleScreenDetectionResult *)screenWithAction:(SpectacleWindowAction *)action\n                              frontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                                             screens:(NSArray<NSScreen *> *)screens\n                                          mainScreen:(NSScreen *)mainScreen\n{\n  NSArray<NSScreen *> *screensInConsistentOrder = [self screensInConsistentOrder:screens];\n  NSScreen *sourceScreen = [self screenContainingRect:[frontmostWindowElement rectOfElement]\n                                              screens:screensInConsistentOrder\n                                           mainScreen:mainScreen];\n  NSScreen *destinationScreen = sourceScreen;\n  if (SpectacleIsMovingToDisplayWindowAction(action)) {\n    destinationScreen = [self nextOrPreviousScreenToFrameOfScreen:NSRectToCGRect([sourceScreen frame])\n                                              inDirectionOfAction:action\n                                                          screens:screensInConsistentOrder];\n  }\n  return [SpectacleScreenDetectionResult resultWithSourceScreen:sourceScreen destinationScreen:destinationScreen];\n}\n\n- (NSScreen *)screenContainingRect:(CGRect)rect\n                           screens:(NSArray<NSScreen *> *)screens\n                        mainScreen:(NSScreen *)mainScreen\n{\n  CGFloat largestPercentageOfRectWithinFrameOfScreen = 0.0f;\n  NSScreen *result = mainScreen;\n  for (NSScreen *currentScreen in screens) {\n    CGRect currentFrameOfScreen = NSRectToCGRect(currentScreen.frame);\n    CGRect normalizedRect = [SpectacleAccessibilityElement normalizeCoordinatesOfRect:rect\n                                                                        frameOfScreen:currentFrameOfScreen];\n    if (CGRectContainsRect(currentFrameOfScreen, normalizedRect)) {\n      result = currentScreen;\n      break;\n    }\n    CGFloat percentageOfRectWithinCurrentFrameOfScreen = [self percentageOfRect:normalizedRect\n                                                            withinFrameOfScreen:currentFrameOfScreen];\n    if (percentageOfRectWithinCurrentFrameOfScreen > largestPercentageOfRectWithinFrameOfScreen) {\n      largestPercentageOfRectWithinFrameOfScreen = percentageOfRectWithinCurrentFrameOfScreen;\n      result = currentScreen;\n    }\n  }\n  return result;\n}\n\n- (CGFloat)percentageOfRect:(CGRect)rect withinFrameOfScreen:(CGRect)frameOfScreen\n{\n  CGRect intersectionOfRectAndFrameOfScreen = CGRectIntersection(rect, frameOfScreen);\n  CGFloat result = 0.0f;\n  if (!CGRectIsNull(intersectionOfRectAndFrameOfScreen)) {\n    result = computeAreaOfRect(intersectionOfRectAndFrameOfScreen) / computeAreaOfRect(rect);\n  }\n  return result;\n}\n\n- (NSScreen *)nextOrPreviousScreenToFrameOfScreen:(CGRect)frameOfScreen\n                              inDirectionOfAction:(SpectacleWindowAction *)action\n                                          screens:(NSArray<NSScreen *> *)screens\n{\n  NSScreen *result = nil;\n  if (screens.count <= 1) {\n    return result;\n  }\n  for (NSInteger i = 0; i < screens.count; i++) {\n    NSScreen *currentScreen = screens[i];\n    CGRect currentFrameOfScreen = NSRectToCGRect(currentScreen.frame);\n    NSInteger nextOrPreviousIndex = i;\n    if (!CGRectEqualToRect(currentFrameOfScreen, frameOfScreen)) {\n      continue;\n    }\n    if (SpectacleIsNextDisplayWindowAction(action)) {\n      nextOrPreviousIndex++;\n    } else if (SpectacleIsPreviousDisplayWindowAction(action)) {\n      nextOrPreviousIndex--;\n    }\n    if (nextOrPreviousIndex < 0) {\n      nextOrPreviousIndex = screens.count - 1;\n    } else if (nextOrPreviousIndex >= screens.count) {\n      nextOrPreviousIndex = 0;\n    }\n    result = screens[nextOrPreviousIndex];\n    break;\n  }\n  return result;\n}\n\n- (NSArray<NSScreen *> *)screensInConsistentOrder:(NSArray<NSScreen *> *)screens\n{\n  return [[screens sortedArrayWithOptions:NSSortStable usingComparator:^(NSScreen *screenOne, NSScreen *screenTwo) {\n    if (CGPointEqualToPoint(screenOne.frame.origin, CGPointMake(0, 0))) {\n      return NSOrderedAscending;\n    } else if (CGPointEqualToPoint(screenTwo.frame.origin, CGPointMake(0, 0))) {\n      return NSOrderedDescending;\n    }\n    return (NSComparisonResult)(screenTwo.frame.origin.y - screenOne.frame.origin.y);\n  }] sortedArrayWithOptions:NSSortStable usingComparator:^(NSScreen *screenOne, NSScreen *screenTwo) {\n    if (CGPointEqualToPoint(screenOne.frame.origin, CGPointMake(0, 0))) {\n      return NSOrderedAscending;\n    } else if (CGPointEqualToPoint(screenTwo.frame.origin, CGPointMake(0, 0))) {\n      return NSOrderedDescending;\n    }\n    return (NSComparisonResult)(screenTwo.frame.origin.x - screenOne.frame.origin.x);\n  }];\n}\n\nstatic CGFloat computeAreaOfRect(CGRect rect)\n{\n  return rect.size.width * rect.size.height;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcut.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n#import \"SpectacleWindowAction.h\"\n\n@class SpectacleShortcut;\n\ntypedef void(^SpectacleShortcutAction)(SpectacleShortcut *);\n\n@interface SpectacleShortcut : NSObject <NSCoding>\n\n@property (nonatomic, readonly, copy) NSString *shortcutName;\n@property (nonatomic, readonly, assign) NSInteger shortcutKeyCode;\n@property (nonatomic, readonly, assign) NSUInteger shortcutModifiers;\n@property (nonatomic, readonly, strong) SpectacleShortcutAction shortcutAction;\n@property (nonatomic, readonly, copy) NSString *shortcutKeyBinding;\n@property (nonatomic, readonly, strong) SpectacleWindowAction *windowAction;\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName shortcutKeyBinding:(NSString *)shortcutKeyBinding;\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                  shortcutKeyBinding:(NSString *)shortcutKeyBinding\n                      shortcutAction:(SpectacleShortcutAction)shortcutAction;\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                     shortcutKeyCode:(NSInteger)shortcutKeyCode\n                   shortcutModifiers:(NSUInteger)shortcutModifiers;\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                     shortcutKeyCode:(NSInteger)shortcutKeyCode\n                   shortcutModifiers:(NSUInteger)shortcutModifiers\n                      shortcutAction:(SpectacleShortcutAction)shortcutAction NS_DESIGNATED_INITIALIZER;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n- (instancetype)copyWithShortcutAction:(SpectacleShortcutAction)shortcutAction;\n\n- (void)triggerShortcutAction;\n\n- (BOOL)isClearedShortcut;\n\n- (NSString *)displayString;\n\n- (BOOL)isEqual:(id)object;\n- (BOOL)isEqualToShortcut:(SpectacleShortcut *)shortcut;\n\n- (BOOL)containsModifiers:(NSUInteger)modifiers;\n\n+ (BOOL)validCocoaModifiers:(NSUInteger)modifiers;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcut.m",
    "content": "#import \"SpectacleShortcut.h\"\n\n#import <Cocoa/Cocoa.h>\n\n#import \"SpectacleShortcutKeyBindings.h\"\n#import \"SpectacleShortcutTranslations.h\"\n\n@implementation SpectacleShortcut\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName shortcutKeyBinding:(NSString *)shortcutKeyBinding\n{\n  return [self initWithShortcutName:shortcutName shortcutKeyBinding:shortcutKeyBinding shortcutAction:nil];\n}\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                  shortcutKeyBinding:(NSString *)shortcutKeyBinding\n                      shortcutAction:(SpectacleShortcutAction)shortcutAction\n{\n  NSNumber *shortcutKeyCode = SpectacleConvertShortcutKeyBindingToKeyCode(shortcutKeyBinding);\n  return [self initWithShortcutName:shortcutName\n                    shortcutKeyCode:shortcutKeyCode ? [shortcutKeyCode integerValue] : -1\n                  shortcutModifiers:[SpectacleConvertShortcutKeyBindingToModifiers(shortcutKeyBinding) unsignedIntegerValue]\n                     shortcutAction:shortcutAction];\n}\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                     shortcutKeyCode:(NSInteger)shortcutKeyCode\n                   shortcutModifiers:(NSUInteger)shortcutModifiers\n{\n  return [self initWithShortcutName:shortcutName\n                    shortcutKeyCode:shortcutKeyCode\n                  shortcutModifiers:shortcutModifiers\n                     shortcutAction:nil];\n}\n\n- (instancetype)initWithShortcutName:(NSString *)shortcutName\n                     shortcutKeyCode:(NSInteger)shortcutKeyCode\n                   shortcutModifiers:(NSUInteger)shortcutModifiers\n                      shortcutAction:(SpectacleShortcutAction)shortcutAction\n{\n  if (self = [super init]) {\n    _shortcutName = shortcutName;\n    _shortcutKeyCode = shortcutKeyCode;\n    _shortcutModifiers = SpectacleConvertModifiersToCarbonIfNecessary(shortcutModifiers);\n    _shortcutAction = shortcutAction;\n  }\n  return self;\n}\n\n- (instancetype)copyWithShortcutAction:(SpectacleShortcutAction)shortcutAction\n{\n  return [[SpectacleShortcut alloc] initWithShortcutName:_shortcutName\n                                         shortcutKeyCode:_shortcutKeyCode\n                                       shortcutModifiers:_shortcutModifiers\n                                          shortcutAction:shortcutAction];\n}\n\n- (instancetype)initWithCoder:(NSCoder *)coder\n{\n  return [self initWithShortcutName:[coder decodeObjectForKey:@\"name\"]\n                    shortcutKeyCode:[coder decodeIntegerForKey:@\"keyCode\"]\n                  shortcutModifiers:[coder decodeIntegerForKey:@\"modifiers\"]];\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder\n{\n  [coder encodeObject:_shortcutName forKey:@\"name\"];\n  [coder encodeInteger:_shortcutKeyCode forKey:@\"keyCode\"];\n  [coder encodeInteger:_shortcutModifiers forKey:@\"modifiers\"];\n}\n\n- (NSString *)shortcutKeyBinding\n{\n  return SpectacleConvertShortcutToKeyBinding(self);\n}\n\n- (SpectacleWindowAction *)windowAction\n{\n  NSString *name = _shortcutName;\n  SpectacleWindowAction *windowAction = kSpectacleWindowActionNone;\n\n  if ([name isEqualToString:@\"MoveToCenter\"]) {\n    windowAction = kSpectacleWindowActionCenter;\n  } else if ([name isEqualToString:@\"MoveToFullscreen\"]) {\n    windowAction = kSpectacleWindowActionFullscreen;\n  } else if ([name isEqualToString:@\"MoveToLeftHalf\"]) {\n    windowAction = kSpectacleWindowActionLeftHalf;\n  } else if ([name isEqualToString:@\"MoveToRightHalf\"]) {\n    windowAction = kSpectacleWindowActionRightHalf;\n  } else if ([name isEqualToString:@\"MoveToTopHalf\"]) {\n    windowAction = kSpectacleWindowActionTopHalf;\n  } else if ([name isEqualToString:@\"MoveToBottomHalf\"]) {\n    windowAction = kSpectacleWindowActionBottomHalf;\n  } else if ([name isEqualToString:@\"MoveToUpperLeft\"]) {\n    windowAction = kSpectacleWindowActionUpperLeft;\n  } else if ([name isEqualToString:@\"MoveToLowerLeft\"]) {\n    windowAction = kSpectacleWindowActionLowerLeft;\n  } else if ([name isEqualToString:@\"MoveToUpperRight\"]) {\n    windowAction = kSpectacleWindowActionUpperRight;\n  } else if ([name isEqualToString:@\"MoveToLowerRight\"]) {\n    windowAction = kSpectacleWindowActionLowerRight;\n  } else if ([name isEqualToString:@\"MoveToNextDisplay\"]) {\n    windowAction = kSpectacleWindowActionNextDisplay;\n  } else if ([name isEqualToString:@\"MoveToPreviousDisplay\"]) {\n    windowAction = kSpectacleWindowActionPreviousDisplay;\n  } else if ([name isEqualToString:@\"MoveToNextThird\"]) {\n    windowAction = kSpectacleWindowActionNextThird;\n  } else if ([name isEqualToString:@\"MoveToPreviousThird\"]) {\n    windowAction = kSpectacleWindowActionPreviousThird;\n  } else if ([name isEqualToString:@\"MakeLarger\"]) {\n    windowAction = kSpectacleWindowActionLarger;\n  } else if ([name isEqualToString:@\"MakeSmaller\"]) {\n    windowAction = kSpectacleWindowActionSmaller;\n  } else if ([name isEqualToString:@\"UndoLastMove\"]) {\n    windowAction = kSpectacleWindowActionUndo;\n  } else if ([name isEqualToString:@\"RedoLastMove\"]) {\n    windowAction = kSpectacleWindowActionRedo;\n  }\n\n  return windowAction;\n}\n\n- (void)triggerShortcutAction\n{\n  if (_shortcutAction) {\n    _shortcutAction(self);\n  }\n}\n\n- (BOOL)isClearedShortcut\n{\n  return _shortcutKeyCode == -1 || (_shortcutKeyCode == 0 && _shortcutModifiers == 0);\n}\n\n- (NSString *)displayString\n{\n  return SpectacleTranslateShortcut(self);\n}\n\n- (BOOL)isEqual:(id)object\n{\n  if (object == self) {\n    return YES;\n  }\n  if (!object || ![object isKindOfClass:[self class]]) {\n    return NO;\n  }\n  return [self isEqualToShortcut:object];\n}\n\n- (BOOL)isEqualToShortcut:(SpectacleShortcut *)shortcut\n{\n  if (shortcut == self) {\n    return YES;\n  }\n  if (shortcut.shortcutKeyCode != _shortcutKeyCode) {\n    return NO;\n  }\n  if (shortcut.shortcutModifiers != _shortcutModifiers) {\n    return NO;\n  }\n  return YES;\n}\n\n- (BOOL)containsModifiers:(NSUInteger)modifiers\n{\n  return _shortcutModifiers == SpectacleConvertModifiersToCarbonIfNecessary(modifiers);\n}\n\n+ (BOOL)validCocoaModifiers:(NSUInteger)modifiers\n{\n  return ((modifiers & NSAlternateKeyMask)\n          || (modifiers & NSCommandKeyMask)\n          || (modifiers & NSControlKeyMask)\n          || (modifiers & NSShiftKeyMask));\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutHolder.h",
    "content": "#import <Carbon/Carbon.h>\n\n#import \"SpectacleMacros.h\"\n\n@class SpectacleShortcut;\n\n@interface SpectacleShortcutHolder : NSObject\n\n@property (nonatomic, readonly, assign) EventHotKeyID shortcutID;\n@property (nonatomic, readonly, strong) SpectacleShortcut *shortcut;\n@property (nonatomic, readonly, assign) EventHotKeyRef shortcutRef;\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID;\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID\n                          shortcut:(SpectacleShortcut *)shortcut;\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID\n                          shortcut:(SpectacleShortcut *)shortcut\n                       shortcutRef:(EventHotKeyRef)shortcutRef NS_DESIGNATED_INITIALIZER;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n- (instancetype)copyWithShortcut:(SpectacleShortcut *)shortcut;\n- (instancetype)copyWithShortcutRef:(EventHotKeyRef)shortcutRef;\n- (instancetype)copyWithClearedShortcut;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutHolder.m",
    "content": "#import \"SpectacleShortcutHolder.h\"\n\n#import \"SpectacleShortcut.h\"\n\n@implementation SpectacleShortcutHolder\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID\n{\n  return [self initWithShortcutID:shortcutID shortcut:nil shortcutRef:nil];\n}\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID\n                          shortcut:(SpectacleShortcut *)shortcut\n{\n  return [self initWithShortcutID:shortcutID shortcut:shortcut shortcutRef:nil];\n}\n\n- (instancetype)initWithShortcutID:(EventHotKeyID)shortcutID\n                          shortcut:(SpectacleShortcut *)shortcut\n                       shortcutRef:(EventHotKeyRef)shortcutRef\n{\n  if (self = [super init]) {\n    _shortcutID = shortcutID;\n    _shortcut = shortcut;\n    _shortcutRef = shortcutRef;\n  }\n  return self;\n}\n\n- (instancetype)copyWithShortcut:(SpectacleShortcut *)shortcut\n{\n  return [[SpectacleShortcutHolder alloc] initWithShortcutID:_shortcutID\n                                                    shortcut:shortcut\n                                                 shortcutRef:_shortcutRef];\n}\n\n- (instancetype)copyWithShortcutRef:(EventHotKeyRef)shortcutRef\n{\n  return [[SpectacleShortcutHolder alloc] initWithShortcutID:_shortcutID\n                                                    shortcut:_shortcut\n                                                 shortcutRef:shortcutRef];\n}\n\n- (instancetype)copyWithClearedShortcut\n{\n  SpectacleShortcut *clearedShortcut = [[SpectacleShortcut alloc] initWithShortcutName:_shortcut.shortcutName\n                                                                       shortcutKeyCode:-1\n                                                                     shortcutModifiers:0];\n  return [[SpectacleShortcutHolder alloc] initWithShortcutID:_shortcutID\n                                                    shortcut:clearedShortcut\n                                                 shortcutRef:nil];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutJSONStorage.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcutStorageMigrationDestination.h\"\n\n@interface SpectacleShortcutJSONStorage : NSObject <SpectacleShortcutStorageMigrationDestination>\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutJSONStorage.m",
    "content": "#import \"SpectacleShortcutJSONStorage.h\"\n\n@implementation SpectacleShortcutJSONStorage\n\n- (NSArray<SpectacleShortcut *> *)loadShortcutsWithAction:(SpectacleShortcutAction)action\n{\n  NSError *error;\n  NSURL *shortcutsFileURL = findShortcutsFileURL(&error);\n  if (!shortcutsFileURL) {\n    NSLog(@\"Unable to locate the shortcuts file: %@\", error.localizedDescription);\n    return nil;\n  }\n  NSData *content = [NSData dataWithContentsOfURL:shortcutsFileURL];\n  NSArray<NSDictionary *> *jsonArray = [NSJSONSerialization JSONObjectWithData:content\n                                                                       options:0\n                                                                         error:&error];\n  if (!jsonArray) {\n    NSLog(@\"Deserializing shortcuts failed: %@\", error.localizedDescription);\n    return nil;\n  }\n  return shortcutsFromJsonObject(jsonArray, action);\n}\n\n- (void)storeShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts\n{\n  NSError *error;\n  NSURL *shortcutsFileURL = findShortcutsFileURL(&error);\n  if (!shortcutsFileURL) {\n    NSLog(@\"Unable to locate the shortcuts file: %@\", error.localizedDescription);\n    return;\n  }\n  NSData *contents = [NSJSONSerialization dataWithJSONObject:jsonObjectFromShortcuts(shortcuts)\n                                                     options:NSJSONWritingPrettyPrinted\n                                                       error:&error];\n  if (![contents writeToURL:shortcutsFileURL atomically:YES]) {\n    NSLog(@\"Unable to store shortcuts at location: %@\", [shortcutsFileURL path]);\n  }\n}\n\n- (BOOL)isMigrationNeeded\n{\n  NSError *error;\n  NSURL *shortcutsFileURL = findShortcutsFileURL(&error);\n  if (!shortcutsFileURL) {\n    NSLog(@\"Unable to locate the shortcuts file: %@\", error.localizedDescription);\n    return YES;\n  }\n  return ![[NSFileManager defaultManager] fileExistsAtPath:[shortcutsFileURL path]];\n}\n\nstatic NSURL *findShortcutsFileURL(NSError **error)\n{\n  NSURL *shortcutsFileURL = [findOrCreateSpectacleDirectory(error) URLByAppendingPathComponent:@\"Shortcuts.json\"];\n  return shortcutsFileURL.URLByResolvingSymlinksInPath;\n}\n\nstatic NSURL *findOrCreateSpectacleDirectory(NSError **error)\n{\n  NSURL *applicationSupportDirectory = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory\n                                                                              inDomain:NSUserDomainMask\n                                                                     appropriateForURL:nil\n                                                                                create:YES\n                                                                                 error:error];\n  if (!applicationSupportDirectory) {\n    return nil;\n  }\n  NSURL *spectacleDirectory = [applicationSupportDirectory URLByAppendingPathComponent:@\"Spectacle\"];\n  BOOL success = [[NSFileManager defaultManager] createDirectoryAtURL:spectacleDirectory\n                                          withIntermediateDirectories:YES\n                                                           attributes:nil\n                                                                error:error];\n  if (!success) {\n    return nil;\n  }\n  return spectacleDirectory;\n}\n\nstatic NSArray<NSDictionary *> *jsonObjectFromShortcuts(NSArray<SpectacleShortcut *> *shortcuts)\n{\n  NSMutableArray<NSDictionary *> *jsonArray = [NSMutableArray new];\n  for (SpectacleShortcut *shortcut in shortcuts) {\n    [jsonArray addObject:@{\n                           @\"shortcut_name\" : shortcut.shortcutName,\n                           @\"shortcut_key_binding\" : shortcut.shortcutKeyBinding ?: [NSNull null],\n                           }];\n  }\n  return jsonArray;\n}\n\nstatic NSArray<SpectacleShortcut *> *shortcutsFromJsonObject(NSArray<NSDictionary *> *jsonArray, SpectacleShortcutAction action)\n{\n  NSMutableArray<SpectacleShortcut *> *shortcuts = [NSMutableArray new];\n  for (NSDictionary *jsonObject in jsonArray) {\n    NSString *shortcutName = jsonObject[@\"shortcut_name\"];\n    NSString *shortcutKeyBinding = jsonObject[@\"shortcut_key_binding\"];\n    [shortcuts addObject:[[SpectacleShortcut alloc] initWithShortcutName:shortcutName\n                                                      shortcutKeyBinding:[shortcutKeyBinding isKindOfClass:[NSNull class]] ? nil : shortcutKeyBinding\n                                                          shortcutAction:action]];\n  }\n  return shortcuts;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutKeyBindings.h",
    "content": "#import <Foundation/Foundation.h>\n\n@class SpectacleShortcut;\n\nNSNumber *SpectacleConvertShortcutKeyBindingToKeyCode(NSString *keyBinding);\nNSNumber *SpectacleConvertShortcutKeyBindingToModifiers(NSString *keyBinding);\n\nNSString *SpectacleConvertShortcutToKeyBinding(SpectacleShortcut *shortcut);\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutKeyBindings.m",
    "content": "#import \"SpectacleShortcutKeyBindings.h\"\n\n#import <Carbon/Carbon.h>\n\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutTranslations.h\"\n\nstatic NSDictionary<NSNumber *, NSString *> *keyCodeToKeyCodeComponentConversionTable(void);\nstatic NSDictionary<NSNumber *, NSString *> *keyCodeToNamedKeyCodeComponentConversionTable(void);\nstatic NSDictionary<NSString *, NSNumber *> *namedKeyCodeComponentToKeyCodeConversionTable(void);\nstatic NSDictionary<NSString *, NSNumber *> *modiferComponentToCarbonModifierConversionTable(void);\nstatic NSDictionary<NSString *, NSNumber *> *keyCodeComponentToKeyCodeConversionTable(void);\nstatic NSString *keyCodeComponentForKeyCode(NSInteger keyCode);\nstatic NSArray<NSString *> *modifierComponentsForModifiers(NSUInteger modifiers);\n\nNSNumber *SpectacleConvertShortcutKeyBindingToKeyCode(NSString *keyBinding)\n{\n  NSString *keyCodeComponent = [[keyBinding componentsSeparatedByString:@\"+\"] lastObject];\n  NSString *sanitizedKeyCodeComponent = [keyCodeComponent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];\n  if (sanitizedKeyCodeComponent.length == 0) {\n    return nil;\n  }\n  NSString *normalizedKeyCodeComponent = [sanitizedKeyCodeComponent uppercaseString];\n  NSNumber *namedBindingKeyCode = namedKeyCodeComponentToKeyCodeConversionTable()[normalizedKeyCodeComponent];\n  if (namedBindingKeyCode) {\n    return namedBindingKeyCode;\n  }\n  return keyCodeComponentToKeyCodeConversionTable()[normalizedKeyCodeComponent];\n}\n\nNSNumber *SpectacleConvertShortcutKeyBindingToModifiers(NSString *keyBinding)\n{\n  NSArray<NSString *> *keyBindingComponents = [keyBinding componentsSeparatedByString:@\"+\"];\n  if (keyBindingComponents.count < 2) {\n    return nil;\n  }\n  NSRange rangeOfModifierComponents = NSMakeRange(0, keyBindingComponents.count - 1);\n  NSArray<NSString *> *modifierComponents = [keyBindingComponents subarrayWithRange:rangeOfModifierComponents];\n  NSNumber *modifiers = @0;\n  for (NSString *modifierComponent in modifierComponents) {\n    NSString *sanitizedModifierComponent = [modifierComponent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];\n    NSString *normalizedModifierComponent = [sanitizedModifierComponent uppercaseString];\n    NSNumber *modifier = modiferComponentToCarbonModifierConversionTable()[normalizedModifierComponent];\n    if (modifier) {\n      modifiers = @([modifiers unsignedIntegerValue] | [modifier unsignedIntegerValue]);\n    }\n  }\n  return modifiers;\n}\n\nNSString *SpectacleConvertShortcutToKeyBinding(SpectacleShortcut *shortcut)\n{\n  NSString *keyCodeComponent = [keyCodeComponentForKeyCode(shortcut.shortcutKeyCode) lowercaseString];\n  NSArray<NSString *> *modifierComponents = modifierComponentsForModifiers(shortcut.shortcutModifiers);\n  if ([shortcut isClearedShortcut] || !keyCodeComponent) {\n    return nil;\n  }\n  return [[modifierComponents arrayByAddingObject:keyCodeComponent] componentsJoinedByString:@\"+\"];\n}\n\nstatic NSDictionary<NSNumber *, NSString *> *keyCodeToKeyCodeComponentConversionTable(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSNumber *, NSString *> *conversionTable;\n  dispatch_once(&onceToken, ^{\n    conversionTable = @{\n                        @(kVK_ANSI_0):            @\"0\",\n                        @(kVK_ANSI_1):            @\"1\",\n                        @(kVK_ANSI_2):            @\"2\",\n                        @(kVK_ANSI_3):            @\"3\",\n                        @(kVK_ANSI_4):            @\"4\",\n                        @(kVK_ANSI_5):            @\"5\",\n                        @(kVK_ANSI_6):            @\"6\",\n                        @(kVK_ANSI_7):            @\"7\",\n                        @(kVK_ANSI_8):            @\"8\",\n                        @(kVK_ANSI_9):            @\"9\",\n                        @(kVK_ANSI_A):            @\"A\",\n                        @(kVK_ANSI_B):            @\"B\",\n                        @(kVK_ANSI_C):            @\"C\",\n                        @(kVK_ANSI_D):            @\"D\",\n                        @(kVK_ANSI_E):            @\"E\",\n                        @(kVK_ANSI_F):            @\"F\",\n                        @(kVK_ANSI_G):            @\"G\",\n                        @(kVK_ANSI_H):            @\"H\",\n                        @(kVK_ANSI_I):            @\"I\",\n                        @(kVK_ANSI_J):            @\"J\",\n                        @(kVK_ANSI_K):            @\"K\",\n                        @(kVK_ANSI_L):            @\"L\",\n                        @(kVK_ANSI_M):            @\"M\",\n                        @(kVK_ANSI_N):            @\"N\",\n                        @(kVK_ANSI_O):            @\"O\",\n                        @(kVK_ANSI_P):            @\"P\",\n                        @(kVK_ANSI_Q):            @\"Q\",\n                        @(kVK_ANSI_R):            @\"R\",\n                        @(kVK_ANSI_S):            @\"S\",\n                        @(kVK_ANSI_T):            @\"T\",\n                        @(kVK_ANSI_U):            @\"U\",\n                        @(kVK_ANSI_V):            @\"V\",\n                        @(kVK_ANSI_W):            @\"W\",\n                        @(kVK_ANSI_X):            @\"X\",\n                        @(kVK_ANSI_Y):            @\"Y\",\n                        @(kVK_ANSI_Z):            @\"Z\",\n\n                        @(kVK_ANSI_Equal):        @\"=\",\n                        @(kVK_ANSI_Minus):        @\"-\",\n                        @(kVK_ANSI_RightBracket): @\"]\",\n                        @(kVK_ANSI_LeftBracket):  @\"[\",\n                        @(kVK_ANSI_Quote):        @\"'\",\n                        @(kVK_ANSI_Semicolon):    @\";\",\n                        @(kVK_ANSI_Backslash):    @\"\\\\\",\n                        @(kVK_ANSI_Comma):        @\",\",\n                        @(kVK_ANSI_Slash):        @\"/\",\n                        @(kVK_ANSI_Period):       @\".\",\n                        @(kVK_ANSI_Grave):        @\"`\",\n                        };\n  });\n  return conversionTable;\n}\n\nstatic NSDictionary<NSNumber *, NSString *> *keyCodeToNamedKeyCodeComponentConversionTable(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSNumber *, NSString *> *conversionTable;\n  dispatch_once(&onceToken, ^{\n    NSMutableDictionary<NSNumber *, NSString *> *generatedConversionTable = [NSMutableDictionary new];\n    for (NSString *namedKeyCodeComponent in [namedKeyCodeComponentToKeyCodeConversionTable() allKeys]) {\n      generatedConversionTable[namedKeyCodeComponentToKeyCodeConversionTable()[namedKeyCodeComponent]] = namedKeyCodeComponent;\n    }\n    conversionTable = generatedConversionTable;\n  });\n  return conversionTable;\n}\n\nstatic NSDictionary<NSString *, NSNumber *> *namedKeyCodeComponentToKeyCodeConversionTable(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSString *, NSNumber *> *conversionTable;\n  dispatch_once(&onceToken, ^{\n    conversionTable = @{\n                        @\"F1\":             @(kVK_F1),\n                        @\"F2\":             @(kVK_F2),\n                        @\"F3\":             @(kVK_F3),\n                        @\"F4\":             @(kVK_F4),\n                        @\"F5\":             @(kVK_F5),\n                        @\"F6\":             @(kVK_F6),\n                        @\"F7\":             @(kVK_F7),\n                        @\"F8\":             @(kVK_F8),\n                        @\"F9\":             @(kVK_F9),\n                        @\"F10\":            @(kVK_F10),\n                        @\"F11\":            @(kVK_F11),\n                        @\"F12\":            @(kVK_F12),\n                        @\"F13\":            @(kVK_F13),\n                        @\"F14\":            @(kVK_F14),\n                        @\"F15\":            @(kVK_F15),\n                        @\"F16\":            @(kVK_F16),\n                        @\"F17\":            @(kVK_F17),\n                        @\"F18\":            @(kVK_F18),\n                        @\"F19\":            @(kVK_F19),\n                        @\"F20\":            @(kVK_F20),\n\n                        @\"KEYPADDECIMAL\":  @(kVK_ANSI_KeypadDecimal),\n                        @\"KEYPADMULTIPLY\": @(kVK_ANSI_KeypadMultiply),\n                        @\"KEYPADPLUS\":     @(kVK_ANSI_KeypadPlus),\n                        @\"KEYPADCLEAR\":    @(kVK_ANSI_KeypadClear),\n                        @\"KEYPADDIVIDE\":   @(kVK_ANSI_KeypadDivide),\n                        @\"KEYPADENTER\":    @(kVK_ANSI_KeypadEnter),\n                        @\"KEYPADMINUS\":    @(kVK_ANSI_KeypadMinus),\n                        @\"KEYPADEQUALS\":   @(kVK_ANSI_KeypadEquals),\n                        @\"KEYPAD0\":        @(kVK_ANSI_Keypad0),\n                        @\"KEYPAD1\":        @(kVK_ANSI_Keypad1),\n                        @\"KEYPAD2\":        @(kVK_ANSI_Keypad2),\n                        @\"KEYPAD3\":        @(kVK_ANSI_Keypad3),\n                        @\"KEYPAD4\":        @(kVK_ANSI_Keypad4),\n                        @\"KEYPAD5\":        @(kVK_ANSI_Keypad5),\n                        @\"KEYPAD6\":        @(kVK_ANSI_Keypad6),\n                        @\"KEYPAD7\":        @(kVK_ANSI_Keypad7),\n                        @\"KEYPAD8\":        @(kVK_ANSI_Keypad8),\n                        @\"KEYPAD9\":        @(kVK_ANSI_Keypad9),\n\n                        @\"RETURN\":         @(kVK_Return),\n                        @\"TAB\":            @(kVK_Tab),\n                        @\"SPACE\":          @(kVK_Space),\n                        @\"DELETE\":         @(kVK_Delete),\n                        @\"ESCAPE\":         @(kVK_Escape),\n                        @\"COMMAND\":        @(kVK_Command),\n                        @\"SHIFT\":          @(kVK_Shift),\n                        @\"CAPSLOCK\":       @(kVK_CapsLock),\n                        @\"OPTION\":         @(kVK_Option),\n                        @\"CONTROL\":        @(kVK_Control),\n                        @\"RIGHTSHIFT\":     @(kVK_RightShift),\n                        @\"RIGHTOPTION\":    @(kVK_RightOption),\n                        @\"RIGHTCONTROL\":   @(kVK_RightControl),\n                        @\"FUNCTION\":       @(kVK_Function),\n                        @\"VOLUMEUP\":       @(kVK_VolumeUp),\n                        @\"VOLUMEDOWN\":     @(kVK_VolumeDown),\n                        @\"MUTE\":           @(kVK_Mute),\n                        @\"HELP\":           @(kVK_Help),\n                        @\"HOME\":           @(kVK_Home),\n                        @\"PAGEUP\":         @(kVK_PageUp),\n                        @\"FORWARDDELETE\":  @(kVK_ForwardDelete),\n                        @\"END\":            @(kVK_End),\n                        @\"PAGEDOWN\":       @(kVK_PageDown),\n                        @\"LEFT\":           @(kVK_LeftArrow),\n                        @\"RIGHT\":          @(kVK_RightArrow),\n                        @\"DOWN\":           @(kVK_DownArrow),\n                        @\"UP\":             @(kVK_UpArrow),\n                        };\n  });\n  return conversionTable;\n}\n\nstatic NSDictionary<NSString *, NSNumber *> *modiferComponentToCarbonModifierConversionTable(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSString *, NSNumber *> *conversionTable;\n  dispatch_once(&onceToken, ^{\n    conversionTable = @{\n                        @\"COMMAND\": @(cmdKey),\n                        @\"CMD\":     @(cmdKey),     // Alias for \"COMMAND\"\n\n                        @\"SHIFT\":   @(shiftKey),\n\n                        @\"OPTION\":  @(optionKey),\n                        @\"ALT\":     @(optionKey),  // Alias for \"OPTION\"\n\n                        @\"CONTROL\": @(controlKey),\n                        @\"CTRL\":    @(controlKey), // Alias for \"CONTROL\"\n                        };\n  });\n  return conversionTable;\n}\n\nstatic NSDictionary<NSString *, NSNumber *> *keyCodeComponentToKeyCodeConversionTable(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSString *, NSNumber *> *conversionTable;\n  dispatch_once(&onceToken, ^{\n    NSMutableDictionary<NSString *, NSNumber *> *generatedConversionTable = [NSMutableDictionary new];\n    for (NSNumber *keyCode in [keyCodeToKeyCodeComponentConversionTable() allKeys]) {\n      generatedConversionTable[keyCodeComponentForKeyCode([keyCode integerValue])] = keyCode;\n    }\n    conversionTable = generatedConversionTable;\n  });\n  return conversionTable;\n}\n\nstatic NSString *keyCodeComponentForKeyCode(NSInteger keyCode)\n{\n  NSString *namedKeyCodeComponent = keyCodeToNamedKeyCodeComponentConversionTable()[@(keyCode)];\n  return (namedKeyCodeComponent.length > 0) ? namedKeyCodeComponent : keyCodeToKeyCodeComponentConversionTable()[@(keyCode)];\n}\n\nstatic NSArray<NSString *> *modifierComponentsForModifiers(NSUInteger modifiers)\n{\n  NSMutableArray<NSString *> *modifierComponents = [NSMutableArray new];\n  if (modifiers & controlKey) {\n    [modifierComponents addObject:@\"ctrl\"];\n  }\n  if (modifiers & optionKey) {\n    [modifierComponents addObject:@\"alt\"];\n  }\n  if (modifiers & shiftKey) {\n    [modifierComponents addObject:@\"shift\"];\n  }\n  if (modifiers & cmdKey) {\n    [modifierComponents addObject:@\"cmd\"];\n  }\n  return modifierComponents;\n}\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutManager.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n\n@class SpectacleShortcut;\n\n@protocol SpectacleShortcutStorage;\n\n@interface SpectacleShortcutManager : NSObject\n\n- (instancetype)initWithShortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage NS_DESIGNATED_INITIALIZER;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n- (void)manageShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts;\n\n- (void)updateShortcut:(SpectacleShortcut *)shortcut;\n- (void)updateShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts;\n\n- (void)clearShortcut:(SpectacleShortcut *)shortcut;\n\n- (NSArray<SpectacleShortcut *> *)shortcuts;\n- (SpectacleShortcut *)shortcutForShortcutName:(NSString *)shortcutName;\n\n- (BOOL)doesShortcutExist:(SpectacleShortcut *)shortcut;\n\n- (void)registerShortcuts;\n- (void)unregisterShortcuts;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutManager.m",
    "content": "#import \"SpectacleShortcutManager.h\"\n\n#import <Carbon/Carbon.h>\n\n#import \"SpectacleShortcutHolder.h\"\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutStorage.h\"\n\nstatic EventHotKeyID currentShortcutID = {\n  .signature = 'ZERO',\n  .id = 0\n};\n\n@implementation SpectacleShortcutManager\n{\n  id<SpectacleShortcutStorage> _shortcutStorage;\n  NSMutableDictionary<NSString *, SpectacleShortcutHolder *> *_registeredShortcutsByName;\n  BOOL _areShorcutsEnabled;\n}\n\n- (instancetype)initWithShortcutStorage:(id<SpectacleShortcutStorage>)shortcutStorage\n{\n  if (self = [super init]) {\n    _shortcutStorage = shortcutStorage;\n    _registeredShortcutsByName = [NSMutableDictionary new];\n    _areShorcutsEnabled = YES;\n    [self installApplicationEventHandler];\n  }\n  return self;\n}\n\n- (void)manageShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts\n{\n  for (SpectacleShortcut *shortcut in shortcuts) {\n    NSString *shortcutName = shortcut.shortcutName;\n    SpectacleShortcutHolder *shortcutHolder = _registeredShortcutsByName[shortcutName];\n    if (shortcutHolder) {\n      NSLog(@\"Unable to add shortcut %@ as it already exists.\", shortcutName);\n      continue;\n    }\n    currentShortcutID.id = ++currentShortcutID.id;\n    shortcutHolder = [[SpectacleShortcutHolder alloc] initWithShortcutID:currentShortcutID shortcut:shortcut];\n    _registeredShortcutsByName[shortcutName] = _areShorcutsEnabled ? [self registerEventHotKey:shortcutHolder] : shortcutHolder;\n  }\n  [self storeShortcuts];\n}\n\n- (void)updateShortcut:(SpectacleShortcut *)shortcut\n{\n  NSString *shortcutName = shortcut.shortcutName;\n  SpectacleShortcutHolder *shortcutHolder = _registeredShortcutsByName[shortcutName];\n  if (!shortcutHolder) {\n    NSLog(@\"Unable to update shortcut %@ as it does not exists.\", shortcutName);\n    return;\n  }\n  if (_areShorcutsEnabled && [self unregisterEventHotKey:shortcutHolder]) {\n    NSLog(@\"Unable to unregister event hot key for shortcut: %@\", shortcutName);\n    return;\n  }\n  SpectacleShortcutHolder *registeredShortcutHolder = _areShorcutsEnabled ? [self registerEventHotKey:shortcutHolder] : shortcutHolder;\n  _registeredShortcutsByName[shortcutName] = [registeredShortcutHolder\n                                              copyWithShortcut:\n                                              [shortcut\n                                               copyWithShortcutAction:\n                                               shortcut.shortcutAction ?: shortcutHolder.shortcut.shortcutAction]];\n  [self storeShortcuts];\n}\n\n- (void)updateShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts\n{\n  for (SpectacleShortcut *shortcut in shortcuts) {\n    [self updateShortcut:shortcut];\n  }\n}\n\n- (void)clearShortcut:(SpectacleShortcut *)shortcut\n{\n  NSString *shortcutName = shortcut.shortcutName;\n  SpectacleShortcutHolder *shortcutHolder = _registeredShortcutsByName[shortcutName];\n  if (!shortcutHolder) {\n    NSLog(@\"Unable to clear shortcut %@ as it does not exists.\", shortcutName);\n    return;\n  }\n  BOOL eventHotKeyUnregistered = NO;\n  if (_areShorcutsEnabled) {\n    eventHotKeyUnregistered = [self unregisterEventHotKey:shortcutHolder];\n  }\n  _registeredShortcutsByName[shortcutName] = [shortcutHolder copyWithClearedShortcut];\n  if (_areShorcutsEnabled && !eventHotKeyUnregistered) {\n    _registeredShortcutsByName[shortcutName] = shortcutHolder;\n  }\n  [self storeShortcuts];\n}\n\n- (NSArray<SpectacleShortcut *> *)shortcuts\n{\n  NSMutableArray<SpectacleShortcut *> *shortcuts = [NSMutableArray new];\n  for (SpectacleShortcutHolder *shortcutHolder in _registeredShortcutsByName.allValues) {\n    [shortcuts addObject:shortcutHolder.shortcut];\n  }\n  return shortcuts;\n}\n\n- (SpectacleShortcut *)shortcutForShortcutName:(NSString *)shortcutName\n{\n  SpectacleShortcutHolder *shortcutHolder = _registeredShortcutsByName[shortcutName];\n  SpectacleShortcut *shortcut = shortcutHolder.shortcut;\n  if (shortcut.isClearedShortcut) {\n    return nil;\n  }\n  return shortcut;\n}\n\n- (BOOL)doesShortcutExist:(SpectacleShortcut *)shortcut\n{\n  for (SpectacleShortcutHolder *shortcutHolder in _registeredShortcutsByName.allValues) {\n    if ([shortcutHolder.shortcut isEqualToShortcut:shortcut]) {\n      return YES;\n    }\n  }\n  return NO;\n}\n\n- (void)registerShortcuts\n{\n  if (_areShorcutsEnabled) {\n    return;\n  }\n  for (SpectacleShortcutHolder *shortcutHolder in _registeredShortcutsByName.allValues) {\n    _registeredShortcutsByName[shortcutHolder.shortcut.shortcutName] = [self registerEventHotKey:shortcutHolder];\n  }\n  _areShorcutsEnabled = YES;\n}\n\n- (void)unregisterShortcuts\n{\n  if (!_areShorcutsEnabled) {\n    return;\n  }\n  for (SpectacleShortcutHolder *shortcutHolder in _registeredShortcutsByName.allValues) {\n    [self unregisterEventHotKey:shortcutHolder];\n  }\n  _areShorcutsEnabled = NO;\n}\n\n- (void)installApplicationEventHandler\n{\n  EventTypeSpec typeSpec;\n  typeSpec.eventClass = kEventClassKeyboard;\n  typeSpec.eventKind = kEventHotKeyPressed;\n  InstallApplicationEventHandler(&hotKeyEventHandler, 1, &typeSpec, (__bridge void*)self, NULL);\n}\n\n- (void)storeShortcuts\n{\n  [_shortcutStorage storeShortcuts:self.shortcuts];\n}\n\n- (SpectacleShortcut *)shortcutForShortcutID:(EventHotKeyID)shortcutID\n{\n  for (SpectacleShortcutHolder *shortcut in _registeredShortcutsByName.allValues) {\n    if (shortcut.shortcutID.id == shortcutID.id) {\n      return shortcut.shortcut;\n    }\n  }\n  return nil;\n}\n\n- (SpectacleShortcutHolder *)registerEventHotKey:(SpectacleShortcutHolder *)shortcutHolder\n{\n  SpectacleShortcut *shortcut = shortcutHolder.shortcut;\n  if (shortcut.isClearedShortcut) {\n    return shortcutHolder;\n  }\n  EventHotKeyRef shortcutRef;\n  OSStatus err;\n  err = RegisterEventHotKey((unsigned int)shortcut.shortcutKeyCode,\n                            (unsigned int)shortcut.shortcutModifiers,\n                            shortcutHolder.shortcutID,\n                            GetEventDispatcherTarget(),\n                            kEventHotKeyNoOptions,\n                            &shortcutRef);\n  if (err) {\n    NSLog(@\"There was a problem registering shortcut %@.\", shortcut.shortcutName);\n    return [shortcutHolder copyWithClearedShortcut];\n  }\n  return [shortcutHolder copyWithShortcutRef:shortcutRef];\n}\n\n- (BOOL)unregisterEventHotKey:(SpectacleShortcutHolder *)shortcutHolder\n{\n  NSString *shortcutName = shortcutHolder.shortcut.shortcutName;\n  EventHotKeyRef shortcutRef = shortcutHolder.shortcutRef;\n  OSStatus err;\n  if (shortcutRef) {\n    err = UnregisterEventHotKey(shortcutRef);\n    if (err) {\n      NSLog(@\"Received the following error code when unregistering shortcut %@: %d\", shortcutName, err);\n      return NO;\n    }\n  }\n  return YES;\n}\n\n- (OSStatus)handleHotKeyEvent:(EventRef)event\n{\n  SpectacleShortcut *shortcut;\n  EventHotKeyID shortcutID;\n  OSStatus err = GetEventParameter(event,\n                                   kEventParamDirectObject,\n                                   typeEventHotKeyID,\n                                   NULL,\n                                   sizeof(EventHotKeyID),\n                                   NULL,\n                                   &shortcutID);\n  if (err) {\n    return err;\n  }\n  shortcut = [self shortcutForShortcutID:shortcutID];\n  if (!shortcut) {\n    NSLog(@\"Unable to handle event for shortcut with handle %d, the registered shortcut does not exist.\", shortcutID.id);\n  }\n  switch (GetEventKind(event)) {\n    case kEventHotKeyPressed:\n      [shortcut triggerShortcutAction];\n      break;\n    default:\n      break;\n  }\n  return noErr;\n}\n\nOSStatus hotKeyEventHandler(EventHandlerCallRef handlerCall, EventRef event, void *shortcutManager)\n{\n  return [(__bridge SpectacleShortcutManager *)shortcutManager handleHotKeyEvent:event];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutRecorder.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n@class SpectacleShortcut;\n@class SpectacleShortcutValidation;\n\n@protocol SpectacleShortcutRecorderDelegate;\n\n@interface SpectacleShortcutRecorder : NSView\n\n@property (nonatomic, copy) NSString *shortcutName;\n@property (nonatomic, strong) SpectacleShortcut *shortcut;\n@property (nonatomic, strong) SpectacleShortcutValidation *shortcutValidation;\n@property (nonatomic, weak) id<SpectacleShortcutRecorderDelegate> delegate;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutRecorder.m",
    "content": "#import \"SpectacleShortcutRecorder.h\"\n\n#import <Carbon/Carbon.h>\n\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutRecorder.h\"\n#import \"SpectacleShortcutRecorderDelegate.h\"\n#import \"SpectacleShortcutTranslations.h\"\n#import \"SpectacleShortcutValidation.h\"\n\nstatic const NSTrackingAreaOptions kTrackingAreaOptions = (NSTrackingMouseEnteredAndExited\n                                                           | NSTrackingActiveWhenFirstResponder\n                                                           | NSTrackingEnabledDuringMouseDrag);\n\nstatic const NSEventModifierFlags kCocoaModifierFlagsMask = (NSControlKeyMask\n                                                             | NSAlternateKeyMask\n                                                             | NSShiftKeyMask\n                                                             | NSCommandKeyMask);\n\n@implementation SpectacleShortcutRecorder\n{\n  BOOL _isRecording;\n  BOOL _isMouseDown;\n  BOOL _isMouseAboveBadge;\n  NSTrackingArea *_badgeButtonTrackingArea;\n  void *_shortcutMode;\n}\n\n- (instancetype)initWithFrame:(NSRect)frame\n{\n  if (self = [super initWithFrame:frame]) {\n    [self _updateTrackingArea];\n  }\n  return self;\n}\n\n- (void)setShortcut:(SpectacleShortcut *)shortcut\n{\n  _shortcut = shortcut;\n  [self _updateTrackingArea];\n  [self setNeedsDisplay:YES];\n}\n\n- (BOOL)acceptsFirstResponder\n{\n  return YES;\n}\n\n- (BOOL)resignFirstResponder\n{\n  [self _stopRecording];\n  return YES;\n}\n\n- (BOOL)acceptsFirstMouse:(NSEvent *)event\n{\n  return YES;\n}\n\n- (void)mouseDown:(NSEvent *)event\n{\n  _isMouseDown = YES;\n  [self setNeedsDisplay:YES];\n}\n\n- (void)mouseUp:(NSEvent *)event\n{\n  NSPoint locationInView = [self convertPoint:event.locationInWindow fromView:nil];\n  if (_badgeButtonTrackingArea && [self mouse:locationInView inRect:badgeRectInBounds(self.bounds)]) {\n    if (_isRecording) {\n      [self _stopRecording];\n    } else {\n      [self _clearShortcut];\n    }\n  } else if ([self mouse:locationInView inRect:self.bounds]) {\n    [self _startRecording];\n  } else {\n    [self setNeedsDisplay:YES];\n  }\n  _isMouseDown = NO;\n}\n\n- (void)mouseEntered:(NSEvent *)event\n{\n  _isMouseAboveBadge = event.trackingArea == _badgeButtonTrackingArea;\n  [self setNeedsDisplay:YES];\n}\n\n- (void)mouseExited:(NSEvent *)event\n{\n  _isMouseAboveBadge = event.trackingArea != _badgeButtonTrackingArea;\n  [self setNeedsDisplay:YES];\n}\n\n- (void)keyDown:(NSEvent *)event\n{\n  if (![self performKeyEquivalent:event]) {\n    [super keyDown:event];\n  }\n}\n\n- (BOOL)performKeyEquivalent:(NSEvent *)event\n{\n  if (self.window.firstResponder != self) {\n    return NO;\n  }\n  NSEventModifierFlags modifierFlags = event.modifierFlags & kCocoaModifierFlagsMask;\n  if (event.keyCode == kVK_Escape && modifierFlags == 0) {\n    [self _stopRecording];\n    return YES;\n  }\n  NSInteger keyCode = event.keyCode;\n  BOOL functionKey = ((keyCode == kVK_F1)  || (keyCode == kVK_F2)  || (keyCode == kVK_F3)  || (keyCode == kVK_F4)  ||\n                      (keyCode == kVK_F5)  || (keyCode == kVK_F6)  || (keyCode == kVK_F7)  || (keyCode == kVK_F8)  ||\n                      (keyCode == kVK_F9)  || (keyCode == kVK_F10) || (keyCode == kVK_F11) || (keyCode == kVK_F12) ||\n                      (keyCode == kVK_F13) || (keyCode == kVK_F14) || (keyCode == kVK_F15) || (keyCode == kVK_F16) ||\n                      (keyCode == kVK_F17) || (keyCode == kVK_F18) || (keyCode == kVK_F19) || (keyCode == kVK_F20));\n  if (_isRecording && (functionKey || [SpectacleShortcut validCocoaModifiers:modifierFlags])) {\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:_shortcutName\n                                                                  shortcutKeyCode:keyCode\n                                                                shortcutModifiers:modifierFlags];\n    NSError *error = nil;\n    if ([_shortcutValidation isShortcutValid:shortcut error:&error]) {\n      _shortcut = shortcut;\n      [_delegate shortcutRecorder:self didReceiveNewShortcut:shortcut];\n    } else {\n      [[NSAlert alertWithError:error] runModal];\n    }\n    [self _stopRecording];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)flagsChanged:(NSEvent *)event\n{\n  if (!_isRecording) {\n    return;\n  }\n  [self setNeedsDisplay:YES];\n}\n\n- (void)drawRect:(NSRect)rect\n{\n  CGFloat radius = NSHeight(rect) / 2.0f;\n  [self _drawBorderInRect:rect withRadius:radius];\n  [self _drawBackgroundInRect:rect withRadius:radius];\n  [self _drawBadgeInRect:rect];\n  [self _drawLabelInRect:rect];\n}\n\n- (void)_startRecording\n{\n  _isRecording = YES;\n  _shortcutMode = PushSymbolicHotKeyMode(kHIHotKeyModeAllDisabled);\n  [self _updateTrackingArea];\n  [self setNeedsDisplay:YES];\n}\n\n- (void)_stopRecording\n{\n  if (!_isRecording) {\n    return;\n  }\n  PopSymbolicHotKeyMode(_shortcutMode);\n  _isRecording = NO;\n  _isMouseAboveBadge = NO;\n  [self _updateTrackingArea];\n  [self setNeedsDisplay:YES];\n}\n\n- (void)_clearShortcut\n{\n  [_delegate shortcutRecorder:self didClearExistingShortcut:_shortcut];\n  _shortcut = nil;\n  _isMouseAboveBadge = NO;\n  [self _updateTrackingArea];\n  [self setNeedsDisplay:YES];\n}\n\n- (void)_updateTrackingArea\n{\n  if (_badgeButtonTrackingArea) {\n    [self removeTrackingArea: _badgeButtonTrackingArea];\n    _badgeButtonTrackingArea = nil;\n  }\n  if (_isRecording || _shortcut) {\n    _badgeButtonTrackingArea = [[NSTrackingArea alloc] initWithRect:badgeRectInBounds(self.bounds)\n                                                            options:kTrackingAreaOptions\n                                                              owner:self\n                                                           userInfo:nil];\n    [self addTrackingArea:_badgeButtonTrackingArea];\n  }\n}\n\n- (void)_drawBorderInRect:(NSRect)rect withRadius:(CGFloat)radius\n{\n  NSBezierPath *roundedPath = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius];\n  [NSGraphicsContext.currentContext saveGraphicsState];\n  [roundedPath addClip];\n  [[NSColor windowFrameColor] set];\n  [NSBezierPath fillRect:rect];\n  [NSGraphicsContext.currentContext restoreGraphicsState];\n}\n\n- (void)_drawBackgroundInRect:(NSRect)rect withRadius:(CGFloat)radius\n{\n  NSBezierPath *roundedPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(rect, 1.0f, 1.0f)\n                                                              xRadius:radius\n                                                              yRadius:radius];\n  NSColor *gradientStartingColor = nil;\n  NSColor *gradientEndingColor = nil;\n  NSGradient *gradient = nil;\n  [NSGraphicsContext.currentContext saveGraphicsState];\n  [roundedPath addClip];\n  if (_isRecording) {\n    gradientStartingColor = [NSColor colorWithDeviceRed:0.784f green:0.953f blue:1.0f alpha:1.0f];\n    gradientEndingColor = [NSColor colorWithDeviceRed:0.694f green:0.859f blue:1.0f alpha:1.0f];\n  } else {\n    gradientStartingColor = [[[NSColor whiteColor] shadowWithLevel:0.2f] colorWithAlphaComponent:0.9f];\n    gradientEndingColor = [[[NSColor whiteColor] highlightWithLevel:0.2f] colorWithAlphaComponent:0.9f];\n  }\n  if (!_isRecording && _isMouseDown && !_isMouseAboveBadge) {\n    gradient = [[NSGradient alloc] initWithStartingColor:gradientEndingColor endingColor:gradientStartingColor];\n  } else {\n    gradient = [[NSGradient alloc] initWithStartingColor:gradientStartingColor endingColor:gradientEndingColor];\n  }\n  [gradient drawInRect:rect angle:90.0f];\n  [NSGraphicsContext.currentContext restoreGraphicsState];\n}\n\n- (void)_drawBadgeInRect:(NSRect)rect\n{\n  NSRect badgeRect = badgeRectInBounds(rect);\n  if ((_isRecording && !_shortcut) || (!_isRecording && _shortcut)) {\n    [self _drawCancelOrClearShortcutBadgeInRect:badgeRect opacity:(_isMouseAboveBadge && _isMouseDown) ? 0.50 : 0.25f];\n  } else if (_isRecording) {\n    [self _drawRevertShortcutBadgeInRect:badgeRect];\n  }\n}\n\n- (void)_drawCancelOrClearShortcutBadgeInRect:(NSRect)rect opacity:(CGFloat)opacity\n{\n  CGFloat horizontalScale = (rect.size.width / 13.0f);\n  CGFloat verticalScale = (rect.size.height / 13.0f);\n  [NSGraphicsContext.currentContext saveGraphicsState];\n  [[NSColor colorWithCalibratedWhite:0.0f alpha:opacity] setFill];\n  [[NSBezierPath bezierPathWithOvalInRect:rect] fill];\n  [[NSColor whiteColor] setStroke];\n  NSBezierPath *cross = [NSBezierPath new];\n  [cross setLineWidth:horizontalScale * 1.4f];\n  [cross moveToPoint:relativePointInRect(4.0f, 4.0f, rect, horizontalScale, verticalScale)];\n  [cross lineToPoint:relativePointInRect(9.0f, 9.0f, rect, horizontalScale, verticalScale)];\n  [cross moveToPoint:relativePointInRect(9.0f, 4.0f, rect, horizontalScale, verticalScale)];\n  [cross lineToPoint:relativePointInRect(4.0f, 9.0f, rect, horizontalScale, verticalScale)];\n  [cross stroke];\n  [NSGraphicsContext.currentContext restoreGraphicsState];\n}\n\n- (void)_drawRevertShortcutBadgeInRect:(NSRect)rect\n{\n  CGFloat horizontalScale = (rect.size.width / 1.0f);\n  CGFloat verticalScale = (rect.size.height / 1.0f);\n  [NSGraphicsContext.currentContext saveGraphicsState];\n  NSBezierPath *swoosh = [NSBezierPath new];\n  [swoosh setLineWidth:horizontalScale];\n  [swoosh moveToPoint:relativePointInRect(0.0489685f, 0.6181513f, rect, horizontalScale, verticalScale)];\n  [swoosh lineToPoint:relativePointInRect(0.4085750f, 0.9469318f, rect, horizontalScale, verticalScale)];\n  [swoosh lineToPoint:relativePointInRect(0.4085750f, 0.7226146f, rect, horizontalScale, verticalScale)];\n  [swoosh curveToPoint:relativePointInRect(0.8508247f, 0.4836237f, rect, horizontalScale, verticalScale)\n         controlPoint1:relativePointInRect(0.4085750f, 0.7226146f, rect, horizontalScale, verticalScale)\n         controlPoint2:relativePointInRect(0.8371143f, 0.7491841f, rect, horizontalScale, verticalScale)];\n  [swoosh curveToPoint:relativePointInRect(0.5507195f, 0.0530682f, rect, horizontalScale, verticalScale)\n         controlPoint1:relativePointInRect(0.8677834f, 0.1545071f, rect, horizontalScale, verticalScale)\n         controlPoint2:relativePointInRect(0.5507195f, 0.0530682f, rect, horizontalScale, verticalScale)];\n  [swoosh curveToPoint:relativePointInRect(0.7421721f, 0.3391942f, rect, horizontalScale, verticalScale)\n         controlPoint1:relativePointInRect(0.5507195f, 0.0530682f, rect, horizontalScale, verticalScale)\n         controlPoint2:relativePointInRect(0.7458685f, 0.1913146f, rect, horizontalScale, verticalScale)];\n  [swoosh curveToPoint:relativePointInRect(0.4085750f, 0.5154130f, rect, horizontalScale, verticalScale)\n         controlPoint1:relativePointInRect(0.7383412f, 0.4930328f, rect, horizontalScale, verticalScale)\n         controlPoint2:relativePointInRect(0.4085750f, 0.5154130f, rect, horizontalScale, verticalScale)];\n  [swoosh lineToPoint:relativePointInRect(0.4085750f, 0.2654000f, rect, horizontalScale, verticalScale)];\n  [swoosh fill];\n  [NSGraphicsContext.currentContext restoreGraphicsState];\n}\n\n- (void)_drawLabelInRect:(NSRect)rect\n{\n  NSString *label = nil;\n  if (_isRecording && !_isMouseAboveBadge) {\n    label = NSLocalizedString(@\"ShortcutRecorderLabelEnterShortcut\", @\"The shortcut recorder label displayed when the shorcut recorder is recording a shortcut\");\n  } else if (_isRecording && _isMouseAboveBadge && !_shortcut) {\n    label = NSLocalizedString(@\"ShortcutRecorderLabelStopRecording\", @\"The shortcut recorder label displayed when the shorcut recorder is recording a shortcut and the shortcut recorder does not have a previously recorded shortcut\");\n  } else if (_isRecording && _isMouseAboveBadge) {\n    label = NSLocalizedString(@\"ShortcutRecorderLabelUseExisting\", \"The shortcut recorder label displayed when the shorcut recorder is recording a shortcut and the shortcut recorder does have a previously recorded shortcut\");\n  } else if (_shortcut) {\n    label = _shortcut.displayString;\n  } else {\n    label = NSLocalizedString(@\"ShortcutRecorderLabelClickToRecord\", @\"The shortcut recorder label displayed when the shorcut recorder is cleared and ready to record a new shortcut\");\n  }\n  NSEventModifierFlags modifierFlags = [NSEvent modifierFlags] & kCocoaModifierFlagsMask;\n  if (_isRecording && modifierFlags) {\n    label = SpectacleTranslateModifiers(modifierFlags);\n  }\n  [self _drawString:label inRect:rect];\n}\n\n- (void)_drawString:(NSString *)string inRect:(NSRect)rect\n{\n  NSMutableDictionary<NSString *, id> *attributes = stringAttributesWithShadow();\n  NSRect labelRect = rect;\n  attributes[NSFontAttributeName] = [NSFont systemFontOfSize:NSFont.smallSystemFontSize];\n  attributes[NSForegroundColorAttributeName] = [NSColor blackColor];\n  labelRect.origin.y = -(NSMidY(rect) - [string sizeWithAttributes:attributes].height / 2.0f);\n  [string drawInRect:labelRect withAttributes:attributes];\n}\n\nstatic NSRect badgeRectInBounds(NSRect bounds)\n{\n  NSRect badgeRect;\n  NSSize badgeSize;\n  badgeSize.width = 13.0f;\n  badgeSize.height = 13.0f;\n  badgeRect.origin = NSMakePoint(NSMaxX(bounds) - badgeSize.width - 4.0f, floor((NSMaxY(bounds) - badgeSize.height) / 2.0f));\n  badgeRect.size = badgeSize;\n  return badgeRect;\n}\n\nstatic NSMutableDictionary<NSString *, id> *stringAttributesWithShadow(void)\n{\n  NSMutableParagraphStyle *paragraphStyle = NSParagraphStyle.defaultParagraphStyle.mutableCopy;\n  NSShadow *textShadow = [NSShadow new];\n  NSMutableDictionary<NSString *, id> *stringAttributes = [NSMutableDictionary new];\n  paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;\n  paragraphStyle.alignment = NSCenterTextAlignment;\n  textShadow.shadowColor = [NSColor whiteColor];\n  textShadow.shadowOffset = NSMakeSize(0.0f, -1.0);\n  textShadow.shadowBlurRadius = 0.0f;\n  stringAttributes[NSParagraphStyleAttributeName] = paragraphStyle;\n  stringAttributes[NSShadowAttributeName] = textShadow;\n  return stringAttributes;\n}\n\nstatic NSPoint relativePointInRect(CGFloat x, CGFloat y, CGRect rect, CGFloat horizontalScale, CGFloat verticalScale)\n{\n  return NSMakePoint((x * horizontalScale) + rect.origin.x, (y * verticalScale) + rect.origin.y);\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutRecorderDelegate.h",
    "content": "#import <Foundation/Foundation.h>\n\n@class SpectacleShortcut;\n@class SpectacleShortcutRecorder;\n\n@protocol SpectacleShortcutRecorderDelegate <NSObject>\n\n- (void)shortcutRecorder:(SpectacleShortcutRecorder *)shortcutRecorder\n   didReceiveNewShortcut:(SpectacleShortcut *)shortcut;\n\n- (void)shortcutRecorder:(SpectacleShortcutRecorder *)shortcutRecorder\ndidClearExistingShortcut:(SpectacleShortcut *)shortcut;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutStorage.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcut.h\"\n\n@protocol SpectacleShortcutStorage <NSObject>\n\n- (NSArray<SpectacleShortcut *> *)loadShortcutsWithAction:(SpectacleShortcutAction)action;\n\n- (void)storeShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutStorageMigrationDestination.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcutStorage.h\"\n\n@protocol SpectacleShortcutStorageMigrationDestination <SpectacleShortcutStorage>\n\n@property (nonatomic, readonly, assign, getter=isMigrationNeeded) BOOL migrationNeeded;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutTranslations.h",
    "content": "#import <Foundation/Foundation.h>\n\n@class SpectacleShortcut;\n\nNSString *SpectacleTranslateKeyCode(NSInteger keyCode);\nNSString *SpectacleTranslateModifiers(NSUInteger modifiers);\nNSString *SpectacleTranslateShortcut(SpectacleShortcut *shortcut);\n\nNSUInteger SpectacleConvertCocoaModifiersToCarbon(NSUInteger modifiers);\nNSUInteger SpectacleConvertCarbonModifiersToCocoa(NSUInteger modifiers);\nNSUInteger SpectacleConvertModifiersToCarbonIfNecessary(NSUInteger modifiers);\nNSUInteger SpectacleConvertModifiersToCocoaIfNecessary(NSUInteger modifiers);\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutTranslations.m",
    "content": "#import \"SpectacleShortcutTranslations.h\"\n\n#import <Carbon/Carbon.h>\n#import <Cocoa/Cocoa.h>\n\n#import \"SpectacleShortcut.h\"\n\ntypedef NS_ENUM(unichar, SpectacleUnicodeGlyph)\n{\n  SpectacleUnicodeGlyphCapsLock       = 0x21EA, // ⇪\n  SpectacleUnicodeGlyphClear          = 0x2327, // ⌧\n  SpectacleUnicodeGlyphCommand        = 0x2318, // ⌘\n  SpectacleUnicodeGlyphControl        = 0x2303, // ⌃\n  SpectacleUnicodeGlyphDelete         = 0x232B, // ⌫\n  SpectacleUnicodeGlyphDownArrow      = 0x2193, // ↓\n  SpectacleUnicodeGlyphEnd            = 0x2198, // ↘\n  SpectacleUnicodeGlyphEnter          = 0x2324, // ⌤\n  SpectacleUnicodeGlyphEscape         = 0x238B, // ⎋\n  SpectacleUnicodeGlyphForwardDelete  = 0x2326, // ⌦\n  SpectacleUnicodeGlyphHome           = 0x2196, // ↖\n  SpectacleUnicodeGlyphLeftArrow      = 0x2190, // ←\n  SpectacleUnicodeGlyphOption         = 0x2325, // ⌥\n  SpectacleUnicodeGlyphPageDown       = 0x21DF, // ⇟\n  SpectacleUnicodeGlyphPageUp         = 0x21DE, // ⇞\n  SpectacleUnicodeGlyphReturn         = 0x21A9, // ↩\n  SpectacleUnicodeGlyphRightArrow     = 0x2192, // →\n  SpectacleUnicodeGlyphShift          = 0x21E7, // ⇧\n  SpectacleUnicodeGlyphSpace          = 0x2423, // ␣\n  SpectacleUnicodeGlyphTab            = 0x21E5, // ⇥\n  SpectacleUnicodeGlyphUpArrow        = 0x2191, // ↑\n};\n\nstatic NSDictionary<NSNumber *, NSString *> *layoutIndependentKeyCodeTranslations(void);\nstatic NSString *glyphForUnicodeChar(unichar unicodeChar);\n\nNSString *SpectacleTranslateKeyCode(NSInteger keyCode)\n{\n  NSString *translatedLayoutIndependentKeyCode = layoutIndependentKeyCodeTranslations()[@(keyCode)];\n  if (translatedLayoutIndependentKeyCode) {\n    return translatedLayoutIndependentKeyCode;\n  }\n  TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource();\n  if (!inputSource) {\n    return @\"?\";\n  }\n  CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData);\n  CFRelease(inputSource);\n  if (!layoutData) {\n    inputSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();\n    if (!inputSource) {\n      return @\"?\";\n    }\n    layoutData = (CFDataRef)TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData);\n    CFRelease(inputSource);\n    if (!layoutData) {\n      return @\"?\";\n    }\n  }\n  const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);\n  UInt32 deadKeyState = 0;\n  UniCharCount maximumStringLength = 4;\n  UniCharCount actualStringLength = 0;\n  UniChar unicodeString[maximumStringLength];\n  OSStatus err = UCKeyTranslate(keyboardLayout,\n                                keyCode,\n                                kUCKeyActionDisplay,\n                                0,\n                                LMGetKbdType(),\n                                kUCKeyTranslateNoDeadKeysBit,\n                                &deadKeyState,\n                                maximumStringLength,\n                                &actualStringLength,\n                                unicodeString);\n  if (err != noErr) {\n    return @\"?\";\n  }\n  return [[NSString stringWithCharacters:unicodeString length:actualStringLength] uppercaseString];\n}\n\nNSString *SpectacleTranslateModifiers(NSUInteger modifiers)\n{\n  NSString *modifierGlyphs = @\"\";\n  modifiers = SpectacleConvertModifiersToCocoaIfNecessary(modifiers);\n  if (modifiers & NSControlKeyMask) {\n    modifierGlyphs = [modifierGlyphs stringByAppendingFormat:@\"%C\", (UInt16)kControlUnicode];\n  }\n  if (modifiers & NSAlternateKeyMask) {\n    modifierGlyphs = [modifierGlyphs stringByAppendingFormat:@\"%C\", (UInt16)kOptionUnicode];\n  }\n  if (modifiers & NSShiftKeyMask) {\n    modifierGlyphs = [modifierGlyphs stringByAppendingFormat:@\"%C\", (UInt16)kShiftUnicode];\n  }\n  if (modifiers & NSCommandKeyMask) {\n    modifierGlyphs = [modifierGlyphs stringByAppendingFormat:@\"%C\", (UInt16)kCommandUnicode];\n  }\n  return modifierGlyphs;\n}\n\nNSString *SpectacleTranslateShortcut(SpectacleShortcut *shortcut)\n{\n  return [NSString stringWithFormat:@\"%@%@\",\n          SpectacleTranslateModifiers(shortcut.shortcutModifiers),\n          SpectacleTranslateKeyCode(shortcut.shortcutKeyCode)];\n}\n\nNSUInteger SpectacleConvertCocoaModifiersToCarbon(NSUInteger modifiers)\n{\n  NSUInteger convertedModifiers = 0;\n  if (modifiers & NSControlKeyMask) {\n    convertedModifiers |= controlKey;\n  }\n  if (modifiers & NSAlternateKeyMask) {\n    convertedModifiers |= optionKey;\n  }\n  if (modifiers & NSShiftKeyMask) {\n    convertedModifiers |= shiftKey;\n  }\n  if (modifiers & NSCommandKeyMask) {\n    convertedModifiers |= cmdKey;\n  }\n  return convertedModifiers;\n}\n\nNSUInteger SpectacleConvertCarbonModifiersToCocoa(NSUInteger modifiers)\n{\n  NSUInteger convertedModifiers = 0;\n  if (modifiers & controlKey) {\n    convertedModifiers |= NSControlKeyMask;\n  }\n  if (modifiers & optionKey) {\n    convertedModifiers |= NSAlternateKeyMask;\n  }\n  if (modifiers & shiftKey) {\n    convertedModifiers |= NSShiftKeyMask;\n  }\n  if (modifiers & cmdKey) {\n    convertedModifiers |= NSCommandKeyMask;\n  }\n  return convertedModifiers;\n}\n\nNSUInteger SpectacleConvertModifiersToCarbonIfNecessary(NSUInteger modifiers)\n{\n  if ([SpectacleShortcut validCocoaModifiers:modifiers]) {\n    modifiers = SpectacleConvertCocoaModifiersToCarbon(modifiers);\n  }\n  return modifiers;\n}\n\nNSUInteger SpectacleConvertModifiersToCocoaIfNecessary(NSUInteger modifiers)\n{\n  if (![SpectacleShortcut validCocoaModifiers:modifiers]) {\n    modifiers = SpectacleConvertCarbonModifiersToCocoa(modifiers);\n  }\n  return modifiers;\n}\n\nstatic NSDictionary<NSNumber *, NSString *> *layoutIndependentKeyCodeTranslations(void)\n{\n  static dispatch_once_t onceToken;\n  static NSDictionary<NSNumber *, NSString *> *translations;\n  dispatch_once(&onceToken, ^{\n    translations = @{\n                     @(kVK_F1):                  @\"F1\",\n                     @(kVK_F2):                  @\"F2\",\n                     @(kVK_F3):                  @\"F3\",\n                     @(kVK_F4):                  @\"F4\",\n                     @(kVK_F5):                  @\"F5\",\n                     @(kVK_F6):                  @\"F6\",\n                     @(kVK_F7):                  @\"F7\",\n                     @(kVK_F8):                  @\"F8\",\n                     @(kVK_F9):                  @\"F9\",\n                     @(kVK_F10):                 @\"F10\",\n                     @(kVK_F11):                 @\"F11\",\n                     @(kVK_F12):                 @\"F12\",\n                     @(kVK_F13):                 @\"F13\",\n                     @(kVK_F14):                 @\"F14\",\n                     @(kVK_F15):                 @\"F15\",\n                     @(kVK_F16):                 @\"F16\",\n                     @(kVK_F17):                 @\"F17\",\n                     @(kVK_F18):                 @\"F18\",\n                     @(kVK_F19):                 @\"F19\",\n                     @(kVK_F20):                 @\"F20\",\n\n                     @(kVK_ANSI_KeypadDecimal):  @\".\",\n                     @(kVK_ANSI_KeypadMultiply): @\"*\",\n                     @(kVK_ANSI_KeypadPlus):     @\"+\",\n                     @(kVK_ANSI_KeypadClear):    glyphForUnicodeChar(SpectacleUnicodeGlyphClear),\n                     @(kVK_ANSI_KeypadDivide):   @\"/\",\n                     @(kVK_ANSI_KeypadEnter):    glyphForUnicodeChar(SpectacleUnicodeGlyphEnter),\n                     @(kVK_ANSI_KeypadMinus):    @\"-\",\n                     @(kVK_ANSI_KeypadEquals):   @\"=\",\n                     @(kVK_ANSI_Keypad0):        @\"0\",\n                     @(kVK_ANSI_Keypad1):        @\"1\",\n                     @(kVK_ANSI_Keypad2):        @\"2\",\n                     @(kVK_ANSI_Keypad3):        @\"3\",\n                     @(kVK_ANSI_Keypad4):        @\"4\",\n                     @(kVK_ANSI_Keypad5):        @\"5\",\n                     @(kVK_ANSI_Keypad6):        @\"6\",\n                     @(kVK_ANSI_Keypad7):        @\"7\",\n                     @(kVK_ANSI_Keypad8):        @\"8\",\n                     @(kVK_ANSI_Keypad9):        @\"9\",\n\n                     @(kVK_Return):              glyphForUnicodeChar(SpectacleUnicodeGlyphReturn),\n                     @(kVK_Tab):                 glyphForUnicodeChar(SpectacleUnicodeGlyphTab),\n                     @(kVK_Space):               glyphForUnicodeChar(SpectacleUnicodeGlyphSpace),\n                     @(kVK_Delete):              glyphForUnicodeChar(SpectacleUnicodeGlyphDelete),\n                     @(kVK_Escape):              glyphForUnicodeChar(SpectacleUnicodeGlyphEscape),\n                     @(kVK_Command):             glyphForUnicodeChar(SpectacleUnicodeGlyphCommand),\n                     @(kVK_Shift):               glyphForUnicodeChar(SpectacleUnicodeGlyphShift),\n                     @(kVK_CapsLock):            glyphForUnicodeChar(SpectacleUnicodeGlyphCapsLock),\n                     @(kVK_Option):              glyphForUnicodeChar(SpectacleUnicodeGlyphOption),\n                     @(kVK_Control):             glyphForUnicodeChar(SpectacleUnicodeGlyphControl),\n                     @(kVK_RightShift):          @\"\",\n                     @(kVK_RightOption):         @\"\",\n                     @(kVK_RightControl):        @\"\",\n                     @(kVK_Function):            @\"\",\n                     @(kVK_VolumeUp):            @\"\",\n                     @(kVK_VolumeDown):          @\"\",\n                     @(kVK_Mute):                @\"\",\n                     @(kVK_Help):                @\"\",\n                     @(kVK_Home):                glyphForUnicodeChar(SpectacleUnicodeGlyphHome),\n                     @(kVK_PageUp):              glyphForUnicodeChar(SpectacleUnicodeGlyphPageUp),\n                     @(kVK_ForwardDelete):       glyphForUnicodeChar(SpectacleUnicodeGlyphForwardDelete),\n                     @(kVK_End):                 glyphForUnicodeChar(SpectacleUnicodeGlyphEnd),\n                     @(kVK_PageDown):            glyphForUnicodeChar(SpectacleUnicodeGlyphPageDown),\n                     @(kVK_LeftArrow):           glyphForUnicodeChar(SpectacleUnicodeGlyphLeftArrow),\n                     @(kVK_RightArrow):          glyphForUnicodeChar(SpectacleUnicodeGlyphRightArrow),\n                     @(kVK_DownArrow):           glyphForUnicodeChar(SpectacleUnicodeGlyphDownArrow),\n                     @(kVK_UpArrow):             glyphForUnicodeChar(SpectacleUnicodeGlyphUpArrow),\n                     };\n  });\n  return translations;\n}\n\nstatic NSString *glyphForUnicodeChar(unichar unicodeChar)\n{\n  return [NSString stringWithFormat: @\"%C\", unicodeChar];\n}\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutUserDefaultsStorage.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleShortcutStorage.h\"\n\n@interface SpectacleShortcutUserDefaultsStorage : NSObject <SpectacleShortcutStorage>\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutUserDefaultsStorage.m",
    "content": "#import \"SpectacleShortcutUserDefaultsStorage.h\"\n\n@implementation SpectacleShortcutUserDefaultsStorage\n\n+ (void)initialize\n{\n  [NSKeyedUnarchiver setClass:[SpectacleShortcut class] forClassName:@\"SpectacleHotKey\"];\n  [NSKeyedUnarchiver setClass:[SpectacleShortcut class] forClassName:@\"ZeroKitHotKey\"];\n  [NSKeyedUnarchiver setClass:[SpectacleShortcut class] forClassName:@\"ZKHotKey\"];\n}\n\n- (NSArray<SpectacleShortcut *> *)loadShortcutsWithAction:(SpectacleShortcutAction)action\n{\n  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n  NSMutableDictionary<NSString *, NSData *> *shortcutsFromUserDefaults = [NSMutableDictionary new];\n  for (NSString *shortcutName in [self shortcutNames]) {\n    shortcutsFromUserDefaults[shortcutName] = [userDefaults dataForKey:shortcutName];\n  }\n  return [self shortcutsFromDictionary:shortcutsFromUserDefaults action:action];\n}\n\n- (void)storeShortcuts:(NSArray<SpectacleShortcut *> *)shortcuts\n{\n  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n  for (SpectacleShortcut *shortcut in shortcuts) {\n    NSData *shortcutData = [NSKeyedArchiver archivedDataWithRootObject:shortcut];\n    NSString *shortcutName = shortcut.shortcutName;\n    if (![shortcutData isEqualToData:[userDefaults dataForKey:shortcutName]]) {\n      [userDefaults setObject:shortcutData forKey:shortcutName];\n    }\n  }\n}\n\n- (BOOL)isMigrationNeeded\n{\n  return NO;\n}\n\n- (NSArray<NSString *> *)shortcutNames\n{\n  return @[\n           @\"MoveToCenter\",\n           @\"MoveToFullscreen\",\n           @\"MoveToLeftHalf\",\n           @\"MoveToRightHalf\",\n           @\"MoveToTopHalf\",\n           @\"MoveToBottomHalf\",\n           @\"MoveToUpperLeft\",\n           @\"MoveToLowerLeft\",\n           @\"MoveToUpperRight\",\n           @\"MoveToLowerRight\",\n           @\"MoveToNextDisplay\",\n           @\"MoveToPreviousDisplay\",\n           @\"MoveToNextThird\",\n           @\"MoveToPreviousThird\",\n           @\"MakeLarger\",\n           @\"MakeSmaller\",\n           @\"UndoLastMove\",\n           @\"RedoLastMove\",\n           ];\n}\n\n- (NSArray<SpectacleShortcut *> *)shortcutsFromDictionary:(NSDictionary<NSString *, NSData *> *)dictionary\n                                                   action:(SpectacleShortcutAction)action\n{\n  NSMutableArray<SpectacleShortcut *> *shortcuts = [NSMutableArray new];\n  for (NSData *shortcutData in dictionary.allValues) {\n    SpectacleShortcut *shortcut = [NSKeyedUnarchiver unarchiveObjectWithData:shortcutData];\n    [shortcuts addObject:[shortcut copyWithShortcutAction:action]];\n  }\n  return shortcuts;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutValidation.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n\n@class SpectacleShortcut;\n@class SpectacleShortcutManager;\n\n@protocol SpectacleShortcutValidator;\n\n@interface SpectacleShortcutValidation : NSObject\n\n- (instancetype)initWithShortcutManager:(SpectacleShortcutManager *)shortcutManager\n                             validators:(NSArray<id<SpectacleShortcutValidator>> *)validators NS_DESIGNATED_INITIALIZER;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n- (BOOL)isShortcutValid:(SpectacleShortcut *)shortcut error:(NSError **)error;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutValidation.m",
    "content": "#import \"SpectacleShortcutValidation.h\"\n\n#import <Carbon/Carbon.h>\n\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutTranslations.h\"\n#import \"SpectacleShortcutValidator.h\"\n\n@implementation SpectacleShortcutValidation\n{\n  SpectacleShortcutManager *_shortcutManager;\n  NSArray<id<SpectacleShortcutValidator>> *_validators;\n}\n\n- (instancetype)initWithShortcutManager:(SpectacleShortcutManager *)shortcutManager\n                             validators:(NSArray<id<SpectacleShortcutValidator>> *)validators\n{\n  if (self = [super init]) {\n    _shortcutManager = shortcutManager;\n    _validators = validators;\n  }\n  return self;\n}\n\n- (BOOL)isShortcutValid:(SpectacleShortcut *)shortcut error:(NSError **)error\n{\n  CFArrayRef shortcuts = NULL;\n  if (CopySymbolicHotKeys(&shortcuts)) {\n    return YES;\n  }\n  for (CFIndex i = 0; i < CFArrayGetCount(shortcuts); i++) {\n    CFDictionaryRef shortcutDictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(shortcuts, i);\n    if (!shortcutDictionary || (CFGetTypeID(shortcutDictionary) != CFDictionaryGetTypeID())) {\n      continue;\n    }\n    if (kCFBooleanTrue != (CFBooleanRef)CFDictionaryGetValue(shortcutDictionary, kHISymbolicHotKeyEnabled)) {\n      continue;\n    }\n    NSInteger keyCode = keyCodeFromDictionary(shortcutDictionary);\n    NSUInteger modifiers = modifiersFromDictionary(shortcutDictionary);\n    if (([shortcut shortcutKeyCode] == keyCode) && [shortcut containsModifiers:modifiers]) {\n      if (error) {\n        NSString *description = NSLocalizedString(@\"AlertMessageTextShortcutValidationError\", @\"The message text of the alert displayed when a shortcut is invalid\");\n        NSString *recoverySuggestion = NSLocalizedString(@\"AlertInformativeTextSystemWideShortcutAlreadyUsed\", @\"The informative text of the alert displayed when a system-wide shortcut is already in use\");\n        *error = [SpectacleShortcutValidation errorWithShortcut:shortcut\n                                                    description:description\n                                             recoverySuggestion:recoverySuggestion];\n      }\n      return NO;\n    }\n  }\n  for (id<SpectacleShortcutValidator> validator in _validators) {\n    if ([validator conformsToProtocol:@protocol(SpectacleShortcutValidator)]\n        && ![validator isShortcutValid:shortcut shortcutManager:_shortcutManager]) {\n      if (error) {\n        NSString *description = NSLocalizedString(@\"AlertMessageTextShortcutValidationError\", @\"The message text of the alert displayed when a shortcut is invalid\");\n        NSString *recoverySuggestion = NSLocalizedString(@\"AlertInformativeTextShortcutAlreadyInUse\", @\"The informative text of the alert displayed when a shortcut is already in use\");\n        *error = [SpectacleShortcutValidation errorWithShortcut:shortcut\n                                                    description:description\n                                             recoverySuggestion:recoverySuggestion];\n      }\n      return NO;\n    }\n  }\n  return YES;\n}\n\n+ (NSError *)errorWithShortcut:(SpectacleShortcut *)shortcut\n                   description:(NSString *)description\n            recoverySuggestion:(NSString *)recoverySuggestion\n{\n  NSString *shortcutString = SpectacleTranslateShortcut(shortcut);\n  return [NSError errorWithDomain:NSCocoaErrorDomain\n                             code:0\n                         userInfo:@{\n                                    NSLocalizedDescriptionKey: [NSString stringWithFormat:description, shortcutString],\n                                    NSLocalizedRecoverySuggestionErrorKey: [NSString stringWithFormat:recoverySuggestion, shortcutString],\n                                    NSLocalizedRecoveryOptionsErrorKey: @[NSLocalizedString(@\"ButtonLabelAffirmative\", @\"The button label used in the affirmative\")]\n                                    }];\n}\n\nstatic NSInteger keyCodeFromDictionary(CFDictionaryRef dictionary)\n{\n  CFNumberRef keyCodeFromDictionary = (CFNumberRef)CFDictionaryGetValue(dictionary, kHISymbolicHotKeyCode);\n  NSInteger keyCode = 0;\n  CFNumberGetValue(keyCodeFromDictionary, kCFNumberLongType, &keyCode);\n  return keyCode;\n}\n\nstatic NSUInteger modifiersFromDictionary(CFDictionaryRef dictionary)\n{\n  CFNumberRef modifiersFromDictionary = (CFNumberRef)CFDictionaryGetValue(dictionary, kHISymbolicHotKeyModifiers);\n  NSUInteger modifiers = 0;\n  CFNumberGetValue(modifiersFromDictionary, kCFNumberLongType, &modifiers);\n  return modifiers;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleShortcutValidator.h",
    "content": "#import <Foundation/Foundation.h>\n\n@class SpectacleShortcut;\n@class SpectacleShortcutManager;\n\n@protocol SpectacleShortcutValidator <NSObject>\n\n- (BOOL)isShortcutValid:(SpectacleShortcut *)shortcut shortcutManager:(SpectacleShortcutManager *)shortcutManager;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleStandardWindowMover.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleWindowMover.h\"\n\n@interface SpectacleStandardWindowMover : NSObject <SpectacleWindowMover>\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover NS_DESIGNATED_INITIALIZER;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleStandardWindowMover.m",
    "content": "#import \"SpectacleStandardWindowMover.h\"\n\n#import \"SpectacleAccessibilityElement.h\"\n\n@implementation SpectacleStandardWindowMover\n{\n  id<SpectacleWindowMover> _innerWindowMover;\n}\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  if (self = [super init]) {\n    _innerWindowMover = innerWindowMover;\n  }\n  return self;\n}\n\n- (instancetype)init\n{\n  return [self initWithInnerWindowMover:nil];\n}\n\n+ (instancetype)newWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover\n{\n  return [[self alloc] initWithInnerWindowMover:innerWindowMover];\n}\n\n- (void)moveWindowRect:(CGRect)windowRect\n         frameOfScreen:(CGRect)frameOfScreen\n  visibleFrameOfScreen:(CGRect)visibleFrameOfScreen\nfrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                action:(SpectacleWindowAction *)action\n{\n  CGRect previousWindowRect = [frontmostWindowElement rectOfElement];\n  if (CGRectIsNull(previousWindowRect)) {\n    return;\n  }\n  [frontmostWindowElement setRectOfElement:windowRect];\n  [_innerWindowMover moveWindowRect:windowRect\n                      frameOfScreen:frameOfScreen\n               visibleFrameOfScreen:visibleFrameOfScreen\n             frontmostWindowElement:frontmostWindowElement\n                             action:action];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleUtilities.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n@interface SpectacleUtilities : NSObject\n\n+ (NSString *)applicationVersion;\n\n+ (void)registerDefaultsForBundle:(NSBundle *)bundle;\n\n+ (void)displayRunningInBackgroundAlertWithCallback:(void (^)(BOOL, BOOL))callback;\n+ (void)displayRestoreDefaultsAlertWithConfirmationCallback:(void (^)(void))callback;\n\n+ (NSString *)pathForPreferencePaneNamed:(NSString *)preferencePaneName;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleUtilities.m",
    "content": "#import \"SpectacleUtilities.h\"\n\n@implementation SpectacleUtilities\n\n+ (NSString *)applicationVersion\n{\n  NSBundle *mainBundle = NSBundle.mainBundle;\n  NSString *bundleVersion = mainBundle.infoDictionary[@\"CFBundleShortVersionString\"];\n  if (!bundleVersion) {\n    bundleVersion = mainBundle.infoDictionary[@\"CFBundleVersion\"];\n  }\n  return bundleVersion;\n}\n\n+ (void)registerDefaultsForBundle:(NSBundle *)bundle\n{\n  NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;\n  NSString *path = [bundle pathForResource:@\"Defaults\" ofType:@\"plist\"];\n  [defaults registerDefaults:[[NSDictionary alloc] initWithContentsOfFile:path]];\n}\n\n+ (void)displayRunningInBackgroundAlertWithCallback:(void (^)(BOOL, BOOL))callback\n{\n  NSAlert *alert = [NSAlert new];\n  alert.alertStyle = NSInformationalAlertStyle;\n  alert.showsSuppressionButton = YES;\n  alert.messageText = NSLocalizedString(@\"AlertMessageTextRunningInBackground\", @\"The message text of the alert displayed when prompting to run Spectacle in the background\");\n  alert.informativeText = NSLocalizedString(@\"AlertInformativeTextRunningInBackground\", @\"The informative text of the alert displayed when prompting to run Spectacle in the background\");\n  [alert addButtonWithTitle:NSLocalizedString(@\"ButtonLabelAffirmative\", @\"The button label used in the affirmative\")];\n  [alert addButtonWithTitle:NSLocalizedString(@\"ButtonLabelNegative\", @\"The button label used in the negative\")];\n  NSInteger response = [alert runModal];\n  BOOL isAlertSuppressed = [alert.suppressionButton state] == NSOnState;\n  switch (response) {\n    case NSAlertFirstButtonReturn:\n      callback(YES, isAlertSuppressed);\n      break;\n    case NSAlertSecondButtonReturn:\n      callback(NO, isAlertSuppressed);\n      break;\n    default:\n      break;\n  }\n}\n\n+ (void)displayRestoreDefaultsAlertWithConfirmationCallback:(void (^)(void))callback\n{\n  NSAlert *alert = [NSAlert new];\n  alert.messageText = NSLocalizedString(@\"AlertMessageTextRestoreDefaults\", @\"The message text of the alert displayed when prompting to restore Spectacle's default shortcuts\");\n  alert.informativeText = NSLocalizedString(@\"AlertInformativeTextRestoreDefaults\", @\"The informative text of the alert displayed when prompting to restore Spectacle's default shortcuts\");\n  [alert addButtonWithTitle:NSLocalizedString(@\"ButtonLabelAffirmative\", @\"The button label used in the affirmative\")];\n  [alert addButtonWithTitle:NSLocalizedString(@\"ButtonLabelNegative\", @\"The button label used in the negative\")];\n  NSInteger response = [alert runModal];\n  switch (response) {\n    case NSAlertFirstButtonReturn:\n      callback();\n      break;\n    case NSAlertSecondButtonReturn:\n      break;\n    default:\n      break;\n  }\n}\n\n+ (NSString *)pathForPreferencePaneNamed:(NSString *)preferencePaneName\n{\n  NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSAllDomainsMask, YES);\n  NSFileManager *fileManager = NSFileManager.defaultManager;\n  NSString *preferencePanePath = nil;\n  if (preferencePaneName) {\n    preferencePaneName = [preferencePaneName stringByAppendingString:@\".prefPane\"];\n    for (__strong NSString *path in paths) {\n      path = [path stringByAppendingPathComponent:preferencePaneName];\n      if (path && [fileManager fileExistsAtPath:path isDirectory:nil]) {\n        preferencePanePath = path;\n        break;\n      }\n    }\n    if (!preferencePanePath) {\n      NSLog(@\"There was a problem obtaining the path for the specified preference pane: %@\", preferencePaneName);\n    }\n  }\n  return preferencePanePath;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowAction.h",
    "content": "#import <Foundation/Foundation.h>\n\ntypedef NSString SpectacleWindowAction;\n\nextern SpectacleWindowAction *const kSpectacleWindowActionUndo;\nextern SpectacleWindowAction *const kSpectacleWindowActionRedo;\nextern SpectacleWindowAction *const kSpectacleWindowActionLarger;\nextern SpectacleWindowAction *const kSpectacleWindowActionSmaller;\nextern SpectacleWindowAction *const kSpectacleWindowActionNone;\nextern SpectacleWindowAction *const kSpectacleWindowActionCenter;\nextern SpectacleWindowAction *const kSpectacleWindowActionFullscreen;\nextern SpectacleWindowAction *const kSpectacleWindowActionLeftHalf;\nextern SpectacleWindowAction *const kSpectacleWindowActionUpperLeft;\nextern SpectacleWindowAction *const kSpectacleWindowActionLowerLeft;\nextern SpectacleWindowAction *const kSpectacleWindowActionRightHalf;\nextern SpectacleWindowAction *const kSpectacleWindowActionUpperRight;\nextern SpectacleWindowAction *const kSpectacleWindowActionLowerRight;\nextern SpectacleWindowAction *const kSpectacleWindowActionTopHalf;\nextern SpectacleWindowAction *const kSpectacleWindowActionBottomHalf;\nextern SpectacleWindowAction *const kSpectacleWindowActionNextDisplay;\nextern SpectacleWindowAction *const kSpectacleWindowActionPreviousDisplay;\nextern SpectacleWindowAction *const kSpectacleWindowActionNextThird;\nextern SpectacleWindowAction *const kSpectacleWindowActionPreviousThird;\n\nBOOL SpectacleIsUndoWindowAction(SpectacleWindowAction *action);\nBOOL SpectacleIsRedoWindowAction(SpectacleWindowAction *action);\n\nBOOL SpectacleIsNextDisplayWindowAction(SpectacleWindowAction *action);\nBOOL SpectacleIsPreviousDisplayWindowAction(SpectacleWindowAction *action);\nBOOL SpectacleIsMovingToDisplayWindowAction(SpectacleWindowAction *action);\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowAction.m",
    "content": "#import \"SpectacleWindowAction.h\"\n\nSpectacleWindowAction *const kSpectacleWindowActionUndo = @\"SpectacleWindowActionUndo\";\nSpectacleWindowAction *const kSpectacleWindowActionRedo = @\"SpectacleWindowActionRedo\";\nSpectacleWindowAction *const kSpectacleWindowActionLarger = @\"SpectacleWindowActionLarger\";\nSpectacleWindowAction *const kSpectacleWindowActionSmaller = @\"SpectacleWindowActionSmaller\";\nSpectacleWindowAction *const kSpectacleWindowActionNone = @\"SpectacleWindowActionNone\";\nSpectacleWindowAction *const kSpectacleWindowActionCenter = @\"SpectacleWindowActionCenter\";\nSpectacleWindowAction *const kSpectacleWindowActionFullscreen = @\"SpectacleWindowActionFullscreen\";\nSpectacleWindowAction *const kSpectacleWindowActionLeftHalf = @\"SpectacleWindowActionLeftHalf\";\nSpectacleWindowAction *const kSpectacleWindowActionUpperLeft = @\"SpectacleWindowActionUpperLeft\";\nSpectacleWindowAction *const kSpectacleWindowActionLowerLeft = @\"SpectacleWindowActionLowerLeft\";\nSpectacleWindowAction *const kSpectacleWindowActionRightHalf = @\"SpectacleWindowActionRightHalf\";\nSpectacleWindowAction *const kSpectacleWindowActionUpperRight = @\"SpectacleWindowActionUpperRight\";\nSpectacleWindowAction *const kSpectacleWindowActionLowerRight = @\"SpectacleWindowActionLowerRight\";\nSpectacleWindowAction *const kSpectacleWindowActionTopHalf = @\"SpectacleWindowActionTopHalf\";\nSpectacleWindowAction *const kSpectacleWindowActionBottomHalf = @\"SpectacleWindowActionBottomHalf\";\nSpectacleWindowAction *const kSpectacleWindowActionNextDisplay = @\"SpectacleWindowActionNextDisplay\";\nSpectacleWindowAction *const kSpectacleWindowActionPreviousDisplay = @\"SpectacleWindowActionPreviousDisplay\";\nSpectacleWindowAction *const kSpectacleWindowActionNextThird = @\"SpectacleWindowActionNextThird\";\nSpectacleWindowAction *const kSpectacleWindowActionPreviousThird = @\"SpectacleWindowActionPreviousThird\";\n\nBOOL SpectacleIsUndoWindowAction(SpectacleWindowAction *action)\n{\n  return [action isEqualToString:kSpectacleWindowActionUndo];\n}\n\nBOOL SpectacleIsRedoWindowAction(SpectacleWindowAction *action)\n{\n  return [action isEqualToString:kSpectacleWindowActionRedo];\n}\n\nBOOL SpectacleIsNextDisplayWindowAction(SpectacleWindowAction *action)\n{\n  return [action isEqualToString:kSpectacleWindowActionNextDisplay];\n}\n\nBOOL SpectacleIsPreviousDisplayWindowAction(SpectacleWindowAction *action)\n{\n  return [action isEqualToString:kSpectacleWindowActionPreviousDisplay];\n}\n\nBOOL SpectacleIsMovingToDisplayWindowAction(SpectacleWindowAction *action)\n{\n  return SpectacleIsNextDisplayWindowAction(action) || SpectacleIsPreviousDisplayWindowAction(action);\n}\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowMover.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleWindowAction.h\"\n\n@class SpectacleAccessibilityElement;\n\n@protocol SpectacleWindowMover <NSObject>\n\n- (instancetype)initWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover;\n\n+ (instancetype)newWithInnerWindowMover:(id<SpectacleWindowMover>)innerWindowMover;\n\n- (void)moveWindowRect:(CGRect)windowRect\n         frameOfScreen:(CGRect)frameOfScreen\n  visibleFrameOfScreen:(CGRect)visibleFrameOfScreen\nfrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                action:(SpectacleWindowAction *)action;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculationRegistry.h",
    "content": "#import <Foundation/Foundation.h>\n#import <JavaScriptCore/JavaScriptCore.h>\n\n#import \"SpectacleWindowAction.h\"\n\n@class SpectacleWindowPositionCalculationResult;\n\ntypedef CGRect *(^SpectacleWindowPositionCalculation)(CGRect windowRect,\n                                                      CGRect visibleFrameOfSourceScreen,\n                                                      CGRect visibleFrameOfDestinationScreen);\n\n@protocol SpectacleWindowPositionCalculationRegistryExports <JSExport>\n\n- (void)registerWindowPositionCalculation:(JSValue *)windowPositionCalculation withAction:(NSString *)action;\n\n@end\n\n@interface SpectacleWindowPositionCalculationRegistry : NSObject <SpectacleWindowPositionCalculationRegistryExports>\n\n- (JSValue *)windowPositionCalculationWithAction:(SpectacleWindowAction *)action;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculationRegistry.m",
    "content": "#import \"SpectacleWindowPositionCalculationRegistry.h\"\n\n#import \"SpectacleJavaScriptEnvironment.h\"\n#import \"SpectacleWindowPositionCalculationResult.h\"\n\n@interface SpectacleWindowPositionCalculationRegistry ()\n\n@property (nonatomic, readonly, strong) SpectacleJavaScriptEnvironment *javaScriptEnvironment;\n\n@end\n\n@implementation SpectacleWindowPositionCalculationRegistry\n{\n  NSMutableDictionary<SpectacleWindowAction *, JSValue *> *_windowPositionCalculations;\n}\n\n- (instancetype)init\n{\n  if (self = [super init]) {\n    _windowPositionCalculations = [NSMutableDictionary new];\n  }\n  return self;\n}\n\n- (void)registerWindowPositionCalculation:(JSValue *)windowPositionCalculation withAction:(SpectacleWindowAction *)action\n{\n  _windowPositionCalculations[action] = windowPositionCalculation;\n}\n\n- (JSValue *)windowPositionCalculationWithAction:(SpectacleWindowAction *)action\n{\n  return _windowPositionCalculations[action];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculationResult.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n#import \"SpectacleWindowAction.h\"\n\n@interface SpectacleWindowPositionCalculationResult : NSObject\n\n@property (nonatomic, readonly, strong) SpectacleWindowAction *action;\n@property (nonatomic, readonly, assign) CGRect windowRect;\n\n- (instancetype)initWithAction:(SpectacleWindowAction *)action windowRect:(CGRect)windowRect NS_DESIGNATED_INITIALIZER;\n\n+ (instancetype)resultWithAction:(SpectacleWindowAction *)action windowRect:(CGRect)windowRect;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculationResult.m",
    "content": "#import \"SpectacleWindowPositionCalculationResult.h\"\n\n@implementation SpectacleWindowPositionCalculationResult\n\n@synthesize action = _action;\n@synthesize windowRect = _windowRect;\n\n- (instancetype)initWithAction:(SpectacleWindowAction *)action windowRect:(CGRect)windowRect\n{\n  if (self = [super init]) {\n    _action = action;\n    _windowRect = windowRect;\n  }\n  return self;\n}\n\n+ (instancetype)resultWithAction:(SpectacleWindowAction *)action windowRect:(CGRect)windowRect\n{\n  return [[SpectacleWindowPositionCalculationResult alloc] initWithAction:action windowRect:windowRect];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculator.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"SpectacleMacros.h\"\n#import \"SpectacleWindowAction.h\"\n\n@class SpectacleWindowPositionCalculationResult;\n\n@interface SpectacleWindowPositionCalculator : NSObject\n\n- (instancetype)initWithErrorHandler:(void(^)(NSString *message))errorHandler NS_DESIGNATED_INITIALIZER;\n\n- (SpectacleWindowPositionCalculationResult *)calculateWindowRect:(CGRect)windowRect\n                                       visibleFrameOfSourceScreen:(CGRect)visibleFrameOfSourceScreen\n                                  visibleFrameOfDestinationScreen:(CGRect)visibleFrameOfDestinationScreen\n                                                           action:(SpectacleWindowAction *)action;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionCalculator.m",
    "content": "#import \"SpectacleWindowPositionCalculator.h\"\n\n#import <JavaScriptCore/JavaScriptCore.h>\n\n#import \"SpectacleJavaScriptEnvironment.h\"\n#import \"SpectacleWindowPositionCalculationRegistry.h\"\n#import \"SpectacleWindowPositionCalculationResult.h\"\n\n@implementation SpectacleWindowPositionCalculator\n{\n  SpectacleWindowPositionCalculationRegistry *_windowPositionCalculationRegistry;\n  SpectacleJavaScriptEnvironment *_javaScriptEnvironment;\n}\n\n- (instancetype)initWithErrorHandler:(void(^)(NSString *message))errorHandler\n{\n  if (self = [super init]) {\n    _windowPositionCalculationRegistry = [SpectacleWindowPositionCalculationRegistry new];\n    _javaScriptEnvironment = [[SpectacleJavaScriptEnvironment alloc] initWithContextBuilder:^(JSContext *context) {\n      context.exceptionHandler = ^(JSContext *context, JSValue *exception) {\n        NSString *errorName = [exception[@\"name\"] toString];\n        NSString *errorMessage = [exception[@\"message\"] toString];\n        errorHandler([NSString stringWithFormat:@\"%@\\n%@\", errorName, errorMessage]);\n      };\n      context[@\"windowPositionCalculationRegistry\"] = self->_windowPositionCalculationRegistry;\n      context[@\"CGRectContainsRect\"] = ^BOOL(CGRect rect1, CGRect rect2) {\n        return CGRectContainsRect(rect1, rect2);\n      };\n      context[@\"CGRectEqualToRect\"] = ^BOOL(CGRect rect1, CGRect rect2) {\n        return CGRectEqualToRect(rect1, rect2);\n      };\n      context[@\"CGRectGetMinX\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMinX(rect);\n      };\n      context[@\"CGRectGetMinY\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMinY(rect);\n      };\n      context[@\"CGRectGetMidX\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMidX(rect);\n      };\n      context[@\"CGRectGetMidY\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMidY(rect);\n      };\n      context[@\"CGRectGetMaxX\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMaxX(rect);\n      };\n      context[@\"CGRectGetMaxY\"] = ^CGFloat(CGRect rect) {\n        return CGRectGetMaxY(rect);\n      };\n    }];\n  }\n  return self;\n}\n\n- (SpectacleWindowPositionCalculationResult *)calculateWindowRect:(CGRect)windowRect\n                                       visibleFrameOfSourceScreen:(CGRect)visibleFrameOfSourceScreen\n                                  visibleFrameOfDestinationScreen:(CGRect)visibleFrameOfDestinationScreen\n                                                           action:(SpectacleWindowAction *)action\n{\n  JSValue *windowPositionCalculation = [_windowPositionCalculationRegistry windowPositionCalculationWithAction:action];\n  if (!windowPositionCalculation) {\n    return nil;\n  }\n  JSValue *result = [windowPositionCalculation callWithArguments:@[\n                                                                   [_javaScriptEnvironment valueWithRect:windowRect],\n                                                                   [_javaScriptEnvironment valueWithRect:visibleFrameOfSourceScreen],\n                                                                   [_javaScriptEnvironment valueWithRect:visibleFrameOfDestinationScreen],\n                                                                   ]];\n  return [SpectacleWindowPositionCalculationResult resultWithAction:action windowRect:[result toRect]];\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionManager.h",
    "content": "#import <Cocoa/Cocoa.h>\n\n#import \"SpectacleMacros.h\"\n#import \"SpectacleWindowAction.h\"\n\ntypedef void (^SpectacleFailureFeedback)(void);\n\n@class SpectacleAccessibilityElement;\n@class SpectacleScreenDetector;\n@class SpectacleShortcut;\n@class SpectacleWindowPositionCalculator;\n\n@protocol SpectacleWindowMover;\n\n@interface SpectacleWindowPositionManager : NSObject\n\n- (instancetype)initWithScreenDetector:(SpectacleScreenDetector *)screenDetector\n              windowPositionCalculator:(SpectacleWindowPositionCalculator *)windowPositionCalculator\n                       sharedWorkspace:(NSWorkspace *)sharedWorkspace\n                       failureFeedback:(SpectacleFailureFeedback)failureFeedback\n                           windowMover:(id<SpectacleWindowMover>)windowMover NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)initWithScreenDetector:(SpectacleScreenDetector *)screenDetector\n              windowPositionCalculator:(SpectacleWindowPositionCalculator *)windowPositionCalculator\n                       sharedWorkspace:(NSWorkspace *)sharedWorkspace;\n\nSPECTACLE_INIT_AND_NEW_UNAVAILABLE\n\n- (void)moveFrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                            action:(SpectacleWindowAction *)action\n                           screens:(NSArray<NSScreen *> *)screens\n                        mainScreen:(NSScreen *)mainScreen;\n\n- (void)moveFrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                            action:(SpectacleWindowAction *)action;\n\n- (void)undoLastWindowAction;\n- (void)redoLastWindowAction;\n\n@end\n"
  },
  {
    "path": "Spectacle/Sources/SpectacleWindowPositionManager.m",
    "content": "#import \"SpectacleWindowPositionManager.h\"\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleBestEffortWindowMover.h\"\n#import \"SpectacleHistory.h\"\n#import \"SpectacleHistoryItem.h\"\n#import \"SpectacleQuantizedWindowMover.h\"\n#import \"SpectacleScreenDetectionResult.h\"\n#import \"SpectacleScreenDetector.h\"\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleStandardWindowMover.h\"\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\n@implementation SpectacleWindowPositionManager\n{\n  NSMutableDictionary<NSString *, SpectacleHistory *> *_applicationHistories;\n  SpectacleScreenDetector *_screenDetector;\n  SpectacleWindowPositionCalculator *_windowPositionCalculator;\n  NSWorkspace *_sharedWorkspace;\n  SpectacleFailureFeedback _failureFeedback;\n  id<SpectacleWindowMover> _windowMover;\n}\n\n- (instancetype)initWithScreenDetector:(SpectacleScreenDetector *)screenDetector\n              windowPositionCalculator:(SpectacleWindowPositionCalculator *)windowPositionCalculator\n                       sharedWorkspace:(NSWorkspace *)sharedWorkspace\n                       failureFeedback:(SpectacleFailureFeedback)failureFeedback\n                           windowMover:(id<SpectacleWindowMover>)windowMover\n{\n  if (self = [super init]) {\n    _applicationHistories = [NSMutableDictionary new];\n    _screenDetector = screenDetector;\n    _windowPositionCalculator = windowPositionCalculator;\n    _sharedWorkspace = sharedWorkspace;\n    _failureFeedback = failureFeedback;\n    _windowMover = windowMover;\n  }\n  return self;\n}\n\n- (instancetype)initWithScreenDetector:(SpectacleScreenDetector *)screenDetector\n              windowPositionCalculator:(SpectacleWindowPositionCalculator *)windowPositionCalculator\n                       sharedWorkspace:(NSWorkspace *)sharedWorkspace\n{\n  return [self initWithScreenDetector:screenDetector\n             windowPositionCalculator:windowPositionCalculator\n                      sharedWorkspace:sharedWorkspace\n                      failureFeedback:^() { NSBeep(); }\n                          windowMover:[SpectacleStandardWindowMover newWithInnerWindowMover:\n                                       [SpectacleQuantizedWindowMover newWithInnerWindowMover:\n                                        [SpectacleBestEffortWindowMover new]]]];\n}\n\n- (void)moveFrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                            action:(SpectacleWindowAction *)action\n                           screens:(NSArray<NSScreen *> *)screens\n                        mainScreen:(NSScreen *)mainScreen\n{\n  SpectacleScreenDetectionResult *screenDetectionResult = [_screenDetector screenWithAction:action\n                                                                     frontmostWindowElement:frontmostWindowElement\n                                                                                    screens:screens\n                                                                                 mainScreen:mainScreen];\n  CGRect frameOfDestinationScreen = CGRectNull;\n  CGRect visibleFrameOfDestinationScreen = CGRectNull;\n  CGRect visibleFrameOfSourceScreen = CGRectNull;\n  SpectacleHistory *history = [self historyForCurrentApplication];\n  SpectacleHistoryItem *historyItem = nil;\n  SpectacleWindowPositionCalculationResult *windowPositionCalculationResult = nil;\n  if (screenDetectionResult.destinationScreen && screenDetectionResult.sourceScreen) {\n    frameOfDestinationScreen = NSRectToCGRect([screenDetectionResult.destinationScreen frame]);\n    visibleFrameOfDestinationScreen = NSRectToCGRect([screenDetectionResult.destinationScreen visibleFrame]);\n    visibleFrameOfSourceScreen = NSRectToCGRect([screenDetectionResult.sourceScreen visibleFrame]);\n  }\n  CGRect frontmostWindowRect = [frontmostWindowElement rectOfElement];\n  CGRect previousFrontmostWindowRect = CGRectNull;\n  if ([frontmostWindowElement isSheet]\n      || [frontmostWindowElement isSystemDialog]\n      || CGRectIsNull(frontmostWindowRect)\n      || CGRectIsNull(frameOfDestinationScreen)\n      || CGRectIsNull(visibleFrameOfDestinationScreen)\n      || CGRectIsNull(visibleFrameOfSourceScreen)) {\n    _failureFeedback();\n    return;\n  }\n  if ([history isEmpty]) {\n    historyItem = [SpectacleHistoryItem historyItemFromAccessibilityElement:frontmostWindowElement\n                                                                 windowRect:frontmostWindowRect];\n    [history addHistoryItem:historyItem];\n  }\n  frontmostWindowRect = [SpectacleAccessibilityElement normalizeCoordinatesOfRect:frontmostWindowRect\n                                                                    frameOfScreen:frameOfDestinationScreen];\n  previousFrontmostWindowRect = frontmostWindowRect;\n  windowPositionCalculationResult = [_windowPositionCalculator calculateWindowRect:frontmostWindowRect\n                                                        visibleFrameOfSourceScreen:visibleFrameOfSourceScreen\n                                                   visibleFrameOfDestinationScreen:visibleFrameOfDestinationScreen\n                                                                            action:action];\n  if (!windowPositionCalculationResult) {\n    _failureFeedback();\n    return;\n  }\n  action = windowPositionCalculationResult.action;\n  frontmostWindowRect = windowPositionCalculationResult.windowRect;\n  if (CGRectEqualToRect(previousFrontmostWindowRect, frontmostWindowRect)) {\n    _failureFeedback();\n    return;\n  }\n  frontmostWindowRect = [SpectacleAccessibilityElement normalizeCoordinatesOfRect:frontmostWindowRect\n                                                                    frameOfScreen:frameOfDestinationScreen];\n  historyItem = [SpectacleHistoryItem historyItemFromAccessibilityElement:frontmostWindowElement\n                                                               windowRect:frontmostWindowRect];\n  [history addHistoryItem:historyItem];\n  [_windowMover moveWindowRect:frontmostWindowRect\n                 frameOfScreen:frameOfDestinationScreen\n          visibleFrameOfScreen:visibleFrameOfDestinationScreen\n        frontmostWindowElement:frontmostWindowElement\n                        action:action];\n}\n\n- (void)moveFrontmostWindowElement:(SpectacleAccessibilityElement *)frontmostWindowElement\n                            action:(SpectacleWindowAction *)action\n{\n  if (SpectacleIsUndoWindowAction(action)) {\n    [self undoLastWindowAction];\n  } else if (SpectacleIsRedoWindowAction(action)) {\n    [self redoLastWindowAction];\n  } else {\n    [self moveFrontmostWindowElement:frontmostWindowElement\n                              action:action\n                             screens:[NSScreen screens]\n                          mainScreen:[NSScreen mainScreen]];\n  }\n}\n\n- (void)undoLastWindowAction\n{\n  [self moveWithHistoryItem:[self historyForCurrentApplication].previousHistoryItem\n                     action:kSpectacleWindowActionUndo\n                    screens:[NSScreen screens]\n                 mainScreen:[NSScreen mainScreen]];\n}\n\n- (void)redoLastWindowAction\n{\n  [self moveWithHistoryItem:[self historyForCurrentApplication].nextHistoryItem\n                     action:kSpectacleWindowActionRedo\n                    screens:[NSScreen screens]\n                 mainScreen:[NSScreen mainScreen]];\n}\n\n- (SpectacleHistory *)historyForCurrentApplication\n{\n  NSString *frontmostApplicationBundleIdentifier = _sharedWorkspace.frontmostApplication.bundleIdentifier;\n  if (!frontmostApplicationBundleIdentifier) {\n    return nil;\n  }\n  if (!_applicationHistories[frontmostApplicationBundleIdentifier]) {\n    _applicationHistories[frontmostApplicationBundleIdentifier] = [SpectacleHistory new];\n  }\n  return _applicationHistories[frontmostApplicationBundleIdentifier];\n}\n\n- (void)moveWithHistoryItem:(SpectacleHistoryItem *)historyItem\n                     action:(SpectacleWindowAction *)action\n                    screens:(NSArray<NSScreen *> *)screens\n                 mainScreen:(NSScreen *)mainScreen\n{\n  SpectacleScreenDetectionResult *screenDetectionResult = [_screenDetector screenWithAction:action\n                                                                     frontmostWindowElement:historyItem.accessibilityElement\n                                                                                    screens:screens\n                                                                                 mainScreen:mainScreen];\n  CGRect visibleFrameOfScreen = CGRectNull;\n  if (screenDetectionResult.destinationScreen) {\n    visibleFrameOfScreen = NSRectToCGRect(screenDetectionResult.destinationScreen.visibleFrame);\n  }\n  if (![self moveWithHistoryItem:historyItem visibleFrameOfScreen:visibleFrameOfScreen action:action]) {\n    _failureFeedback();\n  }\n}\n\n- (BOOL)moveWithHistoryItem:(SpectacleHistoryItem *)historyItem\n       visibleFrameOfScreen:(CGRect)visibleFrameOfScreen\n                     action:(SpectacleWindowAction *)action\n{\n  SpectacleAccessibilityElement *frontmostWindowElement = historyItem.accessibilityElement;\n  CGRect windowRect = historyItem.windowRect;\n  if (!historyItem\n      || !frontmostWindowElement\n      || CGRectIsNull(windowRect)\n      || CGRectIsNull(visibleFrameOfScreen)) {\n    return NO;\n  }\n  [_windowMover moveWindowRect:windowRect\n                 frameOfScreen:CGRectNull\n          visibleFrameOfScreen:visibleFrameOfScreen\n        frontmostWindowElement:frontmostWindowElement\n                        action:action];\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "Spectacle/Supporting Files/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en_US</string>\n\t<key>CFBundleExecutable</key>\n\t<string>Spectacle</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>Spectacle</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.2</string>\n\t<key>CFBundleSignature</key>\n\t<string>ZERO</string>\n\t<key>CFBundleVersion</key>\n\t<string>0</string>\n\t<key>LSApplicationCategoryType</key>\n\t<string>public.app-category.utilities</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>10.9</string>\n\t<key>LSUIElement</key>\n\t<true/>\n\t<key>NSMainNibFile</key>\n\t<string>Spectacle</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n\t<key>SUAllowsAutomaticUpdates</key>\n\t<false/>\n\t<key>SUEnableAutomaticChecks</key>\n\t<true/>\n\t<key>SUFeedURL</key>\n\t<string>https://spectacleapp.com/updates/appcast.xml</string>\n\t<key>SUPublicDSAKeyFile</key>\n\t<string>dsa_public.pem</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Spectacle/Supporting Files/main.m",
    "content": "#import <Cocoa/Cocoa.h>\n\nint main(int argc, char *argv[])\n{\n  return NSApplicationMain(argc, (const char **)argv);\n}\n"
  },
  {
    "path": "Spectacle.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 47;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t07838603148BD517001E7BD7 /* SpectaclePreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 07838602148BD517001E7BD7 /* SpectaclePreferencesController.m */; };\n\t\t2D0759A71C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D0759A61C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.m */; };\n\t\t2D1AE52515D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D1AE52415D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.m */; };\n\t\t2D20F0181CD18ED7003DDA5B /* SpectacleBottomHalfWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0081CD18ED7003DDA5B /* SpectacleBottomHalfWindowCalculationSpec.m */; };\n\t\t2D20F0191CD18ED7003DDA5B /* SpectacleCenterWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0091CD18ED7003DDA5B /* SpectacleCenterWindowCalculationSpec.m */; };\n\t\t2D20F01A1CD18ED7003DDA5B /* SpectacleFullscreenWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00A1CD18ED7003DDA5B /* SpectacleFullscreenWindowCalculationSpec.m */; };\n\t\t2D20F01B1CD18ED7003DDA5B /* SpectacleLargerWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00B1CD18ED7003DDA5B /* SpectacleLargerWindowCalculationSpec.m */; };\n\t\t2D20F01C1CD18ED7003DDA5B /* SpectacleLeftHalfWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00C1CD18ED7003DDA5B /* SpectacleLeftHalfWindowCalculationSpec.m */; };\n\t\t2D20F01D1CD18ED7003DDA5B /* SpectacleLowerLeftWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00D1CD18ED7003DDA5B /* SpectacleLowerLeftWindowCalculationSpec.m */; };\n\t\t2D20F01E1CD18ED7003DDA5B /* SpectacleLowerRightWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00E1CD18ED7003DDA5B /* SpectacleLowerRightWindowCalculationSpec.m */; };\n\t\t2D20F01F1CD18ED7003DDA5B /* SpectacleNextDisplayWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F00F1CD18ED7003DDA5B /* SpectacleNextDisplayWindowCalculationSpec.m */; };\n\t\t2D20F0201CD18ED7003DDA5B /* SpectacleNextThirdWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0101CD18ED7003DDA5B /* SpectacleNextThirdWindowCalculationSpec.m */; };\n\t\t2D20F0211CD18ED7003DDA5B /* SpectaclePreviousDisplayWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0111CD18ED7003DDA5B /* SpectaclePreviousDisplayWindowCalculationSpec.m */; };\n\t\t2D20F0221CD18ED7003DDA5B /* SpectaclePreviousThirdWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0121CD18ED7003DDA5B /* SpectaclePreviousThirdWindowCalculationSpec.m */; };\n\t\t2D20F0231CD18ED7003DDA5B /* SpectacleRightHalfWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0131CD18ED7003DDA5B /* SpectacleRightHalfWindowCalculationSpec.m */; };\n\t\t2D20F0241CD18ED7003DDA5B /* SpectacleSmallerWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0141CD18ED7003DDA5B /* SpectacleSmallerWindowCalculationSpec.m */; };\n\t\t2D20F0251CD18ED7003DDA5B /* SpectacleTopHalfWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0151CD18ED7003DDA5B /* SpectacleTopHalfWindowCalculationSpec.m */; };\n\t\t2D20F0261CD18ED7003DDA5B /* SpectacleUpperLeftWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0161CD18ED7003DDA5B /* SpectacleUpperLeftWindowCalculationSpec.m */; };\n\t\t2D20F0271CD18ED7003DDA5B /* SpectacleUpperRightWindowCalculationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0171CD18ED7003DDA5B /* SpectacleUpperRightWindowCalculationSpec.m */; };\n\t\t2D20F0291CD1969D003DDA5B /* SpectacleWindowPositionManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F0281CD1969D003DDA5B /* SpectacleWindowPositionManagerSpec.m */; };\n\t\t2D24ACB41CC723F600AB3984 /* SpectacleWindowAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D24ACB31CC723F600AB3984 /* SpectacleWindowAction.m */; };\n\t\t2D24ACB71CC8728E00AB3984 /* SpectacleShortcutHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D24ACB61CC8728E00AB3984 /* SpectacleShortcutHolder.m */; };\n\t\t2D2629461CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D2629451CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.m */; };\n\t\t2D279ED416BB4A7800F6894A /* SpectacleHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D279ED316BB4A7800F6894A /* SpectacleHistory.m */; };\n\t\t2D3A050D194956E100CD96E7 /* SpectacleAccessibilityElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A04FD194956E100CD96E7 /* SpectacleAccessibilityElement.m */; };\n\t\t2D3A050E194956E100CD96E7 /* SpectacleShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A0500194956E100CD96E7 /* SpectacleShortcut.m */; };\n\t\t2D3A050F194956E100CD96E7 /* SpectacleShortcutRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A0502194956E100CD96E7 /* SpectacleShortcutRecorder.m */; };\n\t\t2D3A0511194956E100CD96E7 /* SpectacleShortcutTranslations.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A0507194956E100CD96E7 /* SpectacleShortcutTranslations.m */; };\n\t\t2D3A0512194956E100CD96E7 /* SpectacleShortcutValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A0509194956E100CD96E7 /* SpectacleShortcutValidation.m */; };\n\t\t2D4F3ED014A27B4500C29D11 /* SpectacleScreenDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D4F3ECF14A27B4500C29D11 /* SpectacleScreenDetector.m */; };\n\t\t2D5565B1181EDB7F00EFB43A /* Security & Privacy System Preferences.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 2D5565B0181EDB7F00EFB43A /* Security & Privacy System Preferences.scpt */; };\n\t\t2D5783F11BB63BDD00695771 /* SpectacleStandardWindowMover.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D5783F01BB63BDD00695771 /* SpectacleStandardWindowMover.m */; };\n\t\t2D58AE341D7D19AF00BFEEA2 /* SpectacleShortcutTranslationsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D58AE331D7D19AF00BFEEA2 /* SpectacleShortcutTranslationsSpec.m */; };\n\t\t2D58AE361D7D2D5300BFEEA2 /* SpectacleShortcutSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D58AE351D7D2D5300BFEEA2 /* SpectacleShortcutSpec.m */; };\n\t\t2D58CC391C7030B800E3DC74 /* Window Position Calculations in Resources */ = {isa = PBXBuildFile; fileRef = 2D58CC381C7030B800E3DC74 /* Window Position Calculations */; };\n\t\t2D5A83051CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A83041CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.m */; };\n\t\t2D5A83091CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A83081CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.m */; };\n\t\t2D5A830F1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A830E1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.m */; };\n\t\t2D5CCCE915E96F740009CC43 /* dsa_public.pem in Resources */ = {isa = PBXBuildFile; fileRef = 2D5CCCE815E96F740009CC43 /* dsa_public.pem */; };\n\t\t2D7146541CCC12A6003B8292 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2D7146521CCC12A6003B8292 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\t2D71466B1CCC1715003B8292 /* Expecta.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2D7146671CCC1715003B8292 /* Expecta.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\t2D71466C1CCC1715003B8292 /* OCHamcrest.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2D7146681CCC1715003B8292 /* OCHamcrest.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\t2D71466D1CCC1715003B8292 /* OCMockito.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2D7146691CCC1715003B8292 /* OCMockito.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\t2D71466E1CCC1715003B8292 /* Specta.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2D71466A1CCC1715003B8292 /* Specta.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\t2D71466F1CCC171F003B8292 /* Expecta.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D7146671CCC1715003B8292 /* Expecta.framework */; };\n\t\t2D7146701CCC171F003B8292 /* OCHamcrest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D7146681CCC1715003B8292 /* OCHamcrest.framework */; };\n\t\t2D7146711CCC171F003B8292 /* OCMockito.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D7146691CCC1715003B8292 /* OCMockito.framework */; };\n\t\t2D7146721CCC171F003B8292 /* Specta.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D71466A1CCC1715003B8292 /* Specta.framework */; };\n\t\t2D768E8D147ED51A00901E76 /* SpectacleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D768E8C147ED51A00901E76 /* SpectacleAppDelegate.m */; };\n\t\t2D7752101B83E94C00C022EE /* Spectacle.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2DC4E3D01AD84E5C0022ABF0 /* Spectacle.xib */; };\n\t\t2D7752111B83E95000C022EE /* SpectaclePreferencesWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2DC4E3D21AD84E5C0022ABF0 /* SpectaclePreferencesWindow.xib */; };\n\t\t2D7C114A1B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D7C11491B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.m */; };\n\t\t2D7CF9EB1C6FED50004DC708 /* SpectacleWindowPositionCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D7CF9EA1C6FED50004DC708 /* SpectacleWindowPositionCalculator.m */; };\n\t\t2D8DA04D147E0FA0003BE1D3 /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0706C0431191092B0068F04B /* Defaults.plist */; };\n\t\t2D8DA056147E113D003BE1D3 /* SpectacleShortcutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 07678096118679C600614FB5 /* SpectacleShortcutManager.m */; };\n\t\t2D8DA057147E113D003BE1D3 /* SpectacleUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 07BB542C1186662F0045663F /* SpectacleUtilities.m */; };\n\t\t2D8DA058147E113D003BE1D3 /* SpectacleWindowPositionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 072EACFF118A4D5A0015FC8A /* SpectacleWindowPositionManager.m */; };\n\t\t2D8DA05D147E113D003BE1D3 /* SpectacleHistoryItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 079CDA0E1221BAFF0099612C /* SpectacleHistoryItem.m */; };\n\t\t2D8DA05E147E113D003BE1D3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 077938E51184FADB0013BC14 /* main.m */; };\n\t\t2D8E2C641C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D8E2C631C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.m */; };\n\t\t2D98D7311AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D98D7301AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.m */; };\n\t\t2DA23EFC1B7D736100C9E8EF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DA23EFB1B7D736100C9E8EF /* Images.xcassets */; };\n\t\t2DAC59F01BB238D900C660ED /* SpectacleQuantizedWindowMover.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC59EF1BB238D900C660ED /* SpectacleQuantizedWindowMover.m */; };\n\t\t2DAC59F31BB23BE200C660ED /* SpectacleBestEffortWindowMover.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC59F21BB23BE200C660ED /* SpectacleBestEffortWindowMover.m */; };\n\t\t2DC4E3D41AD84E5C0022ABF0 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2DC4E3CA1AD84E5C0022ABF0 /* Credits.rtf */; };\n\t\t2DC4E3D51AD84E5C0022ABF0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2DC4E3CC1AD84E5C0022ABF0 /* InfoPlist.strings */; };\n\t\t2DC4E3D61AD84E5C0022ABF0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2DC4E3CE1AD84E5C0022ABF0 /* Localizable.strings */; };\n\t\t2DC8A0171B85097900ABEBD5 /* SpectacleLoginItemHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DC8A0161B85097900ABEBD5 /* SpectacleLoginItemHelper.m */; };\n\t\t2DE03E481D7B8F5A004E80D6 /* SpectacleShortcutKeyBindingsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE03E471D7B8F5A004E80D6 /* SpectacleShortcutKeyBindingsSpec.m */; };\n\t\t2DE03E4B1D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE03E4A1D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t2DA5B7CC19F8BA79007EDE8E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 089C1669FE841209C02AAC07 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2D1E1AAF147E06AD0021D73D;\n\t\t\tremoteInfo = Spectacle;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t2D7146551CCC12A6003B8292 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t\t2D7146541CCC12A6003B8292 /* Sparkle.framework in Embed Frameworks */,\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D7146661CCC16FD003B8292 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t\t2D71466B1CCC1715003B8292 /* Expecta.framework in CopyFiles */,\n\t\t\t\t2D71466C1CCC1715003B8292 /* OCHamcrest.framework in CopyFiles */,\n\t\t\t\t2D71466D1CCC1715003B8292 /* OCMockito.framework in CopyFiles */,\n\t\t\t\t2D71466E1CCC1715003B8292 /* Specta.framework in CopyFiles */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t0706C0431191092B0068F04B /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Defaults.plist; path = \"Spectacle/Resources/Property Lists/Defaults.plist\"; sourceTree = \"<group>\"; };\n\t\t072EACFE118A4D5A0015FC8A /* SpectacleWindowPositionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleWindowPositionManager.h; path = Spectacle/Sources/SpectacleWindowPositionManager.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t072EACFF118A4D5A0015FC8A /* SpectacleWindowPositionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleWindowPositionManager.m; path = Spectacle/Sources/SpectacleWindowPositionManager.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t07678095118679C600614FB5 /* SpectacleShortcutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleShortcutManager.h; path = Spectacle/Sources/SpectacleShortcutManager.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t07678096118679C600614FB5 /* SpectacleShortcutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutManager.m; path = Spectacle/Sources/SpectacleShortcutManager.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t077938E51184FADB0013BC14 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = main.m; path = \"Spectacle/Supporting Files/main.m\"; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t07838601148BD517001E7BD7 /* SpectaclePreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectaclePreferencesController.h; path = Spectacle/Sources/SpectaclePreferencesController.h; sourceTree = \"<group>\"; };\n\t\t07838602148BD517001E7BD7 /* SpectaclePreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectaclePreferencesController.m; path = Spectacle/Sources/SpectaclePreferencesController.m; sourceTree = \"<group>\"; };\n\t\t079CDA0D1221BAFF0099612C /* SpectacleHistoryItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleHistoryItem.h; path = Spectacle/Sources/SpectacleHistoryItem.h; sourceTree = \"<group>\"; };\n\t\t079CDA0E1221BAFF0099612C /* SpectacleHistoryItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleHistoryItem.m; path = Spectacle/Sources/SpectacleHistoryItem.m; sourceTree = \"<group>\"; };\n\t\t07BB542B1186662F0045663F /* SpectacleUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleUtilities.h; path = Spectacle/Sources/SpectacleUtilities.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t07BB542C1186662F0045663F /* SpectacleUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleUtilities.m; path = Spectacle/Sources/SpectacleUtilities.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D0759A51C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleWindowPositionCalculationRegistry.h; path = Spectacle/Sources/SpectacleWindowPositionCalculationRegistry.h; sourceTree = \"<group>\"; };\n\t\t2D0759A61C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleWindowPositionCalculationRegistry.m; path = Spectacle/Sources/SpectacleWindowPositionCalculationRegistry.m; sourceTree = \"<group>\"; };\n\t\t2D1AE52315D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleRegisteredShortcutValidator.h; path = Spectacle/Sources/SpectacleRegisteredShortcutValidator.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t2D1AE52415D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleRegisteredShortcutValidator.m; path = Spectacle/Sources/SpectacleRegisteredShortcutValidator.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D1E1AB0147E06AD0021D73D /* Spectacle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Spectacle.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2D1E1AD2147E07E50021D73D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = \"Spectacle/Supporting Files/Info.plist\"; sourceTree = \"<group>\"; };\n\t\t2D20F0081CD18ED7003DDA5B /* SpectacleBottomHalfWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleBottomHalfWindowCalculationSpec.m; path = Sources/SpectacleBottomHalfWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0091CD18ED7003DDA5B /* SpectacleCenterWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleCenterWindowCalculationSpec.m; path = Sources/SpectacleCenterWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00A1CD18ED7003DDA5B /* SpectacleFullscreenWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleFullscreenWindowCalculationSpec.m; path = Sources/SpectacleFullscreenWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00B1CD18ED7003DDA5B /* SpectacleLargerWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleLargerWindowCalculationSpec.m; path = Sources/SpectacleLargerWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00C1CD18ED7003DDA5B /* SpectacleLeftHalfWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleLeftHalfWindowCalculationSpec.m; path = Sources/SpectacleLeftHalfWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00D1CD18ED7003DDA5B /* SpectacleLowerLeftWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleLowerLeftWindowCalculationSpec.m; path = Sources/SpectacleLowerLeftWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00E1CD18ED7003DDA5B /* SpectacleLowerRightWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleLowerRightWindowCalculationSpec.m; path = Sources/SpectacleLowerRightWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F00F1CD18ED7003DDA5B /* SpectacleNextDisplayWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleNextDisplayWindowCalculationSpec.m; path = Sources/SpectacleNextDisplayWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0101CD18ED7003DDA5B /* SpectacleNextThirdWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleNextThirdWindowCalculationSpec.m; path = Sources/SpectacleNextThirdWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0111CD18ED7003DDA5B /* SpectaclePreviousDisplayWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectaclePreviousDisplayWindowCalculationSpec.m; path = Sources/SpectaclePreviousDisplayWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0121CD18ED7003DDA5B /* SpectaclePreviousThirdWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectaclePreviousThirdWindowCalculationSpec.m; path = Sources/SpectaclePreviousThirdWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0131CD18ED7003DDA5B /* SpectacleRightHalfWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleRightHalfWindowCalculationSpec.m; path = Sources/SpectacleRightHalfWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0141CD18ED7003DDA5B /* SpectacleSmallerWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleSmallerWindowCalculationSpec.m; path = Sources/SpectacleSmallerWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0151CD18ED7003DDA5B /* SpectacleTopHalfWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleTopHalfWindowCalculationSpec.m; path = Sources/SpectacleTopHalfWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0161CD18ED7003DDA5B /* SpectacleUpperLeftWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleUpperLeftWindowCalculationSpec.m; path = Sources/SpectacleUpperLeftWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0171CD18ED7003DDA5B /* SpectacleUpperRightWindowCalculationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleUpperRightWindowCalculationSpec.m; path = Sources/SpectacleUpperRightWindowCalculationSpec.m; sourceTree = \"<group>\"; };\n\t\t2D20F0281CD1969D003DDA5B /* SpectacleWindowPositionManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleWindowPositionManagerSpec.m; path = Sources/SpectacleWindowPositionManagerSpec.m; sourceTree = \"<group>\"; };\n\t\t2D2490DF1C7A5BD900A4282B /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Spectacle/Resources/Localizations/fi.lproj/Spectacle.strings; sourceTree = \"<group>\"; };\n\t\t2D2490E01C7A5BD900A4282B /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Spectacle/Resources/Localizations/fi.lproj/SpectaclePreferencesWindow.strings; sourceTree = \"<group>\"; };\n\t\t2D2490E11C7A5BD900A4282B /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = fi; path = Spectacle/Resources/Localizations/fi.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t2D2490E21C7A5BD900A4282B /* fi */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fi; path = Spectacle/Resources/Localizations/fi.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t2D2490E31C7A5BD900A4282B /* fi */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fi; path = Spectacle/Resources/Localizations/fi.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\t2D24ACB31CC723F600AB3984 /* SpectacleWindowAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleWindowAction.m; path = Spectacle/Sources/SpectacleWindowAction.m; sourceTree = \"<group>\"; };\n\t\t2D24ACB51CC8728E00AB3984 /* SpectacleShortcutHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutHolder.h; path = Spectacle/Sources/SpectacleShortcutHolder.h; sourceTree = \"<group>\"; };\n\t\t2D24ACB61CC8728E00AB3984 /* SpectacleShortcutHolder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutHolder.m; path = Spectacle/Sources/SpectacleShortcutHolder.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D2629441CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleScreenDetectionResult.h; path = Spectacle/Sources/SpectacleScreenDetectionResult.h; sourceTree = \"<group>\"; };\n\t\t2D2629451CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleScreenDetectionResult.m; path = Spectacle/Sources/SpectacleScreenDetectionResult.m; sourceTree = \"<group>\"; };\n\t\t2D279ED216BB4A7800F6894A /* SpectacleHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleHistory.h; path = Spectacle/Sources/SpectacleHistory.h; sourceTree = \"<group>\"; };\n\t\t2D279ED316BB4A7800F6894A /* SpectacleHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleHistory.m; path = Spectacle/Sources/SpectacleHistory.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D2A61A31DC2CD9C00D86193 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Spectacle/Resources/Localizations/es.lproj/Spectacle.strings; sourceTree = \"<group>\"; };\n\t\t2D2A61A41DC2CD9C00D86193 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Spectacle/Resources/Localizations/es.lproj/SpectaclePreferencesWindow.strings; sourceTree = \"<group>\"; };\n\t\t2D2A61A51DC2CD9C00D86193 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = es; path = Spectacle/Resources/Localizations/es.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t2D2A61A61DC2CD9C00D86193 /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = Spectacle/Resources/Localizations/es.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t2D2A61A71DC2CD9C00D86193 /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = Spectacle/Resources/Localizations/es.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\t2D3A04FC194956E100CD96E7 /* SpectacleAccessibilityElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleAccessibilityElement.h; path = Spectacle/Sources/SpectacleAccessibilityElement.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t2D3A04FD194956E100CD96E7 /* SpectacleAccessibilityElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleAccessibilityElement.m; path = Spectacle/Sources/SpectacleAccessibilityElement.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D3A04FF194956E100CD96E7 /* SpectacleShortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleShortcut.h; path = Spectacle/Sources/SpectacleShortcut.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t2D3A0500194956E100CD96E7 /* SpectacleShortcut.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcut.m; path = Spectacle/Sources/SpectacleShortcut.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D3A0501194956E100CD96E7 /* SpectacleShortcutRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutRecorder.h; path = Spectacle/Sources/SpectacleShortcutRecorder.h; sourceTree = \"<group>\"; };\n\t\t2D3A0502194956E100CD96E7 /* SpectacleShortcutRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleShortcutRecorder.m; path = Spectacle/Sources/SpectacleShortcutRecorder.m; sourceTree = \"<group>\"; };\n\t\t2D3A0505194956E100CD96E7 /* SpectacleShortcutRecorderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutRecorderDelegate.h; path = Spectacle/Sources/SpectacleShortcutRecorderDelegate.h; sourceTree = \"<group>\"; };\n\t\t2D3A0506194956E100CD96E7 /* SpectacleShortcutTranslations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutTranslations.h; path = Spectacle/Sources/SpectacleShortcutTranslations.h; sourceTree = \"<group>\"; };\n\t\t2D3A0507194956E100CD96E7 /* SpectacleShortcutTranslations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutTranslations.m; path = Spectacle/Sources/SpectacleShortcutTranslations.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D3A0508194956E100CD96E7 /* SpectacleShortcutValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutValidation.h; path = Spectacle/Sources/SpectacleShortcutValidation.h; sourceTree = \"<group>\"; };\n\t\t2D3A0509194956E100CD96E7 /* SpectacleShortcutValidation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutValidation.m; path = Spectacle/Sources/SpectacleShortcutValidation.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D3A050A194956E100CD96E7 /* SpectacleShortcutValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutValidator.h; path = Spectacle/Sources/SpectacleShortcutValidator.h; sourceTree = \"<group>\"; };\n\t\t2D4F3ECE14A27B4500C29D11 /* SpectacleScreenDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleScreenDetector.h; path = Spectacle/Sources/SpectacleScreenDetector.h; sourceTree = \"<group>\"; };\n\t\t2D4F3ECF14A27B4500C29D11 /* SpectacleScreenDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleScreenDetector.m; path = Spectacle/Sources/SpectacleScreenDetector.m; sourceTree = \"<group>\"; };\n\t\t2D5565B0181EDB7F00EFB43A /* Security & Privacy System Preferences.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = \"Security & Privacy System Preferences.scpt\"; path = \"Spectacle/Resources/Scripts/Security & Privacy System Preferences.scpt\"; sourceTree = \"<group>\"; };\n\t\t2D5783EF1BB63BDD00695771 /* SpectacleStandardWindowMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleStandardWindowMover.h; path = Spectacle/Sources/SpectacleStandardWindowMover.h; sourceTree = \"<group>\"; };\n\t\t2D5783F01BB63BDD00695771 /* SpectacleStandardWindowMover.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleStandardWindowMover.m; path = Spectacle/Sources/SpectacleStandardWindowMover.m; sourceTree = \"<group>\"; };\n\t\t2D58AE331D7D19AF00BFEEA2 /* SpectacleShortcutTranslationsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleShortcutTranslationsSpec.m; path = Sources/SpectacleShortcutTranslationsSpec.m; sourceTree = \"<group>\"; };\n\t\t2D58AE351D7D2D5300BFEEA2 /* SpectacleShortcutSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutSpec.m; path = Sources/SpectacleShortcutSpec.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D58CC381C7030B800E3DC74 /* Window Position Calculations */ = {isa = PBXFileReference; lastKnownFileType = folder; name = \"Window Position Calculations\"; path = \"Spectacle/Resources/Window Position Calculations\"; sourceTree = \"<group>\"; };\n\t\t2D5A83031CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutJSONStorage.h; path = Spectacle/Sources/SpectacleShortcutJSONStorage.h; sourceTree = \"<group>\"; };\n\t\t2D5A83041CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutJSONStorage.m; path = Spectacle/Sources/SpectacleShortcutJSONStorage.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D5A83071CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleMigratingShortcutStorage.h; path = Spectacle/Sources/SpectacleMigratingShortcutStorage.h; sourceTree = \"<group>\"; };\n\t\t2D5A83081CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleMigratingShortcutStorage.m; path = Spectacle/Sources/SpectacleMigratingShortcutStorage.m; sourceTree = \"<group>\"; };\n\t\t2D5A830C1CDC363B00EBE80A /* SpectacleShortcutStorageMigrationDestination.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutStorageMigrationDestination.h; path = Spectacle/Sources/SpectacleShortcutStorageMigrationDestination.h; sourceTree = \"<group>\"; };\n\t\t2D5A830D1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleDefaultShortcutHelpers.h; path = Spectacle/Sources/SpectacleDefaultShortcutHelpers.h; sourceTree = \"<group>\"; };\n\t\t2D5A830E1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleDefaultShortcutHelpers.m; path = Spectacle/Sources/SpectacleDefaultShortcutHelpers.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D5CCCE815E96F740009CC43 /* dsa_public.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_public.pem; path = Spectacle/Resources/Certificates/dsa_public.pem; sourceTree = \"<group>\"; };\n\t\t2D7146521CCC12A6003B8292 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Carthage/Build/Mac/Sparkle.framework; sourceTree = \"<group>\"; };\n\t\t2D7146671CCC1715003B8292 /* Expecta.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Expecta.framework; path = ../Carthage/Build/Mac/Expecta.framework; sourceTree = \"<group>\"; };\n\t\t2D7146681CCC1715003B8292 /* OCHamcrest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCHamcrest.framework; path = ../Carthage/Build/Mac/OCHamcrest.framework; sourceTree = \"<group>\"; };\n\t\t2D7146691CCC1715003B8292 /* OCMockito.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMockito.framework; path = ../Carthage/Build/Mac/OCMockito.framework; sourceTree = \"<group>\"; };\n\t\t2D71466A1CCC1715003B8292 /* Specta.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Specta.framework; path = ../Carthage/Build/Mac/Specta.framework; sourceTree = \"<group>\"; };\n\t\t2D768E8B147ED51A00901E76 /* SpectacleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SpectacleAppDelegate.h; path = Spectacle/Sources/SpectacleAppDelegate.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t2D768E8C147ED51A00901E76 /* SpectacleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleAppDelegate.m; path = Spectacle/Sources/SpectacleAppDelegate.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2D7C11471B86C63A00B81E11 /* SpectacleShortcutStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutStorage.h; path = Spectacle/Sources/SpectacleShortcutStorage.h; sourceTree = \"<group>\"; };\n\t\t2D7C11481B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutUserDefaultsStorage.h; path = Spectacle/Sources/SpectacleShortcutUserDefaultsStorage.h; sourceTree = \"<group>\"; };\n\t\t2D7C11491B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleShortcutUserDefaultsStorage.m; path = Spectacle/Sources/SpectacleShortcutUserDefaultsStorage.m; sourceTree = \"<group>\"; };\n\t\t2D7CF9E91C6FED50004DC708 /* SpectacleWindowPositionCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleWindowPositionCalculator.h; path = Spectacle/Sources/SpectacleWindowPositionCalculator.h; sourceTree = \"<group>\"; };\n\t\t2D7CF9EA1C6FED50004DC708 /* SpectacleWindowPositionCalculator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleWindowPositionCalculator.m; path = Spectacle/Sources/SpectacleWindowPositionCalculator.m; sourceTree = \"<group>\"; };\n\t\t2D8E2C621C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleJavaScriptEnvironment.h; path = Spectacle/Sources/SpectacleJavaScriptEnvironment.h; sourceTree = \"<group>\"; };\n\t\t2D8E2C631C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleJavaScriptEnvironment.m; path = Spectacle/Sources/SpectacleJavaScriptEnvironment.m; sourceTree = \"<group>\"; };\n\t\t2D98D72C1ADDBBF6007AD995 /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = Spectacle/Resources/Localizations/fr.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t2D98D72D1ADDBBF6007AD995 /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = Spectacle/Resources/Localizations/fr.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\t2D98D72E1ADDBBF6007AD995 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = fr; path = Spectacle/Resources/Localizations/fr.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t2D98D72F1AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleWindowPositionCalculationResult.h; path = Spectacle/Sources/SpectacleWindowPositionCalculationResult.h; sourceTree = \"<group>\"; };\n\t\t2D98D7301AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleWindowPositionCalculationResult.m; path = Spectacle/Sources/SpectacleWindowPositionCalculationResult.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t2DA23EFB1B7D736100C9E8EF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Spectacle/Resources/Images.xcassets; sourceTree = \"<group>\"; };\n\t\t2DA23EFD1B80FB6400C9E8EF /* it */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = it; path = Spectacle/Resources/Localizations/it.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t2DA23EFE1B80FF6F00C9E8EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Spectacle/Resources/Localizations/Base.lproj/Spectacle.xib; sourceTree = \"<group>\"; };\n\t\t2DA23EFF1B80FF6F00C9E8EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Spectacle/Resources/Localizations/Base.lproj/SpectaclePreferencesWindow.xib; sourceTree = \"<group>\"; };\n\t\t2DA23F031B81016B00C9E8EF /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Spectacle/Resources/Localizations/fr.lproj/Spectacle.strings; sourceTree = \"<group>\"; };\n\t\t2DA23F051B81017000C9E8EF /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Spectacle/Resources/Localizations/fr.lproj/SpectaclePreferencesWindow.strings; sourceTree = \"<group>\"; };\n\t\t2DA23F071B8109D400C9E8EF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Spectacle/Resources/Localizations/it.lproj/Spectacle.strings; sourceTree = \"<group>\"; };\n\t\t2DA23F091B8109D900C9E8EF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Spectacle/Resources/Localizations/it.lproj/SpectaclePreferencesWindow.strings; sourceTree = \"<group>\"; };\n\t\t2DA5B7C619F8BA79007EDE8E /* SpectacleSpecs.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpectacleSpecs.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2DA5B7C919F8BA79007EDE8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = \"Supporting Files/Info.plist\"; sourceTree = \"<group>\"; };\n\t\t2DAC59E81BB234F500C660ED /* SpectacleWindowMover.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectacleWindowMover.h; path = Spectacle/Sources/SpectacleWindowMover.h; sourceTree = \"<group>\"; };\n\t\t2DAC59EE1BB238D900C660ED /* SpectacleQuantizedWindowMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleQuantizedWindowMover.h; path = Spectacle/Sources/SpectacleQuantizedWindowMover.h; sourceTree = \"<group>\"; };\n\t\t2DAC59EF1BB238D900C660ED /* SpectacleQuantizedWindowMover.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleQuantizedWindowMover.m; path = Spectacle/Sources/SpectacleQuantizedWindowMover.m; sourceTree = \"<group>\"; };\n\t\t2DAC59F11BB23BE200C660ED /* SpectacleBestEffortWindowMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleBestEffortWindowMover.h; path = Spectacle/Sources/SpectacleBestEffortWindowMover.h; sourceTree = \"<group>\"; };\n\t\t2DAC59F21BB23BE200C660ED /* SpectacleBestEffortWindowMover.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleBestEffortWindowMover.m; path = Spectacle/Sources/SpectacleBestEffortWindowMover.m; sourceTree = \"<group>\"; };\n\t\t2DAC59F51BB241DE00C660ED /* SpectacleWindowAction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectacleWindowAction.h; path = Spectacle/Sources/SpectacleWindowAction.h; sourceTree = \"<group>\"; };\n\t\t2DB075441CD041A5001CE204 /* SpectacleMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleMacros.h; path = Spectacle/Sources/SpectacleMacros.h; sourceTree = \"<group>\"; };\n\t\t2DC4E3CB1AD84E5C0022ABF0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = Spectacle/Resources/Localizations/en.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t2DC4E3CD1AD84E5C0022ABF0 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = Spectacle/Resources/Localizations/en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t2DC4E3CF1AD84E5C0022ABF0 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = Spectacle/Resources/Localizations/en.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\t2DC4E3D91AD84E7F0022ABF0 /* it */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = it; path = Spectacle/Resources/Localizations/it.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\t2DC4E3DA1AD84E7F0022ABF0 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = it; path = Spectacle/Resources/Localizations/it.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t2DC8A0151B85097900ABEBD5 /* SpectacleLoginItemHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleLoginItemHelper.h; path = Spectacle/Sources/SpectacleLoginItemHelper.h; sourceTree = \"<group>\"; };\n\t\t2DC8A0161B85097900ABEBD5 /* SpectacleLoginItemHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleLoginItemHelper.m; path = Spectacle/Sources/SpectacleLoginItemHelper.m; sourceTree = \"<group>\"; };\n\t\t2DE03E471D7B8F5A004E80D6 /* SpectacleShortcutKeyBindingsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectacleShortcutKeyBindingsSpec.m; path = Sources/SpectacleShortcutKeyBindingsSpec.m; sourceTree = \"<group>\"; };\n\t\t2DE03E491D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectacleShortcutKeyBindings.h; path = Spectacle/Sources/SpectacleShortcutKeyBindings.h; sourceTree = \"<group>\"; };\n\t\t2DE03E4A1D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = SpectacleShortcutKeyBindings.m; path = Spectacle/Sources/SpectacleShortcutKeyBindings.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t574F6A1A1C57BE40001A5679 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = Spectacle/Resources/Localizations/pt.lproj/Spectacle.strings; sourceTree = \"<group>\"; };\n\t\t574F6A1B1C57BE40001A5679 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = Spectacle/Resources/Localizations/pt.lproj/SpectaclePreferencesWindow.strings; sourceTree = \"<group>\"; };\n\t\t574F6A1C1C57BE40001A5679 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = pt; path = Spectacle/Resources/Localizations/pt.lproj/Credits.rtf; sourceTree = \"<group>\"; };\n\t\t574F6A1D1C57BE40001A5679 /* pt */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = pt; path = Spectacle/Resources/Localizations/pt.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t574F6A1E1C57BE40001A5679 /* pt */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = pt; path = Spectacle/Resources/Localizations/pt.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t2D1E1AAD147E06AD0021D73D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2DA5B7C319F8BA79007EDE8E /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D71466F1CCC171F003B8292 /* Expecta.framework in Frameworks */,\n\t\t\t\t2D7146701CCC171F003B8292 /* OCHamcrest.framework in Frameworks */,\n\t\t\t\t2D7146711CCC171F003B8292 /* OCMockito.framework in Frameworks */,\n\t\t\t\t2D7146721CCC171F003B8292 /* Specta.framework 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\t0747DAE81183AABB00F75DD2 /* Preferences */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2DC8A0151B85097900ABEBD5 /* SpectacleLoginItemHelper.h */,\n\t\t\t\t2DC8A0161B85097900ABEBD5 /* SpectacleLoginItemHelper.m */,\n\t\t\t\t07838601148BD517001E7BD7 /* SpectaclePreferencesController.h */,\n\t\t\t\t07838602148BD517001E7BD7 /* SpectaclePreferencesController.m */,\n\t\t\t);\n\t\t\tname = Preferences;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t0747DAE91183AAC100F75DD2 /* Accessibility API */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D3A04FC194956E100CD96E7 /* SpectacleAccessibilityElement.h */,\n\t\t\t\t2D3A04FD194956E100CD96E7 /* SpectacleAccessibilityElement.m */,\n\t\t\t);\n\t\t\tname = \"Accessibility API\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t0747DAEB1183AAE700F75DD2 /* Property Lists */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0706C0431191092B0068F04B /* Defaults.plist */,\n\t\t\t);\n\t\t\tname = \"Property Lists\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t089C166AFE841209C02AAC07 /* Spectacle */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D89B5731B8133E900F9FC1C /* Spectacle */,\n\t\t\t\t2DA5B7C719F8BA79007EDE8E /* SpectacleSpecs */,\n\t\t\t\t19C28FB8FE9D52D311CA2CBB /* Products */,\n\t\t\t);\n\t\t\tname = Spectacle;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t089C1671FE841209C02AAC07 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D7146521CCC12A6003B8292 /* Sparkle.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t089C167CFE841241C02AAC07 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D5CCCE715E96F4F0009CC43 /* Certificates */,\n\t\t\t\t0747DAEB1183AAE700F75DD2 /* Property Lists */,\n\t\t\t\t2DB2DC22181ECFCF0008A192 /* Scripts */,\n\t\t\t\t2DC4E3CA1AD84E5C0022ABF0 /* Credits.rtf */,\n\t\t\t\t2DA23EFB1B7D736100C9E8EF /* Images.xcassets */,\n\t\t\t\t2DC4E3CC1AD84E5C0022ABF0 /* InfoPlist.strings */,\n\t\t\t\t2DC4E3CE1AD84E5C0022ABF0 /* Localizable.strings */,\n\t\t\t\t2DC4E3D01AD84E5C0022ABF0 /* Spectacle.xib */,\n\t\t\t\t2DC4E3D21AD84E5C0022ABF0 /* SpectaclePreferencesWindow.xib */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t08FB77AFFE84173DC02AAC07 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0747DAE81183AABB00F75DD2 /* Preferences */,\n\t\t\t\t2DC8A0131B84E1AF00ABEBD5 /* Shortcuts */,\n\t\t\t\t2DC8A0141B84E24500ABEBD5 /* Window Management */,\n\t\t\t\t2D768E8B147ED51A00901E76 /* SpectacleAppDelegate.h */,\n\t\t\t\t2D768E8C147ED51A00901E76 /* SpectacleAppDelegate.m */,\n\t\t\t\t2DB075441CD041A5001CE204 /* SpectacleMacros.h */,\n\t\t\t\t07BB542B1186662F0045663F /* SpectacleUtilities.h */,\n\t\t\t\t07BB542C1186662F0045663F /* SpectacleUtilities.m */,\n\t\t\t);\n\t\t\tname = Sources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t19C28FB8FE9D52D311CA2CBB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D1E1AB0147E06AD0021D73D /* Spectacle.app */,\n\t\t\t\t2DA5B7C619F8BA79007EDE8E /* SpectacleSpecs.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D5CCCE715E96F4F0009CC43 /* Certificates */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D5CCCE815E96F740009CC43 /* dsa_public.pem */,\n\t\t\t);\n\t\t\tname = Certificates;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D7146611CCC1381003B8292 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D7146671CCC1715003B8292 /* Expecta.framework */,\n\t\t\t\t2D7146681CCC1715003B8292 /* OCHamcrest.framework */,\n\t\t\t\t2D7146691CCC1715003B8292 /* OCMockito.framework */,\n\t\t\t\t2D71466A1CCC1715003B8292 /* Specta.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D7C11441B86829300B81E11 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D20F0081CD18ED7003DDA5B /* SpectacleBottomHalfWindowCalculationSpec.m */,\n\t\t\t\t2D20F0091CD18ED7003DDA5B /* SpectacleCenterWindowCalculationSpec.m */,\n\t\t\t\t2D20F00A1CD18ED7003DDA5B /* SpectacleFullscreenWindowCalculationSpec.m */,\n\t\t\t\t2D20F00B1CD18ED7003DDA5B /* SpectacleLargerWindowCalculationSpec.m */,\n\t\t\t\t2D20F00C1CD18ED7003DDA5B /* SpectacleLeftHalfWindowCalculationSpec.m */,\n\t\t\t\t2D20F00D1CD18ED7003DDA5B /* SpectacleLowerLeftWindowCalculationSpec.m */,\n\t\t\t\t2D20F00E1CD18ED7003DDA5B /* SpectacleLowerRightWindowCalculationSpec.m */,\n\t\t\t\t2D20F00F1CD18ED7003DDA5B /* SpectacleNextDisplayWindowCalculationSpec.m */,\n\t\t\t\t2D20F0101CD18ED7003DDA5B /* SpectacleNextThirdWindowCalculationSpec.m */,\n\t\t\t\t2D20F0111CD18ED7003DDA5B /* SpectaclePreviousDisplayWindowCalculationSpec.m */,\n\t\t\t\t2D20F0121CD18ED7003DDA5B /* SpectaclePreviousThirdWindowCalculationSpec.m */,\n\t\t\t\t2D20F0131CD18ED7003DDA5B /* SpectacleRightHalfWindowCalculationSpec.m */,\n\t\t\t\t2DE03E471D7B8F5A004E80D6 /* SpectacleShortcutKeyBindingsSpec.m */,\n\t\t\t\t2D58AE351D7D2D5300BFEEA2 /* SpectacleShortcutSpec.m */,\n\t\t\t\t2D58AE331D7D19AF00BFEEA2 /* SpectacleShortcutTranslationsSpec.m */,\n\t\t\t\t2D20F0141CD18ED7003DDA5B /* SpectacleSmallerWindowCalculationSpec.m */,\n\t\t\t\t2D20F0151CD18ED7003DDA5B /* SpectacleTopHalfWindowCalculationSpec.m */,\n\t\t\t\t2D20F0161CD18ED7003DDA5B /* SpectacleUpperLeftWindowCalculationSpec.m */,\n\t\t\t\t2D20F0171CD18ED7003DDA5B /* SpectacleUpperRightWindowCalculationSpec.m */,\n\t\t\t\t2D20F0281CD1969D003DDA5B /* SpectacleWindowPositionManagerSpec.m */,\n\t\t\t);\n\t\t\tname = Sources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D7C11461B86C61800B81E11 /* Shortcut Storage */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D5A83071CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.h */,\n\t\t\t\t2D5A83081CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.m */,\n\t\t\t\t2D7C11471B86C63A00B81E11 /* SpectacleShortcutStorage.h */,\n\t\t\t\t2D5A830C1CDC363B00EBE80A /* SpectacleShortcutStorageMigrationDestination.h */,\n\t\t\t\t2D5A83031CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.h */,\n\t\t\t\t2D5A83041CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.m */,\n\t\t\t\t2D7C11481B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.h */,\n\t\t\t\t2D7C11491B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.m */,\n\t\t\t);\n\t\t\tname = \"Shortcut Storage\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D7CF9E81C6FEC2E004DC708 /* Window Position Calculator */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D58CC381C7030B800E3DC74 /* Window Position Calculations */,\n\t\t\t\t2D8E2C621C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.h */,\n\t\t\t\t2D8E2C631C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.m */,\n\t\t\t\t2D98D72F1AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.h */,\n\t\t\t\t2D98D7301AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.m */,\n\t\t\t\t2D7CF9E91C6FED50004DC708 /* SpectacleWindowPositionCalculator.h */,\n\t\t\t\t2D7CF9EA1C6FED50004DC708 /* SpectacleWindowPositionCalculator.m */,\n\t\t\t\t2D0759A51C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.h */,\n\t\t\t\t2D0759A61C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.m */,\n\t\t\t);\n\t\t\tname = \"Window Position Calculator\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D89B5731B8133E900F9FC1C /* Spectacle */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t089C167CFE841241C02AAC07 /* Resources */,\n\t\t\t\t08FB77AFFE84173DC02AAC07 /* Sources */,\n\t\t\t\t32DBCFA10370C40200C91783 /* Supporting Files */,\n\t\t\t\t089C1671FE841209C02AAC07 /* Frameworks */,\n\t\t\t);\n\t\t\tname = Spectacle;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D89B5741B81340B00F9FC1C /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2DA5B7C919F8BA79007EDE8E /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DA5B7C719F8BA79007EDE8E /* SpectacleSpecs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D7C11441B86829300B81E11 /* Sources */,\n\t\t\t\t2D89B5741B81340B00F9FC1C /* Supporting Files */,\n\t\t\t\t2D7146611CCC1381003B8292 /* Frameworks */,\n\t\t\t);\n\t\t\tpath = SpectacleSpecs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DAC59EA1BB2364700C660ED /* Window Movement History */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D279ED216BB4A7800F6894A /* SpectacleHistory.h */,\n\t\t\t\t2D279ED316BB4A7800F6894A /* SpectacleHistory.m */,\n\t\t\t\t079CDA0D1221BAFF0099612C /* SpectacleHistoryItem.h */,\n\t\t\t\t079CDA0E1221BAFF0099612C /* SpectacleHistoryItem.m */,\n\t\t\t);\n\t\t\tname = \"Window Movement History\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DAC59F41BB23DAD00C660ED /* Window Movers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2DAC59F11BB23BE200C660ED /* SpectacleBestEffortWindowMover.h */,\n\t\t\t\t2DAC59F21BB23BE200C660ED /* SpectacleBestEffortWindowMover.m */,\n\t\t\t\t2DAC59EE1BB238D900C660ED /* SpectacleQuantizedWindowMover.h */,\n\t\t\t\t2DAC59EF1BB238D900C660ED /* SpectacleQuantizedWindowMover.m */,\n\t\t\t\t2D5783EF1BB63BDD00695771 /* SpectacleStandardWindowMover.h */,\n\t\t\t\t2D5783F01BB63BDD00695771 /* SpectacleStandardWindowMover.m */,\n\t\t\t\t2DAC59E81BB234F500C660ED /* SpectacleWindowMover.h */,\n\t\t\t);\n\t\t\tname = \"Window Movers\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DB2DC22181ECFCF0008A192 /* Scripts */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D5565B0181EDB7F00EFB43A /* Security & Privacy System Preferences.scpt */,\n\t\t\t);\n\t\t\tname = Scripts;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC8A0111B84E17400ABEBD5 /* Shortcut Management */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t07678095118679C600614FB5 /* SpectacleShortcutManager.h */,\n\t\t\t\t07678096118679C600614FB5 /* SpectacleShortcutManager.m */,\n\t\t\t\t2D1AE52315D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.h */,\n\t\t\t\t2D1AE52415D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.m */,\n\t\t\t);\n\t\t\tname = \"Shortcut Management\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC8A0121B84E18400ABEBD5 /* Shortcut Recorder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D3A0501194956E100CD96E7 /* SpectacleShortcutRecorder.h */,\n\t\t\t\t2D3A0502194956E100CD96E7 /* SpectacleShortcutRecorder.m */,\n\t\t\t\t2D3A0505194956E100CD96E7 /* SpectacleShortcutRecorderDelegate.h */,\n\t\t\t);\n\t\t\tname = \"Shortcut Recorder\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC8A0131B84E1AF00ABEBD5 /* Shortcuts */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2DC8A0111B84E17400ABEBD5 /* Shortcut Management */,\n\t\t\t\t2DC8A0121B84E18400ABEBD5 /* Shortcut Recorder */,\n\t\t\t\t2D7C11461B86C61800B81E11 /* Shortcut Storage */,\n\t\t\t\t2D5A830D1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.h */,\n\t\t\t\t2D5A830E1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.m */,\n\t\t\t\t2D3A04FF194956E100CD96E7 /* SpectacleShortcut.h */,\n\t\t\t\t2D3A0500194956E100CD96E7 /* SpectacleShortcut.m */,\n\t\t\t\t2D24ACB51CC8728E00AB3984 /* SpectacleShortcutHolder.h */,\n\t\t\t\t2D24ACB61CC8728E00AB3984 /* SpectacleShortcutHolder.m */,\n\t\t\t\t2DE03E491D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.h */,\n\t\t\t\t2DE03E4A1D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.m */,\n\t\t\t\t2D3A0506194956E100CD96E7 /* SpectacleShortcutTranslations.h */,\n\t\t\t\t2D3A0507194956E100CD96E7 /* SpectacleShortcutTranslations.m */,\n\t\t\t\t2D3A050A194956E100CD96E7 /* SpectacleShortcutValidator.h */,\n\t\t\t\t2D3A0508194956E100CD96E7 /* SpectacleShortcutValidation.h */,\n\t\t\t\t2D3A0509194956E100CD96E7 /* SpectacleShortcutValidation.m */,\n\t\t\t);\n\t\t\tname = Shortcuts;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC8A0141B84E24500ABEBD5 /* Window Management */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0747DAE91183AAC100F75DD2 /* Accessibility API */,\n\t\t\t\t2DAC59EA1BB2364700C660ED /* Window Movement History */,\n\t\t\t\t2DAC59F41BB23DAD00C660ED /* Window Movers */,\n\t\t\t\t2D7CF9E81C6FEC2E004DC708 /* Window Position Calculator */,\n\t\t\t\t2D2629441CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.h */,\n\t\t\t\t2D2629451CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.m */,\n\t\t\t\t2D4F3ECE14A27B4500C29D11 /* SpectacleScreenDetector.h */,\n\t\t\t\t2D4F3ECF14A27B4500C29D11 /* SpectacleScreenDetector.m */,\n\t\t\t\t2DAC59F51BB241DE00C660ED /* SpectacleWindowAction.h */,\n\t\t\t\t2D24ACB31CC723F600AB3984 /* SpectacleWindowAction.m */,\n\t\t\t\t072EACFE118A4D5A0015FC8A /* SpectacleWindowPositionManager.h */,\n\t\t\t\t072EACFF118A4D5A0015FC8A /* SpectacleWindowPositionManager.m */,\n\t\t\t);\n\t\t\tname = \"Window Management\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t32DBCFA10370C40200C91783 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D1E1AD2147E07E50021D73D /* Info.plist */,\n\t\t\t\t077938E51184FADB0013BC14 /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t2D1E1AAF147E06AD0021D73D /* Spectacle */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D1E1ACB147E06AD0021D73D /* Build configuration list for PBXNativeTarget \"Spectacle\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2D1E1AAC147E06AD0021D73D /* Sources */,\n\t\t\t\t2D1E1AAD147E06AD0021D73D /* Frameworks */,\n\t\t\t\t2D1E1AAE147E06AD0021D73D /* Resources */,\n\t\t\t\t2DC25F9D19FF3F93009591A9 /* Update CFBundleVersion */,\n\t\t\t\t2D7146551CCC12A6003B8292 /* Embed Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Spectacle;\n\t\t\tproductName = Spectacle;\n\t\t\tproductReference = 2D1E1AB0147E06AD0021D73D /* Spectacle.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2DA5B7C519F8BA79007EDE8E /* SpectacleSpecs */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2DA5B7D019F8BA79007EDE8E /* Build configuration list for PBXNativeTarget \"SpectacleSpecs\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2DA5B7C219F8BA79007EDE8E /* Sources */,\n\t\t\t\t2DA5B7C319F8BA79007EDE8E /* Frameworks */,\n\t\t\t\t2DA5B7C419F8BA79007EDE8E /* Resources */,\n\t\t\t\t2D7146661CCC16FD003B8292 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t2DA5B7CD19F8BA79007EDE8E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = SpectacleSpecs;\n\t\t\tproductName = SpectacleSpecs;\n\t\t\tproductReference = 2DA5B7C619F8BA79007EDE8E /* SpectacleSpecs.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t089C1669FE841209C02AAC07 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1120;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t2DA5B7C519F8BA79007EDE8E = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 6.1;\n\t\t\t\t\t\tTestTargetID = 2D1E1AAF147E06AD0021D73D;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 1DBD214C08BA80EA00186707 /* Build configuration list for PBXProject \"Spectacle\" */;\n\t\t\tcompatibilityVersion = \"Xcode 6.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 1;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tit,\n\t\t\t\tfr,\n\t\t\t\tBase,\n\t\t\t\tpt,\n\t\t\t\tfi,\n\t\t\t\tes,\n\t\t\t);\n\t\t\tmainGroup = 089C166AFE841209C02AAC07 /* Spectacle */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t2D1E1AAF147E06AD0021D73D /* Spectacle */,\n\t\t\t\t2DA5B7C519F8BA79007EDE8E /* SpectacleSpecs */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t2D1E1AAE147E06AD0021D73D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2DC4E3D41AD84E5C0022ABF0 /* Credits.rtf in Resources */,\n\t\t\t\t2D8DA04D147E0FA0003BE1D3 /* Defaults.plist in Resources */,\n\t\t\t\t2D5CCCE915E96F740009CC43 /* dsa_public.pem in Resources */,\n\t\t\t\t2DA23EFC1B7D736100C9E8EF /* Images.xcassets in Resources */,\n\t\t\t\t2DC4E3D51AD84E5C0022ABF0 /* InfoPlist.strings in Resources */,\n\t\t\t\t2DC4E3D61AD84E5C0022ABF0 /* Localizable.strings in Resources */,\n\t\t\t\t2D5565B1181EDB7F00EFB43A /* Security & Privacy System Preferences.scpt in Resources */,\n\t\t\t\t2D7752101B83E94C00C022EE /* Spectacle.xib in Resources */,\n\t\t\t\t2D7752111B83E95000C022EE /* SpectaclePreferencesWindow.xib in Resources */,\n\t\t\t\t2D58CC391C7030B800E3DC74 /* Window Position Calculations in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2DA5B7C419F8BA79007EDE8E /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t2DC25F9D19FF3F93009591A9 /* Update CFBundleVersion */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Update CFBundleVersion\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"# See: http://tgoode.com/2014/06/05/sensible-way-increment-bundle-version-cfbundleversion-xcode/\\nbranch=${1:-'master'}\\nbuild_number=$(expr $(git rev-list $branch --count) - $(git rev-list HEAD...$branch --count))\\necho \\\"Updating build number to $build_number using branch: $branch\\\"\\n/usr/libexec/PlistBuddy -c \\\"Set :CFBundleVersion $build_number\\\" \\\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\\\"\\n\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t2D1E1AAC147E06AD0021D73D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D8DA05E147E113D003BE1D3 /* main.m in Sources */,\n\t\t\t\t2D3A050D194956E100CD96E7 /* SpectacleAccessibilityElement.m in Sources */,\n\t\t\t\t2D768E8D147ED51A00901E76 /* SpectacleAppDelegate.m in Sources */,\n\t\t\t\t2DAC59F31BB23BE200C660ED /* SpectacleBestEffortWindowMover.m in Sources */,\n\t\t\t\t2D5A830F1CDC475B00EBE80A /* SpectacleDefaultShortcutHelpers.m in Sources */,\n\t\t\t\t2D279ED416BB4A7800F6894A /* SpectacleHistory.m in Sources */,\n\t\t\t\t2D8DA05D147E113D003BE1D3 /* SpectacleHistoryItem.m in Sources */,\n\t\t\t\t2D8E2C641C7AAD5A0074129C /* SpectacleJavaScriptEnvironment.m in Sources */,\n\t\t\t\t2DC8A0171B85097900ABEBD5 /* SpectacleLoginItemHelper.m in Sources */,\n\t\t\t\t2D5A83091CDB020A00EBE80A /* SpectacleMigratingShortcutStorage.m in Sources */,\n\t\t\t\t07838603148BD517001E7BD7 /* SpectaclePreferencesController.m in Sources */,\n\t\t\t\t2DAC59F01BB238D900C660ED /* SpectacleQuantizedWindowMover.m in Sources */,\n\t\t\t\t2D1AE52515D715F400EAC5BD /* SpectacleRegisteredShortcutValidator.m in Sources */,\n\t\t\t\t2D2629461CCECB9E009D1ED0 /* SpectacleScreenDetectionResult.m in Sources */,\n\t\t\t\t2D4F3ED014A27B4500C29D11 /* SpectacleScreenDetector.m in Sources */,\n\t\t\t\t2D3A050E194956E100CD96E7 /* SpectacleShortcut.m in Sources */,\n\t\t\t\t2D24ACB71CC8728E00AB3984 /* SpectacleShortcutHolder.m in Sources */,\n\t\t\t\t2D5A83051CDAFDEB00EBE80A /* SpectacleShortcutJSONStorage.m in Sources */,\n\t\t\t\t2DE03E4B1D7B98D6004E80D6 /* SpectacleShortcutKeyBindings.m in Sources */,\n\t\t\t\t2D8DA056147E113D003BE1D3 /* SpectacleShortcutManager.m in Sources */,\n\t\t\t\t2D3A050F194956E100CD96E7 /* SpectacleShortcutRecorder.m in Sources */,\n\t\t\t\t2D3A0511194956E100CD96E7 /* SpectacleShortcutTranslations.m in Sources */,\n\t\t\t\t2D7C114A1B86C7CD00B81E11 /* SpectacleShortcutUserDefaultsStorage.m in Sources */,\n\t\t\t\t2D3A0512194956E100CD96E7 /* SpectacleShortcutValidation.m in Sources */,\n\t\t\t\t2D5783F11BB63BDD00695771 /* SpectacleStandardWindowMover.m in Sources */,\n\t\t\t\t2D8DA057147E113D003BE1D3 /* SpectacleUtilities.m in Sources */,\n\t\t\t\t2D24ACB41CC723F600AB3984 /* SpectacleWindowAction.m in Sources */,\n\t\t\t\t2D0759A71C71746500A17E80 /* SpectacleWindowPositionCalculationRegistry.m in Sources */,\n\t\t\t\t2D98D7311AE064B7007AD995 /* SpectacleWindowPositionCalculationResult.m in Sources */,\n\t\t\t\t2D7CF9EB1C6FED50004DC708 /* SpectacleWindowPositionCalculator.m in Sources */,\n\t\t\t\t2D8DA058147E113D003BE1D3 /* SpectacleWindowPositionManager.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2DA5B7C219F8BA79007EDE8E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D20F0181CD18ED7003DDA5B /* SpectacleBottomHalfWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0191CD18ED7003DDA5B /* SpectacleCenterWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01A1CD18ED7003DDA5B /* SpectacleFullscreenWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01B1CD18ED7003DDA5B /* SpectacleLargerWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01C1CD18ED7003DDA5B /* SpectacleLeftHalfWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01D1CD18ED7003DDA5B /* SpectacleLowerLeftWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01E1CD18ED7003DDA5B /* SpectacleLowerRightWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F01F1CD18ED7003DDA5B /* SpectacleNextDisplayWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0201CD18ED7003DDA5B /* SpectacleNextThirdWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0211CD18ED7003DDA5B /* SpectaclePreviousDisplayWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0221CD18ED7003DDA5B /* SpectaclePreviousThirdWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0231CD18ED7003DDA5B /* SpectacleRightHalfWindowCalculationSpec.m in Sources */,\n\t\t\t\t2DE03E481D7B8F5A004E80D6 /* SpectacleShortcutKeyBindingsSpec.m in Sources */,\n\t\t\t\t2D58AE361D7D2D5300BFEEA2 /* SpectacleShortcutSpec.m in Sources */,\n\t\t\t\t2D58AE341D7D19AF00BFEEA2 /* SpectacleShortcutTranslationsSpec.m in Sources */,\n\t\t\t\t2D20F0241CD18ED7003DDA5B /* SpectacleSmallerWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0251CD18ED7003DDA5B /* SpectacleTopHalfWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0261CD18ED7003DDA5B /* SpectacleUpperLeftWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0271CD18ED7003DDA5B /* SpectacleUpperRightWindowCalculationSpec.m in Sources */,\n\t\t\t\t2D20F0291CD1969D003DDA5B /* SpectacleWindowPositionManagerSpec.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t2DA5B7CD19F8BA79007EDE8E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 2D1E1AAF147E06AD0021D73D /* Spectacle */;\n\t\t\ttargetProxy = 2DA5B7CC19F8BA79007EDE8E /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t2DC4E3CA1AD84E5C0022ABF0 /* Credits.rtf */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t2DC4E3CB1AD84E5C0022ABF0 /* en */,\n\t\t\t\t2D98D72E1ADDBBF6007AD995 /* fr */,\n\t\t\t\t2DC4E3DA1AD84E7F0022ABF0 /* it */,\n\t\t\t\t574F6A1C1C57BE40001A5679 /* pt */,\n\t\t\t\t2D2490E11C7A5BD900A4282B /* fi */,\n\t\t\t\t2D2A61A51DC2CD9C00D86193 /* es */,\n\t\t\t);\n\t\t\tname = Credits.rtf;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC4E3CC1AD84E5C0022ABF0 /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t2DC4E3CD1AD84E5C0022ABF0 /* en */,\n\t\t\t\t2D98D72C1ADDBBF6007AD995 /* fr */,\n\t\t\t\t2DA23EFD1B80FB6400C9E8EF /* it */,\n\t\t\t\t574F6A1D1C57BE40001A5679 /* pt */,\n\t\t\t\t2D2490E21C7A5BD900A4282B /* fi */,\n\t\t\t\t2D2A61A61DC2CD9C00D86193 /* es */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC4E3CE1AD84E5C0022ABF0 /* Localizable.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t2DC4E3CF1AD84E5C0022ABF0 /* en */,\n\t\t\t\t2D98D72D1ADDBBF6007AD995 /* fr */,\n\t\t\t\t2DC4E3D91AD84E7F0022ABF0 /* it */,\n\t\t\t\t574F6A1E1C57BE40001A5679 /* pt */,\n\t\t\t\t2D2490E31C7A5BD900A4282B /* fi */,\n\t\t\t\t2D2A61A71DC2CD9C00D86193 /* es */,\n\t\t\t);\n\t\t\tname = Localizable.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC4E3D01AD84E5C0022ABF0 /* Spectacle.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t2DA23EFE1B80FF6F00C9E8EF /* Base */,\n\t\t\t\t2DA23F031B81016B00C9E8EF /* fr */,\n\t\t\t\t2DA23F071B8109D400C9E8EF /* it */,\n\t\t\t\t574F6A1A1C57BE40001A5679 /* pt */,\n\t\t\t\t2D2490DF1C7A5BD900A4282B /* fi */,\n\t\t\t\t2D2A61A31DC2CD9C00D86193 /* es */,\n\t\t\t);\n\t\t\tname = Spectacle.xib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2DC4E3D21AD84E5C0022ABF0 /* SpectaclePreferencesWindow.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t2DA23EFF1B80FF6F00C9E8EF /* Base */,\n\t\t\t\t2DA23F051B81017000C9E8EF /* fr */,\n\t\t\t\t2DA23F091B8109D900C9E8EF /* it */,\n\t\t\t\t574F6A1B1C57BE40001A5679 /* pt */,\n\t\t\t\t2D2490E01C7A5BD900A4282B /* fi */,\n\t\t\t\t2D2A61A41DC2CD9C00D86193 /* es */,\n\t\t\t);\n\t\t\tname = SpectaclePreferencesWindow.xib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t1DBD214D08BA80EA00186707 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_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_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_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 = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_TREAT_WARNINGS_AS_ERRORS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.9;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t1DBD214E08BA80EA00186707 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_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_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_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 = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_TREAT_WARNINGS_AS_ERRORS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.9;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2D1E1ACC147E06AD0021D73D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = Spectacle;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Carthage/Build/Mac\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"Spectacle/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.divisiblebyzero.Spectacle;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D1E1ACD147E06AD0021D73D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = Spectacle;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Carthage/Build/Mac\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"Spectacle/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.divisiblebyzero.Spectacle;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2DA5B7CE19F8BA79007EDE8E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(BUILT_PRODUCTS_DIR)/Spectacle.app/Contents/MacOS/Spectacle\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(DEVELOPER_FRAMEWORKS_DIR)\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Carthage/Build/Mac\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"SpectacleSpecs/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.divisiblebyzero.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUNDLE_LOADER)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2DA5B7CF19F8BA79007EDE8E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(BUILT_PRODUCTS_DIR)/Spectacle.app/Contents/MacOS/Spectacle\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(DEVELOPER_FRAMEWORKS_DIR)\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Carthage/Build/Mac\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"SpectacleSpecs/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.divisiblebyzero.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUNDLE_LOADER)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t1DBD214C08BA80EA00186707 /* Build configuration list for PBXProject \"Spectacle\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t1DBD214D08BA80EA00186707 /* Debug */,\n\t\t\t\t1DBD214E08BA80EA00186707 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2D1E1ACB147E06AD0021D73D /* Build configuration list for PBXNativeTarget \"Spectacle\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D1E1ACC147E06AD0021D73D /* Debug */,\n\t\t\t\t2D1E1ACD147E06AD0021D73D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2DA5B7D019F8BA79007EDE8E /* Build configuration list for PBXNativeTarget \"SpectacleSpecs\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2DA5B7CE19F8BA79007EDE8E /* Debug */,\n\t\t\t\t2DA5B7CF19F8BA79007EDE8E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 089C1669FE841209C02AAC07 /* Project object */;\n}\n"
  },
  {
    "path": "Spectacle.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:Spectacle.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Spectacle.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": "Spectacle.xcodeproj/xcshareddata/xcschemes/Spectacle.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1120\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D1E1AAF147E06AD0021D73D\"\n               BuildableName = \"Spectacle.app\"\n               BlueprintName = \"Spectacle\"\n               ReferencedContainer = \"container:Spectacle.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2DA5B7C519F8BA79007EDE8E\"\n               BuildableName = \"SpectacleSpecs.xctest\"\n               BlueprintName = \"SpectacleSpecs\"\n               ReferencedContainer = \"container:Spectacle.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D1E1AAF147E06AD0021D73D\"\n            BuildableName = \"Spectacle.app\"\n            BlueprintName = \"Spectacle\"\n            ReferencedContainer = \"container:Spectacle.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2DA5B7C519F8BA79007EDE8E\"\n               BuildableName = \"SpectacleSpecs.xctest\"\n               BlueprintName = \"SpectacleSpecs\"\n               ReferencedContainer = \"container:Spectacle.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D1E1AAF147E06AD0021D73D\"\n            BuildableName = \"Spectacle.app\"\n            BlueprintName = \"Spectacle\"\n            ReferencedContainer = \"container:Spectacle.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D1E1AAF147E06AD0021D73D\"\n            BuildableName = \"Spectacle.app\"\n            BlueprintName = \"Spectacle\"\n            ReferencedContainer = \"container:Spectacle.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleBottomHalfWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleBottomHalfWindowCalculation)\ndescribe(@\"SpectacleBottomHalfWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the bottom half of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionBottomHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the bottom 2/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 1440.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionBottomHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 582.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the bottom 1/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 1440.0f, 582.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionBottomHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 291.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleCenterWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleCenterWindowCalculation)\ndescribe(@\"SpectacleCenterWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a centered window's CGRect\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionCenter];\n    expect(result.windowRect).to.equal(CGRectMake(438.0f, 249.0f, 564.0f, 384.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleFullscreenWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleFullscreenWindowCalculation)\ndescribe(@\"SpectacleFullscreenWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a fullscreen window's CGRect\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionFullscreen];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleLargerWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleLargerWindowCalculation)\ndescribe(@\"SpectacleLargerWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's larger CGRect when centered in the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(360.0f, 222.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(345.0f, 207.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(345.0f, 207.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(330.0f, 192.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(330.0f, 192.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(315.0f, 177.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the top edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(402.0f, 441.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(387.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(387.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(372.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(372.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(357.0f, 351.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the bottom edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(238.0f, 4.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(223.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(223.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(208.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(208.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(193.0f, 4.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the left edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 250.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 235.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 235.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 220.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 220.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 205.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the right edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(720.0f, 303.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 288.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 288.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 273.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 273.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(630.0f, 258.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the top and left edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 441.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 351.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the top and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(720.0f, 441.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(630.0f, 351.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the bottom and left edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 3.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the bottom and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(720.0f, 4.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(630.0f, 4.0f, 810.0f, 526.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the top and bottom edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(344.0f, 4.0f, 720.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(329.0f, 4.0f, 750.0f, 873.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(329.0f, 4.0f, 750.0f, 873.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(314.0f, 4.0f, 780.0f, 873.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(314.0f, 4.0f, 780.0f, 873.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(299.0f, 4.0f, 810.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's larger CGRect when against the left and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 285.0f, 1436.0f, 446.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 270.0f, 1440.0f, 476.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 270.0f, 1440.0f, 476.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 255.0f, 1440.0f, 506.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 255.0f, 1440.0f, 506.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionLarger];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 240.0f, 1440.0f, 536.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleLeftHalfWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleLeftHalfWindowCalculation)\ndescribe(@\"SpectacleLeftHalfWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the left half of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLeftHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 720.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the left 2/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 720.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLeftHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 960.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the left 1/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 960.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLeftHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 480.0f, 873.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleLowerLeftWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleLowerLeftWindowCalculation)\ndescribe(@\"SpectacleLowerLeftWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the lower left corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLowerLeft];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 720.0f, 436.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleLowerRightWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleLowerRightWindowCalculation)\ndescribe(@\"SpectacleLowerRightWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the lower right corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionLowerRight];\n\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 4.0f, 720.0f, 436.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleNextDisplayWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleNextDisplayWindowCalculation)\ndescribe(@\"SpectacleNextDisplayWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(1440.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a centered window's CGRect in the next display\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextDisplay];\n    expect(result.windowRect).to.equal(CGRectMake(1878.0f, 249.0f, 564.0f, 384.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleNextThirdWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleNextThirdWindowCalculation)\ndescribe(@\"SpectacleNextThirdWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the first horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 480.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the second horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 480.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n    expect(result.windowRect).to.equal(CGRectMake(480.0f, 4.0f, 480.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the last horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(480.0f, 4.0f, 480.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n    expect(result.windowRect).to.equal(CGRectMake(960.0f, 4.0f, 480.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the first vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(960.0f, 4.0f, 480.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 586.0f, 1440.0f, 291.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the second vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 586.0f, 1440.0f, 291.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 295.0f, 1440.0f, 291.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the last vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 295.0f, 1440.0f, 291.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionNextThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 291.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectaclePreviousDisplayWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectaclePreviousDisplayWindowCalculation)\ndescribe(@\"SpectaclePreviousDisplayWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(1440.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a centered window's CGRect in the previous display\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousDisplay];\n    expect(result.windowRect).to.equal(CGRectMake(1878.0f, 249.0f, 564.0f, 384.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectaclePreviousThirdWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectaclePreviousThirdWindowCalculation)\ndescribe(@\"SpectaclePreviousThirdWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the first horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 480.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the last vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 480.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 1440.0f, 291.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the second vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 1440.0f, 291.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 295.0f, 1440.0f, 291.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the first vertical third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 295.0f, 1440.0f, 291.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 586.0f, 1440.0f, 291.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the last horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 586.0f, 1440.0f, 291.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(960.0f, 4.0f, 480.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the second horizontal third of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(960.0f, 4.0f, 480.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionPreviousThird];\n    expect(result.windowRect).to.equal(CGRectMake(480.0f, 4.0f, 480.0f, 873.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleRightHalfWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleRightHalfWindowCalculation)\ndescribe(@\"SpectacleRightHalfWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the right half of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionRightHalf];\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 4.0f, 720.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the right 2/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(720.0f, 4.0f, 720.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionRightHalf];\n    expect(result.windowRect).to.equal(CGRectMake(480.0f, 4.0f, 960.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the right 1/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(480.0f, 4.0f, 960.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionRightHalf];\n    expect(result.windowRect).to.equal(CGRectMake(960.0f, 4.0f, 480.0f, 873.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleShortcutKeyBindingsSpec.m",
    "content": "#import <Carbon/Carbon.h>\n#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutKeyBindings.h\"\n\nstatic SpectacleShortcut *shortcutForKeyBinding(NSString *keyBinding);\n\nSpecBegin(SpectacleShortcutKeyBindings)\ndescribe(@\"SpectacleShortcutKeyBindings\", ^{\n  it(@\"should convert an empty or nil key binding to nil modifiers\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(nil)).to.equal(nil);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"\")).to.equal(nil);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\" \")).to.equal(nil);\n  });\n\n  it(@\"should convert key bindings to modifiers\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"cmd+c\")).to.equal(cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"shift+cmd+c\")).to.equal(shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"alt+shift+cmd+c\")).to.equal(optionKey | shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"ctrl+alt+shift+cmd+c\")).to.equal(controlKey | optionKey | shiftKey | cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"command+c\")).to.equal(cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"shift+command+c\")).to.equal(shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"option+shift+command+c\")).to.equal(optionKey | shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"control+option+shift+command+c\")).to.equal(controlKey | optionKey | shiftKey | cmdKey);\n  });\n\n  it(@\"should convert mixed case key bindings to modifiers\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"Cmd+C\")).to.equal(cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"Shift+Cmd+C\")).to.equal(shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"Alt+Shift+Cmd+C\")).to.equal(optionKey | shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"Ctrl+Alt+Shift+Cmd+C\")).to.equal(controlKey | optionKey | shiftKey | cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"COMMAND+C\")).to.equal(cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"SHIFT+COMMAND+C\")).to.equal(shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"OPTION+SHIFT+COMMAND+C\")).to.equal(optionKey | shiftKey |cmdKey);\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\"CONTROL+OPTION+SHIFT+COMMAND+C\")).to.equal(controlKey | optionKey | shiftKey | cmdKey);\n  });\n\n  it(@\"should convert key bindings with whitespace to modifiers\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToModifiers(@\" alt  +   shift    +     cmd    +c\")).to.equal(optionKey | shiftKey |cmdKey);\n  });\n\n  it(@\"should convert an empty or nil key binding to nil key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(nil)).to.equal(nil);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"\")).to.equal(nil);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\" \")).to.equal(nil);\n  });\n\n  it(@\"should convert lowercase alphabetical key bindings to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"a\")).to.equal(kVK_ANSI_A);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"b\")).to.equal(kVK_ANSI_B);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"c\")).to.equal(kVK_ANSI_C);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"d\")).to.equal(kVK_ANSI_D);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"e\")).to.equal(kVK_ANSI_E);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f\")).to.equal(kVK_ANSI_F);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"g\")).to.equal(kVK_ANSI_G);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"h\")).to.equal(kVK_ANSI_H);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"i\")).to.equal(kVK_ANSI_I);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"j\")).to.equal(kVK_ANSI_J);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"k\")).to.equal(kVK_ANSI_K);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"l\")).to.equal(kVK_ANSI_L);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"m\")).to.equal(kVK_ANSI_M);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"n\")).to.equal(kVK_ANSI_N);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"o\")).to.equal(kVK_ANSI_O);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"p\")).to.equal(kVK_ANSI_P);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"q\")).to.equal(kVK_ANSI_Q);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"r\")).to.equal(kVK_ANSI_R);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"s\")).to.equal(kVK_ANSI_S);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"t\")).to.equal(kVK_ANSI_T);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"u\")).to.equal(kVK_ANSI_U);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"v\")).to.equal(kVK_ANSI_V);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"w\")).to.equal(kVK_ANSI_W);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"x\")).to.equal(kVK_ANSI_X);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"y\")).to.equal(kVK_ANSI_Y);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"z\")).to.equal(kVK_ANSI_Z);\n  });\n\n  it(@\"should convert uppercase alphabetical key bindings to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"A\")).to.equal(kVK_ANSI_A);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"B\")).to.equal(kVK_ANSI_B);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"C\")).to.equal(kVK_ANSI_C);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"D\")).to.equal(kVK_ANSI_D);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"E\")).to.equal(kVK_ANSI_E);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F\")).to.equal(kVK_ANSI_F);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"G\")).to.equal(kVK_ANSI_G);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"H\")).to.equal(kVK_ANSI_H);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"I\")).to.equal(kVK_ANSI_I);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"J\")).to.equal(kVK_ANSI_J);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"K\")).to.equal(kVK_ANSI_K);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"L\")).to.equal(kVK_ANSI_L);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"M\")).to.equal(kVK_ANSI_M);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"N\")).to.equal(kVK_ANSI_N);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"O\")).to.equal(kVK_ANSI_O);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"P\")).to.equal(kVK_ANSI_P);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Q\")).to.equal(kVK_ANSI_Q);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"R\")).to.equal(kVK_ANSI_R);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"S\")).to.equal(kVK_ANSI_S);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"T\")).to.equal(kVK_ANSI_T);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"U\")).to.equal(kVK_ANSI_U);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"V\")).to.equal(kVK_ANSI_V);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"W\")).to.equal(kVK_ANSI_W);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"X\")).to.equal(kVK_ANSI_X);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Y\")).to.equal(kVK_ANSI_Y);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Z\")).to.equal(kVK_ANSI_Z);\n  });\n\n  it(@\"should convert numeric key bindings to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"0\")).to.equal(kVK_ANSI_0);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"1\")).to.equal(kVK_ANSI_1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"2\")).to.equal(kVK_ANSI_2);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"3\")).to.equal(kVK_ANSI_3);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"4\")).to.equal(kVK_ANSI_4);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"5\")).to.equal(kVK_ANSI_5);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"6\")).to.equal(kVK_ANSI_6);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"7\")).to.equal(kVK_ANSI_7);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"8\")).to.equal(kVK_ANSI_8);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"9\")).to.equal(kVK_ANSI_9);\n  });\n\n  it(@\"should convert alphabetical key bindings with modifiers to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"cmd+a\")).to.equal(kVK_ANSI_A);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+cmd+b\")).to.equal(kVK_ANSI_B);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"alt+shift+cmd+c\")).to.equal(kVK_ANSI_C);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"ctrl+alt+shift+cmd+d\")).to.equal(kVK_ANSI_D);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"command+e\")).to.equal(kVK_ANSI_E);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+command+f\")).to.equal(kVK_ANSI_F);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"option+shift+command+g\")).to.equal(kVK_ANSI_G);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"control+option+shift+command+h\")).to.equal(kVK_ANSI_H);\n  });\n\n  it(@\"should convert alphanumeric key bindings with whitespace to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\" cmd  +   a    \")).to.equal(kVK_ANSI_A);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\" shift  +   cmd    +     0      \")).to.equal(kVK_ANSI_0);\n  });\n\n  it(@\"should convert named key bindings to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f1\")).to.equal(kVK_F1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f2\")).to.equal(kVK_F2);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f3\")).to.equal(kVK_F3);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f4\")).to.equal(kVK_F4);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f5\")).to.equal(kVK_F5);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f6\")).to.equal(kVK_F6);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f7\")).to.equal(kVK_F7);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f8\")).to.equal(kVK_F8);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f9\")).to.equal(kVK_F9);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f10\")).to.equal(kVK_F10);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f11\")).to.equal(kVK_F11);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f12\")).to.equal(kVK_F12);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f13\")).to.equal(kVK_F13);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f14\")).to.equal(kVK_F14);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f15\")).to.equal(kVK_F15);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f16\")).to.equal(kVK_F16);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f17\")).to.equal(kVK_F17);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f18\")).to.equal(kVK_F18);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f19\")).to.equal(kVK_F19);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"f20\")).to.equal(kVK_F20);\n\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypaddecimal\")).to.equal(kVK_ANSI_KeypadDecimal);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadmultiply\")).to.equal(kVK_ANSI_KeypadMultiply);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadplus\")).to.equal(kVK_ANSI_KeypadPlus);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadclear\")).to.equal(kVK_ANSI_KeypadClear);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypaddivide\")).to.equal(kVK_ANSI_KeypadDivide);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadenter\")).to.equal(kVK_ANSI_KeypadEnter);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadminus\")).to.equal(kVK_ANSI_KeypadMinus);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypadequals\")).to.equal(kVK_ANSI_KeypadEquals);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad0\")).to.equal(kVK_ANSI_Keypad0);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad1\")).to.equal(kVK_ANSI_Keypad1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad2\")).to.equal(kVK_ANSI_Keypad2);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad3\")).to.equal(kVK_ANSI_Keypad3);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad4\")).to.equal(kVK_ANSI_Keypad4);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad5\")).to.equal(kVK_ANSI_Keypad5);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad6\")).to.equal(kVK_ANSI_Keypad6);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad7\")).to.equal(kVK_ANSI_Keypad7);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad8\")).to.equal(kVK_ANSI_Keypad8);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"keypad9\")).to.equal(kVK_ANSI_Keypad9);\n\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"return\")).to.equal(kVK_Return);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"tab\")).to.equal(kVK_Tab);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"space\")).to.equal(kVK_Space);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"delete\")).to.equal(kVK_Delete);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"escape\")).to.equal(kVK_Escape);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"command\")).to.equal(kVK_Command);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift\")).to.equal(kVK_Shift);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"capslock\")).to.equal(kVK_CapsLock);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"option\")).to.equal(kVK_Option);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"control\")).to.equal(kVK_Control);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"rightshift\")).to.equal(kVK_RightShift);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"rightoption\")).to.equal(kVK_RightOption);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"rightcontrol\")).to.equal(kVK_RightControl);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"function\")).to.equal(kVK_Function);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"volumeup\")).to.equal(kVK_VolumeUp);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"volumedown\")).to.equal(kVK_VolumeDown);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"mute\")).to.equal(kVK_Mute);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"help\")).to.equal(kVK_Help);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"home\")).to.equal(kVK_Home);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"pageup\")).to.equal(kVK_PageUp);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"forwarddelete\")).to.equal(kVK_ForwardDelete);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"end\")).to.equal(kVK_End);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"pagedown\")).to.equal(kVK_PageDown);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"left\")).to.equal(kVK_LeftArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"right\")).to.equal(kVK_RightArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"down\")).to.equal(kVK_DownArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"up\")).to.equal(kVK_UpArrow);\n  });\n\n  it(@\"should convert mixed case named key bindings to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F1\")).to.equal(kVK_F1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F2\")).to.equal(kVK_F2);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F3\")).to.equal(kVK_F3);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F4\")).to.equal(kVK_F4);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F5\")).to.equal(kVK_F5);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F6\")).to.equal(kVK_F6);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F7\")).to.equal(kVK_F7);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F8\")).to.equal(kVK_F8);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F9\")).to.equal(kVK_F9);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F10\")).to.equal(kVK_F10);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F11\")).to.equal(kVK_F11);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F12\")).to.equal(kVK_F12);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F13\")).to.equal(kVK_F13);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F14\")).to.equal(kVK_F14);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F15\")).to.equal(kVK_F15);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F16\")).to.equal(kVK_F16);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F17\")).to.equal(kVK_F17);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F18\")).to.equal(kVK_F18);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F19\")).to.equal(kVK_F19);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"F20\")).to.equal(kVK_F20);\n\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadDecimal\")).to.equal(kVK_ANSI_KeypadDecimal);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadMultiply\")).to.equal(kVK_ANSI_KeypadMultiply);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadPlus\")).to.equal(kVK_ANSI_KeypadPlus);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadClear\")).to.equal(kVK_ANSI_KeypadClear);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadDivide\")).to.equal(kVK_ANSI_KeypadDivide);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadEnter\")).to.equal(kVK_ANSI_KeypadEnter);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadMinus\")).to.equal(kVK_ANSI_KeypadMinus);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"KeypadEquals\")).to.equal(kVK_ANSI_KeypadEquals);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad0\")).to.equal(kVK_ANSI_Keypad0);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad1\")).to.equal(kVK_ANSI_Keypad1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad2\")).to.equal(kVK_ANSI_Keypad2);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad3\")).to.equal(kVK_ANSI_Keypad3);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad4\")).to.equal(kVK_ANSI_Keypad4);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad5\")).to.equal(kVK_ANSI_Keypad5);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad6\")).to.equal(kVK_ANSI_Keypad6);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad7\")).to.equal(kVK_ANSI_Keypad7);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad8\")).to.equal(kVK_ANSI_Keypad8);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Keypad9\")).to.equal(kVK_ANSI_Keypad9);\n\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Return\")).to.equal(kVK_Return);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Tab\")).to.equal(kVK_Tab);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Space\")).to.equal(kVK_Space);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Delete\")).to.equal(kVK_Delete);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Escape\")).to.equal(kVK_Escape);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Command\")).to.equal(kVK_Command);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Shift\")).to.equal(kVK_Shift);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"CapsLock\")).to.equal(kVK_CapsLock);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Option\")).to.equal(kVK_Option);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Control\")).to.equal(kVK_Control);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"RightShift\")).to.equal(kVK_RightShift);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"RightOption\")).to.equal(kVK_RightOption);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"RightControl\")).to.equal(kVK_RightControl);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Function\")).to.equal(kVK_Function);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"VolumeUp\")).to.equal(kVK_VolumeUp);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"VolumeDown\")).to.equal(kVK_VolumeDown);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Mute\")).to.equal(kVK_Mute);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Help\")).to.equal(kVK_Help);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Home\")).to.equal(kVK_Home);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"PageUp\")).to.equal(kVK_PageUp);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"ForwardDelete\")).to.equal(kVK_ForwardDelete);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"End\")).to.equal(kVK_End);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"PageDown\")).to.equal(kVK_PageDown);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Left\")).to.equal(kVK_LeftArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Right\")).to.equal(kVK_RightArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Down\")).to.equal(kVK_DownArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"Up\")).to.equal(kVK_UpArrow);\n  });\n\n  it(@\"should convert named key bindings with modifiers to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"cmd+up\")).to.equal(kVK_UpArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+cmd+down\")).to.equal(kVK_DownArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"alt+shift+cmd+left\")).to.equal(kVK_LeftArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"ctrl+alt+shift+cmd+right\")).to.equal(kVK_RightArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"command+space\")).to.equal(kVK_Space);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+command+f1\")).to.equal(kVK_F1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"option+shift+command+keypad0\")).to.equal(kVK_ANSI_Keypad0);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"control+option+shift+command+escape\")).to.equal(kVK_Escape);\n  });\n\n  it(@\"should convert mixed case named key bindings with modifiers to key codes\", ^{\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"cmd+Up\")).to.equal(kVK_UpArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+cmd+Down\")).to.equal(kVK_DownArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"alt+shift+cmd+left\")).to.equal(kVK_LeftArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"ctrl+alt+shift+cmd+Right\")).to.equal(kVK_RightArrow);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"command+SPACE\")).to.equal(kVK_Space);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"shift+command+F1\")).to.equal(kVK_F1);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"option+shift+command+KEYPAD0\")).to.equal(kVK_ANSI_Keypad0);\n    expect(SpectacleConvertShortcutKeyBindingToKeyCode(@\"control+option+shift+command+ESCAPE\")).to.equal(kVK_Escape);\n  });\n\n  it(@\"should convert empty shortcuts to nil key bindings\", ^{\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(nil))).to.equal(nil);\n  });\n\n  it(@\"should convert shortcuts to key bindings\", ^{\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+c\"))).to.equal(@\"alt+cmd+c\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+f\"))).to.equal(@\"alt+cmd+f\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+left\"))).to.equal(@\"alt+cmd+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+right\"))).to.equal(@\"alt+cmd+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+up\"))).to.equal(@\"alt+cmd+up\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+down\"))).to.equal(@\"alt+cmd+down\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+cmd+left\"))).to.equal(@\"ctrl+cmd+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+shift+cmd+left\"))).to.equal(@\"ctrl+shift+cmd+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+cmd+right\"))).to.equal(@\"ctrl+cmd+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+shift+cmd+right\"))).to.equal(@\"ctrl+shift+cmd+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+cmd+right\"))).to.equal(@\"ctrl+alt+cmd+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+cmd+left\"))).to.equal(@\"ctrl+alt+cmd+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+right\"))).to.equal(@\"ctrl+alt+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+left\"))).to.equal(@\"ctrl+alt+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+shift+right\"))).to.equal(@\"ctrl+alt+shift+right\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"ctrl+alt+shift+left\"))).to.equal(@\"ctrl+alt+shift+left\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+cmd+z\"))).to.equal(@\"alt+cmd+z\");\n    expect(SpectacleConvertShortcutToKeyBinding(shortcutForKeyBinding(@\"alt+shift+cmd+z\"))).to.equal(@\"alt+shift+cmd+z\");\n  });\n});\nSpecEnd\n\nstatic SpectacleShortcut *shortcutForKeyBinding(NSString *keyBinding)\n{\n  return [[SpectacleShortcut alloc] initWithShortcutName:nil shortcutKeyBinding:keyBinding];\n}\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleShortcutSpec.m",
    "content": "#import <Carbon/Carbon.h>\n#import <Cocoa/Cocoa.h>\n#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleShortcut.h\"\n\nSpecBegin(SpectacleShortcut)\ndescribe(@\"SpectacleShortcut\", ^{\n  it(@\"should be initialized with a key binding\", ^{\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                               shortcutKeyBinding:@\"option+command+c\"];\n    expect(shortcut.shortcutKeyCode).to.equal(kVK_ANSI_C);\n    expect(shortcut.shortcutModifiers).to.equal(optionKey | cmdKey);\n  });\n\n  it(@\"should be copied with a new shortcut action\", ^{\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                                  shortcutKeyCode:kVK_ANSI_C\n                                                                shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask];\n    expect(shortcut.shortcutAction).to.beFalsy;\n    expect([shortcut copyWithShortcutAction:^(SpectacleShortcut *shortcut) {}].shortcutAction).to.beTruthy;\n  });\n\n  it(@\"should trigger shortcut actions\", ^{\n    __block BOOL shortcutActionTriggered;\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                                  shortcutKeyCode:kVK_ANSI_C\n                                                                shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask\n                                                                   shortcutAction:^(SpectacleShortcut *shortcut) {\n                                                                     shortcutActionTriggered = YES;\n                                                                   }];\n    [shortcut triggerShortcutAction];\n    expect(shortcutActionTriggered).to.beTruthy;\n  });\n\n  it(@\"should determine if the shortcut is cleared\", ^{\n    expect([[[SpectacleShortcut alloc] initWithShortcutName:nil shortcutKeyBinding:nil] isClearedShortcut]).to.beTruthy;\n    expect([[[SpectacleShortcut alloc] initWithShortcutName:nil shortcutKeyBinding:@\"\"] isClearedShortcut]).to.beTruthy;\n    expect([[[SpectacleShortcut alloc] initWithShortcutName:nil\n                                            shortcutKeyCode:-1\n                                          shortcutModifiers:0] isClearedShortcut]).to.beTruthy;\n    expect([[[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                            shortcutKeyCode:-1\n                                          shortcutModifiers:0] isClearedShortcut]).to.beTruthy;\n  });\n\n  it(@\"should provide a display string\", ^{\n    expect([[[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                            shortcutKeyCode:kVK_ANSI_C\n                                          shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask] displayString]).to.equal(@\"⌥⌘C\");\n  });\n\n  it(@\"should provide a key binding\", ^{\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                               shortcutKeyBinding:@\"alt+cmd+c\"];\n    expect(shortcut.shortcutKeyBinding).to.equal(@\"alt+cmd+c\");\n  });\n\n  it(@\"should support equality\", ^{\n    SpectacleShortcut *shortcut1 = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                                   shortcutKeyCode:kVK_ANSI_C\n                                                                 shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask];\n    SpectacleShortcut *shortcut2 = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                                   shortcutKeyCode:kVK_ANSI_C\n                                                                 shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask];\n    SpectacleShortcut *shortcut3 = [[SpectacleShortcut alloc] initWithShortcutName:nil\n                                                                   shortcutKeyCode:kVK_ANSI_C\n                                                                 shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask];\n    expect(shortcut1).to.equal(shortcut2);\n    expect(shortcut1).to.equal(shortcut3);\n    expect(shortcut1).notTo.equal([[SpectacleShortcut alloc] initWithShortcutName:nil\n                                                                  shortcutKeyCode:-1\n                                                                shortcutModifiers:0]);\n  });\n\n  it(@\"should determine if the shortcut is contains modifiers\", ^{\n    SpectacleShortcut *shortcut = [[SpectacleShortcut alloc] initWithShortcutName:@\"MoveToCenter\"\n                                                                  shortcutKeyCode:kVK_ANSI_C\n                                                                shortcutModifiers:NSAlternateKeyMask | NSCommandKeyMask];\n    expect([shortcut containsModifiers:NSAlternateKeyMask]).to.beTruthy;\n    expect([shortcut containsModifiers:NSAlternateKeyMask | NSCommandKeyMask]).to.beTruthy;\n    expect([shortcut containsModifiers:NSControlKeyMask]).to.beFalsy;\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleShortcutTranslationsSpec.m",
    "content": "#import <Carbon/Carbon.h>\n#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleShortcut.h\"\n#import \"SpectacleShortcutTranslations.h\"\n\nstatic SpectacleShortcut *shortcutForKeyBinding(NSString *keyBinding);\n\nSpecBegin(SpectacleShortcutTranslations)\ndescribe(@\"SpectacleShortcutTranslations\", ^{\n  it(@\"should translate alphanumeric key codes\", ^{\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_A)).to.equal(@\"A\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_B)).to.equal(@\"B\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_C)).to.equal(@\"C\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_D)).to.equal(@\"D\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_E)).to.equal(@\"E\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_F)).to.equal(@\"F\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_G)).to.equal(@\"G\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_H)).to.equal(@\"H\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_I)).to.equal(@\"I\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_J)).to.equal(@\"J\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_K)).to.equal(@\"K\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_L)).to.equal(@\"L\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_M)).to.equal(@\"M\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_N)).to.equal(@\"N\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_O)).to.equal(@\"O\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_P)).to.equal(@\"P\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Q)).to.equal(@\"Q\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_R)).to.equal(@\"R\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_S)).to.equal(@\"S\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_T)).to.equal(@\"T\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_U)).to.equal(@\"U\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_V)).to.equal(@\"V\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_W)).to.equal(@\"W\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_X)).to.equal(@\"X\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Y)).to.equal(@\"Y\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Z)).to.equal(@\"Z\");\n\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_0)).to.equal(@\"0\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_1)).to.equal(@\"1\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_2)).to.equal(@\"2\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_3)).to.equal(@\"3\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_4)).to.equal(@\"4\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_5)).to.equal(@\"5\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_6)).to.equal(@\"6\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_7)).to.equal(@\"7\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_8)).to.equal(@\"8\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_9)).to.equal(@\"9\");\n  });\n\n  it(@\"should translate keyboard layout independent key codes\", ^{\n    expect(SpectacleTranslateKeyCode(kVK_F1)).to.equal(@\"F1\");\n    expect(SpectacleTranslateKeyCode(kVK_F2)).to.equal(@\"F2\");\n    expect(SpectacleTranslateKeyCode(kVK_F3)).to.equal(@\"F3\");\n    expect(SpectacleTranslateKeyCode(kVK_F4)).to.equal(@\"F4\");\n    expect(SpectacleTranslateKeyCode(kVK_F5)).to.equal(@\"F5\");\n    expect(SpectacleTranslateKeyCode(kVK_F6)).to.equal(@\"F6\");\n    expect(SpectacleTranslateKeyCode(kVK_F7)).to.equal(@\"F7\");\n    expect(SpectacleTranslateKeyCode(kVK_F8)).to.equal(@\"F8\");\n    expect(SpectacleTranslateKeyCode(kVK_F9)).to.equal(@\"F9\");\n    expect(SpectacleTranslateKeyCode(kVK_F10)).to.equal(@\"F10\");\n    expect(SpectacleTranslateKeyCode(kVK_F11)).to.equal(@\"F11\");\n    expect(SpectacleTranslateKeyCode(kVK_F12)).to.equal(@\"F12\");\n    expect(SpectacleTranslateKeyCode(kVK_F13)).to.equal(@\"F13\");\n    expect(SpectacleTranslateKeyCode(kVK_F14)).to.equal(@\"F14\");\n    expect(SpectacleTranslateKeyCode(kVK_F15)).to.equal(@\"F15\");\n    expect(SpectacleTranslateKeyCode(kVK_F16)).to.equal(@\"F16\");\n    expect(SpectacleTranslateKeyCode(kVK_F17)).to.equal(@\"F17\");\n    expect(SpectacleTranslateKeyCode(kVK_F18)).to.equal(@\"F18\");\n    expect(SpectacleTranslateKeyCode(kVK_F19)).to.equal(@\"F19\");\n    expect(SpectacleTranslateKeyCode(kVK_F20)).to.equal(@\"F20\");\n\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadDecimal)).to.equal(@\".\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadMultiply)).to.equal(@\"*\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadPlus)).to.equal(@\"+\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadClear)).to.equal(@\"⌧\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadDivide)).to.equal(@\"/\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadEnter)).to.equal(@\"⌤\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadMinus)).to.equal(@\"-\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_KeypadEquals)).to.equal(@\"=\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad0)).to.equal(@\"0\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad1)).to.equal(@\"1\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad2)).to.equal(@\"2\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad3)).to.equal(@\"3\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad4)).to.equal(@\"4\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad5)).to.equal(@\"5\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad6)).to.equal(@\"6\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad7)).to.equal(@\"7\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad8)).to.equal(@\"8\");\n    expect(SpectacleTranslateKeyCode(kVK_ANSI_Keypad9)).to.equal(@\"9\");\n\n    expect(SpectacleTranslateKeyCode(kVK_Return)).to.equal(@\"↩\");\n    expect(SpectacleTranslateKeyCode(kVK_Tab)).to.equal(@\"⇥\");\n    expect(SpectacleTranslateKeyCode(kVK_Space)).to.equal(@\"␣\");\n    expect(SpectacleTranslateKeyCode(kVK_Delete)).to.equal(@\"⌫\");\n    expect(SpectacleTranslateKeyCode(kVK_Escape)).to.equal(@\"⎋\");\n    expect(SpectacleTranslateKeyCode(kVK_Command)).to.equal(@\"⌘\");\n    expect(SpectacleTranslateKeyCode(kVK_Shift)).to.equal(@\"⇧\");\n    expect(SpectacleTranslateKeyCode(kVK_CapsLock)).to.equal(@\"⇪\");\n    expect(SpectacleTranslateKeyCode(kVK_Option)).to.equal(@\"⌥\");\n    expect(SpectacleTranslateKeyCode(kVK_Control)).to.equal(@\"⌃\");\n    expect(SpectacleTranslateKeyCode(kVK_RightShift)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_RightOption)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_RightControl)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_Function)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_VolumeUp)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_VolumeDown)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_Mute)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_Help)).to.equal(@\"\");\n    expect(SpectacleTranslateKeyCode(kVK_Home)).to.equal(@\"↖\");\n    expect(SpectacleTranslateKeyCode(kVK_PageUp)).to.equal(@\"⇞\");\n    expect(SpectacleTranslateKeyCode(kVK_ForwardDelete)).to.equal(@\"⌦\");\n    expect(SpectacleTranslateKeyCode(kVK_End)).to.equal(@\"↘\");\n    expect(SpectacleTranslateKeyCode(kVK_PageDown)).to.equal(@\"⇟\");\n    expect(SpectacleTranslateKeyCode(kVK_LeftArrow)).to.equal(@\"←\");\n    expect(SpectacleTranslateKeyCode(kVK_RightArrow)).to.equal(@\"→\");\n    expect(SpectacleTranslateKeyCode(kVK_DownArrow)).to.equal(@\"↓\");\n    expect(SpectacleTranslateKeyCode(kVK_UpArrow)).to.equal(@\"↑\");\n  });\n\n  it(@\"should translate empty modifiers\", ^{\n    expect(SpectacleTranslateModifiers(0)).to.equal(@\"\");\n  });\n\n  it(@\"should translate modifiers\", ^{\n    expect(SpectacleTranslateModifiers(NSControlKeyMask)).to.equal(@\"⌃\");\n    expect(SpectacleTranslateModifiers(NSAlternateKeyMask)).to.equal(@\"⌥\");\n    expect(SpectacleTranslateModifiers(NSShiftKeyMask)).to.equal(@\"⇧\");\n    expect(SpectacleTranslateModifiers(NSCommandKeyMask)).to.equal(@\"⌘\");\n\n  });\n\n  it(@\"should translate shortcuts\", ^{\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+c\"))).to.equal(@\"⌥⌘C\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+f\"))).to.equal(@\"⌥⌘F\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+left\"))).to.equal(@\"⌥⌘←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+right\"))).to.equal(@\"⌥⌘→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+up\"))).to.equal(@\"⌥⌘↑\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+down\"))).to.equal(@\"⌥⌘↓\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+command+left\"))).to.equal(@\"⌃⌘←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+shift+command+left\"))).to.equal(@\"⌃⇧⌘←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+command+right\"))).to.equal(@\"⌃⌘→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+shift+command+right\"))).to.equal(@\"⌃⇧⌘→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+command+right\"))).to.equal(@\"⌃⌥⌘→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+command+left\"))).to.equal(@\"⌃⌥⌘←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+right\"))).to.equal(@\"⌃⌥→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+left\"))).to.equal(@\"⌃⌥←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+shift+right\"))).to.equal(@\"⌃⌥⇧→\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"control+option+shift+left\"))).to.equal(@\"⌃⌥⇧←\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+command+z\"))).to.equal(@\"⌥⌘Z\");\n    expect(SpectacleTranslateShortcut(shortcutForKeyBinding(@\"option+shift+command+z\"))).to.equal(@\"⌥⇧⌘Z\");\n  });\n\n  it(@\"should convert empty modifiers\", ^{\n    expect(SpectacleConvertCocoaModifiersToCarbon(0)).to.equal(0);\n    expect(SpectacleConvertCarbonModifiersToCocoa(0)).to.equal(0);\n  });\n\n  it(@\"should convert invalid modifiers\", ^{\n    expect(SpectacleConvertCocoaModifiersToCarbon(42)).to.equal(0);\n    expect(SpectacleConvertCarbonModifiersToCocoa(42)).to.equal(0);\n  });\n\n  it(@\"should convert Cocoa modifiers to Carbon modifiers\", ^{\n    expect(SpectacleConvertCocoaModifiersToCarbon(NSControlKeyMask)).to.equal(controlKey);\n    expect(SpectacleConvertCocoaModifiersToCarbon(NSAlternateKeyMask)).to.equal(optionKey);\n    expect(SpectacleConvertCocoaModifiersToCarbon(NSShiftKeyMask)).to.equal(shiftKey);\n    expect(SpectacleConvertCocoaModifiersToCarbon(NSCommandKeyMask)).to.equal(cmdKey);\n  });\n\n  it(@\"should convert Carbon modifiers to Cocoa modifiers\", ^{\n    expect(SpectacleConvertCarbonModifiersToCocoa(controlKey)).to.equal(NSControlKeyMask);\n    expect(SpectacleConvertCarbonModifiersToCocoa(optionKey)).to.equal(NSAlternateKeyMask);\n    expect(SpectacleConvertCarbonModifiersToCocoa(shiftKey)).to.equal(NSShiftKeyMask);\n    expect(SpectacleConvertCarbonModifiersToCocoa(cmdKey)).to.equal(NSCommandKeyMask);\n  });\n\n  it(@\"should convert modifiers to Carbon modifiers if necessary\", ^{\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(controlKey)).to.equal(controlKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(optionKey)).to.equal(optionKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(shiftKey)).to.equal(shiftKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(cmdKey)).to.equal(cmdKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(NSControlKeyMask)).to.equal(controlKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(NSAlternateKeyMask)).to.equal(optionKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(NSShiftKeyMask)).to.equal(shiftKey);\n    expect(SpectacleConvertModifiersToCarbonIfNecessary(NSCommandKeyMask)).to.equal(cmdKey);\n  });\n\n  it(@\"should convert modifiers to Cocoa modifiers if necessary\", ^{\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(NSControlKeyMask)).to.equal(NSControlKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(NSAlternateKeyMask)).to.equal(NSAlternateKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(NSShiftKeyMask)).to.equal(NSShiftKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(NSCommandKeyMask)).to.equal(NSCommandKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(controlKey)).to.equal(NSControlKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(optionKey)).to.equal(NSAlternateKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(shiftKey)).to.equal(NSShiftKeyMask);\n    expect(SpectacleConvertModifiersToCocoaIfNecessary(cmdKey)).to.equal(NSCommandKeyMask);\n  });\n});\nSpecEnd\n\nstatic SpectacleShortcut *shortcutForKeyBinding(NSString *keyBinding)\n{\n  return [[SpectacleShortcut alloc] initWithShortcutName:nil shortcutKeyBinding:keyBinding];\n}\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleSmallerWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleSmallerWindowCalculation)\ndescribe(@\"SpectacleSmallerWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's smaller CGRect when centered in the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(315.0f, 177.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(330.0f, 192.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(330.0f, 192.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(345.0f, 207.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(345.0f, 207.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(360.0f, 222.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the top edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(357.0f, 351.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(372.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(372.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(387.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(387.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(402.0f, 441.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the bottom edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(193.0f, 4.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(208.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(208.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(223.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(223.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(238.0f, 4.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the left edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 205.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 220.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 220.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 235.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 235.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 250.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the right edge of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(630.0f, 258.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 273.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 273.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 288.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 288.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 303.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the top and left edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 351.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 441.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the top and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(630.0f, 351.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 381.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 381.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 411.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 411.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 441.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the bottom and left edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 4.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the bottom and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(630.0f, 4.0f, 810.0f, 526.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(660.0f, 4.0f, 780.0f, 496.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(660.0f, 4.0f, 780.0f, 496.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(690.0f, 4.0f, 750.0f, 466.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(690.0f, 4.0f, 750.0f, 466.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 4.0f, 720.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the top and bottom edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(299.0f, 4.0f, 810.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(314.0f, 4.0f, 780.0f, 873.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(314.0f, 4.0f, 780.0f, 873.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(329.0f, 4.0f, 750.0f, 873.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(329.0f, 4.0f, 750.0f, 873.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(344.0f, 4.0f, 720.0f, 873.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against the left and right edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 240.0f, 1440.0f, 536.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 255.0f, 1440.0f, 506.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 255.0f, 1440.0f, 506.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 270.0f, 1440.0f, 476.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 270.0f, 1440.0f, 476.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 285.0f, 1440.0f, 446.0f));\n  });\n\n  it(@\"should calculate a window's smaller CGRect when against all edges of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(15.0f, 19.0f, 1410.0f, 843.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(15.0f, 19.0f, 1410.0f, 843.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(30.0f, 34.0f, 1380.0f, 813.0f));\n    result = [windowPositionCalculator calculateWindowRect:CGRectMake(30.0f, 34.0f, 1380.0f, 813.0f)\n                                visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                           visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                    action:kSpectacleWindowActionSmaller];\n    expect(result.windowRect).to.equal(CGRectMake(45.0f, 49.0f, 1350.0f, 783.0f));\n\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleTopHalfWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleTopHalfWindowCalculation)\ndescribe(@\"SpectacleTopHalfWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the top half of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionTopHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 441.0f, 1440.0f, 436.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the top 2/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 441.0f, 1440.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionTopHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 295.0f, 1440.0f, 582.0f));\n  });\n\n  it(@\"should calculate a window's CGRect in the top 1/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 295.0f, 1440.0f, 582.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionTopHalf];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 586.0f, 1440.0f, 291.0f));\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleUpperLeftWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleUpperLeftWindowCalculation)\ndescribe(@\"SpectacleUpperLeftWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the upper left corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperLeft];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 441.0f, 720.0f, 436.0f));\n  });\n  \n  it(@\"should calculate a window's CGRect in the left 2/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 441.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperLeft];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 441.0f, 960.0f, 436.0f));\n  });\n  \n  it(@\"should calculate a window's CGRect in the left 1/3 of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(0.0f, 441.0f, 960.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperLeft];\n    expect(result.windowRect).to.equal(CGRectMake(0.0f, 441.0f, 480.0f, 436.0f));\n  });\n\n  \n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleUpperRightWindowCalculationSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n\nSpecBegin(SpectacleUpperRightWindowCalculation)\ndescribe(@\"SpectacleUpperRightWindowCalculation\", ^{\n  CGRect visibleFrameSourceScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect visibleFrameDestinationScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  SpectacleWindowPositionCalculator *windowPositionCalculator = [[SpectacleWindowPositionCalculator alloc] initWithErrorHandler:^(NSString *message) {\n    EXP_failure(message);\n  }];\n\n  it(@\"should calculate a window's CGRect in the upper right corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(165.0f, 245.0f, 564.0f, 384.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperRight];\n    expect(result.windowRect).to.equal(CGRectMake(720.0f, 441.0f, 720.0f, 436.0f));\n  });\n  \n  it(@\"should calculate a window's CGRect in the upper right 2/3 corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(720.0f, 441.0f, 720.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperRight];\n    expect(result.windowRect).to.equal(CGRectMake(480.0f, 441.0f, 960.0f, 436.0f));\n  });\n  \n  it(@\"should calculate a window's CGRect in the upper right 1/3 corner of the screen\", ^{\n    SpectacleWindowPositionCalculationResult *result = [windowPositionCalculator calculateWindowRect:CGRectMake(480.0f, 441.0f, 960.0f, 436.0f)\n                                                                          visibleFrameOfSourceScreen:visibleFrameSourceScreen\n                                                                     visibleFrameOfDestinationScreen:visibleFrameDestinationScreen\n                                                                                              action:kSpectacleWindowActionUpperRight];\n    expect(result.windowRect).to.equal(CGRectMake(960.0f, 441.0f, 480.0f, 436.0f));\n  });\n\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Sources/SpectacleWindowPositionManagerSpec.m",
    "content": "#import <Expecta/Expecta.h>\n#import <OCHamcrest/OCHamcrest.h>\n#import <OCMockito/OCMockito.h>\n#import <Specta/Specta.h>\n\n#import \"SpectacleAccessibilityElement.h\"\n#import \"SpectacleScreenDetectionResult.h\"\n#import \"SpectacleScreenDetector.h\"\n#import \"SpectacleWindowPositionCalculationResult.h\"\n#import \"SpectacleWindowPositionCalculator.h\"\n#import \"SpectacleWindowPositionManager.h\"\n\nSpecBegin(SpectacleWindowPositionManager)\ndescribe(@\"SpectacleWindowPositionManager\", ^{\n  CGRect frameOfScreen = CGRectMake(0.0f, 0.0f, 1440.0f, 900.0f);\n  CGRect visibleFrameOfScreen = CGRectMake(0.0f, 4.0f, 1440.0f, 873.0f);\n  CGRect frontmostWindowRect = CGRectMake(165.0f, 245.0f, 564.0f, 384.0f);\n\n  __block NSScreen *mockMainScreen;\n  __block SpectacleScreenDetector *mockScreenDetector;\n  __block SpectacleWindowPositionCalculator *mockWindowPositionCalculator;\n  __block NSWorkspace *mockSharedWorkspace;\n  __block NSRunningApplication *mockFrontmostApplication;\n  __block SpectacleWindowPositionManager *windowPositionManager;\n  __block SpectacleWindowPositionCalculationResult *mockWindowPositionCalculationResult;\n\n  beforeEach(^{\n    mockMainScreen = mock([NSScreen class]);\n    mockScreenDetector = mock([SpectacleScreenDetector class]);\n    mockWindowPositionCalculator = mock([SpectacleWindowPositionCalculator class]);\n    mockSharedWorkspace = mock([NSWorkspace class]);\n    mockFrontmostApplication = mock([NSRunningApplication class]);\n    mockWindowPositionCalculationResult = mock([SpectacleWindowPositionCalculationResult class]);\n\n    [given([mockMainScreen frame]) willReturnStruct:&frameOfScreen objCType:@encode(NSRect)];\n    [given([mockMainScreen visibleFrame]) willReturnStruct:&visibleFrameOfScreen objCType:@encode(NSRect)];\n\n    MKTOngoingStubbing *ongoingWindowPositionCalculatorStubbing =\n      given([mockWindowPositionCalculator calculateWindowRect:CGRectNull\n                                   visibleFrameOfSourceScreen:CGRectNull\n                              visibleFrameOfDestinationScreen:CGRectNull\n                                                       action:kSpectacleWindowActionNone]);\n\n    ongoingWindowPositionCalculatorStubbing = [ongoingWindowPositionCalculatorStubbing withMatcher:anything()\n                                                                                       forArgument:0];\n\n    ongoingWindowPositionCalculatorStubbing = [ongoingWindowPositionCalculatorStubbing withMatcher:anything()\n                                                                                       forArgument:1];\n\n    ongoingWindowPositionCalculatorStubbing = [ongoingWindowPositionCalculatorStubbing withMatcher:anything()\n                                                                                       forArgument:2];\n\n    ongoingWindowPositionCalculatorStubbing = [ongoingWindowPositionCalculatorStubbing withMatcher:anything()\n                                                                                       forArgument:3];\n\n    [ongoingWindowPositionCalculatorStubbing willReturn:mockWindowPositionCalculationResult];\n\n    MKTOngoingStubbing *ongoingScreenDetectorStubbing =\n      given([mockScreenDetector screenWithAction:kSpectacleWindowActionNone\n                          frontmostWindowElement:anything()\n                                         screens:anything()\n                                      mainScreen:anything()]);\n\n    ongoingScreenDetectorStubbing = [ongoingScreenDetectorStubbing withMatcher:anything()\n                                                                   forArgument:0];\n\n    ongoingScreenDetectorStubbing = [ongoingScreenDetectorStubbing withMatcher:anything()\n                                                                   forArgument:1];\n\n    [ongoingScreenDetectorStubbing willReturn:[SpectacleScreenDetectionResult resultWithSourceScreen:mockMainScreen\n                                                                                   destinationScreen:mockMainScreen]];\n\n    [given([mockFrontmostApplication bundleIdentifier]) willReturn:@\"com.divisiblebyzero.SpectacleSpecs\"];\n\n    [given([mockSharedWorkspace frontmostApplication]) willReturn:mockFrontmostApplication];\n\n    windowPositionManager = [[SpectacleWindowPositionManager alloc] initWithScreenDetector:mockScreenDetector\n                                                                  windowPositionCalculator:mockWindowPositionCalculator\n                                                                           sharedWorkspace:mockSharedWorkspace\n                                                                           failureFeedback:^() {}\n                                                                               windowMover:nil];\n  });\n\n  it(@\"should do nothing if the frontmost window is a sheet\", ^{\n    SpectacleAccessibilityElement *mockAccessibilityElemenet = mock([SpectacleAccessibilityElement class]);\n\n    [given([mockAccessibilityElemenet rectOfElement]) willReturnStruct:&frontmostWindowRect objCType:@encode(CGRect)];\n    [given([mockAccessibilityElemenet isSheet]) willReturnBool:YES];\n\n    [windowPositionManager moveFrontmostWindowElement:mockAccessibilityElemenet\n                                               action:kSpectacleWindowActionNone\n                                              screens:@[mockMainScreen]\n                                           mainScreen:mockMainScreen];\n\n    [verify(mockAccessibilityElemenet) rectOfElement];\n    [verify(mockAccessibilityElemenet) isSheet];\n    [verifyCount(mockAccessibilityElemenet, never()) isSystemDialog];\n\n    [verifyCount(mockWindowPositionCalculator, never()) calculateWindowRect:CGRectNull\n                                                 visibleFrameOfSourceScreen:CGRectNull\n                                            visibleFrameOfDestinationScreen:CGRectNull\n                                                                     action:kSpectacleWindowActionNone];\n  });\n\n  it(@\"should do nothing if the frontmost window is a system dialog\", ^{\n    SpectacleAccessibilityElement *mockAccessibilityElemenet = mock([SpectacleAccessibilityElement class]);\n\n    [given([mockAccessibilityElemenet rectOfElement]) willReturnStruct:&frontmostWindowRect objCType:@encode(CGRect)];\n    [given([mockAccessibilityElemenet isSheet]) willReturnBool:NO];\n    [given([mockAccessibilityElemenet isSystemDialog]) willReturnBool:YES];\n\n    [windowPositionManager moveFrontmostWindowElement:mockAccessibilityElemenet\n                                               action:kSpectacleWindowActionNone\n                                              screens:@[mockMainScreen]\n                                           mainScreen:mockMainScreen];\n\n    [verify(mockAccessibilityElemenet) rectOfElement];\n    [verify(mockAccessibilityElemenet) isSheet];\n    [verify(mockAccessibilityElemenet) isSystemDialog];\n\n    [verifyCount(mockWindowPositionCalculator, never()) calculateWindowRect:CGRectNull\n                                                 visibleFrameOfSourceScreen:CGRectNull\n                                            visibleFrameOfDestinationScreen:CGRectNull\n                                                                     action:kSpectacleWindowActionNone];\n  });\n\n  it(@\"should do nothing if the frontmost window rect is unavailable\", ^{\n    SpectacleAccessibilityElement *mockAccessibilityElemenet = mock([SpectacleAccessibilityElement class]);\n\n    [given([mockAccessibilityElemenet rectOfElement]) willReturnStruct:&CGRectNull objCType:@encode(CGRect)];\n    [given([mockAccessibilityElemenet isSheet]) willReturnBool:NO];\n    [given([mockAccessibilityElemenet isSystemDialog]) willReturnBool:YES];\n\n    [windowPositionManager moveFrontmostWindowElement:mockAccessibilityElemenet\n                                               action:kSpectacleWindowActionNone\n                                              screens:@[mockMainScreen]\n                                           mainScreen:mockMainScreen];\n\n    [verify(mockAccessibilityElemenet) rectOfElement];\n    [verify(mockAccessibilityElemenet) isSheet];\n    [verify(mockAccessibilityElemenet) isSystemDialog];\n\n    [verifyCount(mockWindowPositionCalculator, never()) calculateWindowRect:CGRectNull\n                                                 visibleFrameOfSourceScreen:CGRectNull\n                                            visibleFrameOfDestinationScreen:CGRectNull\n                                                                     action:kSpectacleWindowActionNone];\n  });\n\n  it(@\"should do nothing if screen detection fails\", ^{\n    SpectacleAccessibilityElement *mockAccessibilityElemenet = mock([SpectacleAccessibilityElement class]);\n\n    [given([mockAccessibilityElemenet rectOfElement]) willReturnStruct:&frontmostWindowRect\n                                                              objCType:@encode(CGRect)];\n    [given([mockAccessibilityElemenet isSheet]) willReturnBool:NO];\n    [given([mockAccessibilityElemenet isSystemDialog]) willReturnBool:YES];\n\n    [given([mockScreenDetector screenWithAction:kSpectacleWindowActionCenter\n                         frontmostWindowElement:anything()\n                                        screens:anything()\n                                     mainScreen:anything()]) willReturn:nil];\n\n    [windowPositionManager moveFrontmostWindowElement:mockAccessibilityElemenet\n                                               action:kSpectacleWindowActionNone\n                                              screens:@[mockMainScreen]\n                                           mainScreen:mockMainScreen];\n\n    [verify(mockAccessibilityElemenet) rectOfElement];\n    [verify(mockAccessibilityElemenet) isSheet];\n    [verify(mockAccessibilityElemenet) isSystemDialog];\n\n    [verifyCount(mockWindowPositionCalculator, never()) calculateWindowRect:CGRectNull\n                                                 visibleFrameOfSourceScreen:CGRectNull\n                                            visibleFrameOfDestinationScreen:CGRectNull\n                                                                     action:kSpectacleWindowActionNone];\n  });\n\n  it(@\"should do nothing if the window position calculation returns the same results\", ^{\n    SpectacleAccessibilityElement *mockAccessibilityElemenet = mock([SpectacleAccessibilityElement class]);\n\n    [given([mockAccessibilityElemenet rectOfElement]) willReturnStruct:&frontmostWindowRect objCType:@encode(CGRect)];\n    [given([mockAccessibilityElemenet isSheet]) willReturnBool:NO];\n    [given([mockAccessibilityElemenet isSystemDialog]) willReturnBool:NO];\n\n    [given([mockWindowPositionCalculationResult action]) willReturn:kSpectacleWindowActionCenter];\n\n    CGRect flippedFrontmostWindowRect = frontmostWindowRect;\n\n    [given([mockWindowPositionCalculationResult windowRect]) willReturnStruct:&flippedFrontmostWindowRect\n                                                                     objCType:@encode(CGRect)];\n\n    [windowPositionManager moveFrontmostWindowElement:mockAccessibilityElemenet\n                                               action:kSpectacleWindowActionCenter\n                                              screens:@[mockMainScreen]\n                                           mainScreen:mockMainScreen];\n\n    [(SpectacleWindowPositionCalculationResult *)verify(mockWindowPositionCalculationResult) action];\n    [verify(mockWindowPositionCalculationResult) windowRect];\n\n    [[verifyCount(mockAccessibilityElemenet, never()) withMatcher:anything()] setRectOfElement:CGRectNull];\n  });\n});\nSpecEnd\n"
  },
  {
    "path": "SpectacleSpecs/Supporting Files/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  }
]