Repository: julienXX/terminal-notifier Branch: master Commit: 1e09b8b287ce Files: 27 Total size: 213.1 KB Directory structure: gitextract_kqhj6oc8/ ├── .github/ │ └── ISSUE_TEMPLATE.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.markdown ├── Ruby/ │ ├── Gemfile │ ├── LICENSE │ ├── README.markdown │ ├── Rakefile │ ├── bin/ │ │ └── terminal-notifier │ ├── lib/ │ │ └── terminal-notifier.rb │ ├── spec/ │ │ └── terminal-notifier_spec.rb │ └── terminal-notifier.gemspec ├── Terminal Notifier/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Terminal Notifier-Info.plist │ ├── Terminal Notifier-Prefix.pch │ ├── en.lproj/ │ │ ├── Credits.rtf │ │ ├── InfoPlist.strings │ │ └── MainMenu.xib │ └── main.m ├── Terminal Notifier.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── Terminal Notifier.xccheckout │ └── xcshareddata/ │ └── xcschemes/ │ └── Terminal Notifier.xcscheme └── Terminal.icns ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ # Please check everything that applies to your issue: - [ ] I looked in closed issues and it has not already been answered - [ ] My issue appeared with a terminal-notifier update - [ ] I'm using a tool that uses terminal-notifier (guard-notifier, node-notifier...) # To help us debug your issue please include: - the macOS version you use - terminal-notifier version - how did you install terminal-notifier (binary download, homebrew, ruby gem...)? - step-by-step reproduction instructions # Common issues and solution: - I'm using tmux -> see #115 - I'm using iterm2 -> see #147 - I want to change the icon -> see https://github.com/julienXX/terminal-notifier/issues/197#issuecomment-301305576 - I want sticky notifications or action buttons -> please use [alerter](https://github.com/vjeantet/alerter) Thanks! ================================================ FILE: .gitignore ================================================ .*.sw? .DS_Store DerivedData xcuserdata Ruby/*.zip Ruby/*.gem Ruby/vendor build ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at julien@sideburns.eu. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: CONTRIBUTING.md ================================================ # How to contribute I like to encourage you to contribute to the repository. This should be as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request. ## How to prepare * You need a [GitHub account](https://github.com/signup/free) * Submit an [issue ticket](https://github.com/julienXX/terminal-notifier/issues) for your issue if there is no one yet. * Describe the issue and include steps to reproduce if it's a bug. * Ensure to mention the earliest version that you know is affected. * If you are able and want to fix this, fork the repository on GitHub ## Make Changes * In your forked repository, create a topic branch for your upcoming patch. (e.g. `feature--autoplay` or `bugfix--ios-crash`) * Usually this is based on the master branch. * Create a branch based on master; `git branch fix/master/my_contribution master` then checkout the new branch with `git checkout fix/master/my_contribution`. Please avoid working directly on the `master` branch. * Make sure you stick to the coding style that is used already. * Make commits of logical units and describe them properly. * Check for unnecessary whitespace with `git diff --check` before committing. * If possible, submit tests to your patch / new feature so it can be tested easily. * Assure nothing is broken by running all the tests. ## Submit Changes * Push your changes to a topic branch in your fork of the repository. * Open a pull request to the original repository and choose the right original branch you want to patch. _Advanced users may install the `hub` gem and use the [`hub pull-request` command](https://hub.github.com/hub.1.html)._ * If not done in commit messages (which you really should do) please reference and update your issue with the code changes. But _please do not close the issue yourself_. _Notice: You can [turn your previously filed issues into a pull-request here](http://issue2pr.herokuapp.com/)._ * Even if you have write access to the repository, do not directly push or merge pull-requests. Let another team member review your pull request and approve. # Additional Resources * [General GitHub documentation](http://help.github.com/) * [GitHub pull request documentation](https://help.github.com/articles/about-pull-requests/) * [Read the Issue Guidelines by @necolas](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md) for more details ================================================ FILE: LICENSE.md ================================================ All the works are available under the MIT license. Except for ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is copyright of Apple. Copyright (C) 2012-2016 Eloy Durán eloy.de.enige@gmail.com, Julien Blanchard julien@sideburns.eu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.markdown ================================================ # terminal-notifier [![GitHub release](https://img.shields.io/github/release/julienXX/terminal-notifier.svg)](https://github.com/julienXX/terminal-notifier/releases) terminal-notifier is a command-line tool to send macOS User Notifications, which are available on macOS 10.10 and higher. ## News [alerter](https://github.com/vjeantet/alerter) features were merged in terminal-notifier 1.7. This led to some issues and even more issues in the 1.8 release. We decided with [Valère Jeantet](https://github.com/vjeantet) to rollback this merge. From now on terminal-notifier won't have the sticky notification feature nor the actions buttons. If you need them please use [alerter](https://github.com/vjeantet/alerter). I also want to follow [semver](http://semver.org) hence this latest version starts at 2.0.0. Sticking to two smaller specialized tools will hopefully make them easier to maintain and less error prone. ## Caveats * It is currently packaged as an application bundle, because `NSUserNotification` does not work from a ‘Foundation tool’. [radar://11956694](radar://11956694) * If you intend to package terminal-notifier with your app to distribute it on the Mac App Store, please use 1.5.2; version 1.6.0+ uses a private method override, which is not allowed in the App Store Guidelines. * If you're using macOS < 10.10 you should use terminal-notifier 1.6.3. * If you're looking for sticky notifications or more actions on a notification please use [alerter](https://github.com/vjeantet/alerter) ## Download Prebuilt binaries are available from the [releases section](https://github.com/julienXX/terminal-notifier/releases). Or if you want to use this from [Ruby](https://github.com/julienXX/terminal-notifier/tree/master/Ruby), you can install it through RubyGems: ``` $ [sudo] gem install terminal-notifier ``` You can also install it via [Homebrew](https://github.com/mxcl/homebrew): ``` $ brew install terminal-notifier ``` ## Usage ``` $ ./terminal-notifier.app/Contents/MacOS/terminal-notifier -[message|group|list] [VALUE|ID|ID] [options] ``` In order to use terminal-notifier, you have to call the binary _inside_ the application bundle. The Ruby gem, which wraps this tool, _does_ have a bin wrapper. If installed you can simply do: ``` $ terminal-notifier -[message|group|list] [VALUE|ID|ID] [options] ``` This will obviously be a bit slower than using the tool without the wrapper. If you'd like notifications to stay on the screen until dismissed, go to System Preferences -> Notifications -> terminal-notifier and change the style from Banners to Alerts. You cannot do this on a per-notification basis. ### Example Uses Display piped data with a sound: ``` $ echo 'Piped Message Data!' | terminal-notifier -sound default ``` ![Example 1](assets/Example_1.png) Use a custom icon: ``` $ terminal-notifier -title ProjectX -subtitle "new tag detected" -message "Finished" -appIcon http://vjeantet.fr/images/logo.png ``` ![Example 3](assets/Example_3.png) Open an URL when the notification is clicked: ``` $ terminal-notifier -title '💰' -message 'Check your Apple stock!' -open 'http://finance.yahoo.com/q?s=AAPL' ``` ![Example 4](assets/Example_4.png) Open an app when the notification is clicked: ``` $ terminal-notifier -group 'address-book-sync' -title 'Address Book Sync' -subtitle 'Finished' -message 'Imported 42 contacts.' -activate 'com.apple.AddressBook' ``` ![Example 5](assets/Example_5.png) ### Options At a minimum, you must specify either the `-message` , the `-remove`, or the `-list` option. ------------------------------------------------------------------------------- `-message VALUE` **[required]** The message body of the notification. If you pipe data into terminal-notifier, you can omit this option, and the piped data will become the message body instead. ------------------------------------------------------------------------------- `-title VALUE` The title of the notification. This defaults to ‘Terminal’. ------------------------------------------------------------------------------- `-subtitle VALUE` The subtitle of the notification. ------------------------------------------------------------------------------- `-sound NAME` Play the `NAME` sound when the notification appears. Sound names are listed in `/System/Library/Sounds`. Use the special `NAME` “default” for the default notification sound. ------------------------------------------------------------------------------- `-group ID` Specifies the notification’s ‘group’. For any ‘group’, only _one_ notification will ever be shown, replacing previously posted notifications. A notification can be explicitly removed with the `-remove` option (see below). Example group IDs: * The sender’s name (to scope the notifications by tool). * The sender’s process ID (to scope the notifications by a unique process). * The current working directory (to scope notifications by project). ------------------------------------------------------------------------------- `-remove ID` **[required]** Remove a previous notification from the `ID` ‘group’, if one exists. Use the special `ID` “ALL” to remove all messages. ------------------------------------------------------------------------------- `-list ID` **[required]** Lists details about the specified ‘group’ `ID`. Use the special `ID` “ALL” to list details about all currently active messages. The output of this command is tab-separated, which makes it easy to parse. ------------------------------------------------------------------------------- `-activate ID` Activate the application specified by `ID` when the user clicks the notification. You can find the bundle identifier (`CFBundleIdentifier`) of an application in its `Info.plist` file _inside_ the application bundle. Examples application IDs are: * `com.apple.Terminal` to activate Terminal.app * `com.apple.Safari` to activate Safari.app ------------------------------------------------------------------------------- `-sender ID` Fakes the sender application of the notification. This uses the specified application’s icon, and will launch it when the notification is clicked. Using this option fakes the sender application, so that the notification system will launch that application when the notification is clicked. Because of this it is important to note that you cannot combine this with options like `-execute` and `-activate` which depend on the sender of the notification to be ‘terminal-notifier’ to perform its work. For information on the `ID`, see the `-activate` option. ------------------------------------------------------------------------------- `-appIcon PATH` Specify an image `PATH` to display instead of the application icon. **WARNING: This option is subject to change, since it relies on a private method.** ------------------------------------------------------------------------------- `-contentImage PATH` Specify an image `PATH` to attach inside of the notification. **WARNING: This option is subject to change since it relies on a private method.** ------------------------------------------------------------------------------- `-open URL` Open `URL` when the user clicks the notification. This can be a web or file URL, or any custom URL scheme. ------------------------------------------------------------------------------- `-execute COMMAND` Run the shell command `COMMAND` when the user clicks the notification. ------------------------------------------------------------------------------- `-ignoreDnD` Ignore Do Not Disturb settings and unconditionally show the notification. **WARNING: This option is subject to change since it relies on a private method.** ## License All the works are available under the MIT license. **Except** for ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is copyright of Apple. Copyright (C) 2012-2017 Eloy Durán , Julien Blanchard Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Ruby/Gemfile ================================================ source 'https://rubygems.org' gemspec ================================================ FILE: Ruby/LICENSE ================================================ All the works are available under the MIT license. **Except** for ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is copyright of Apple. Copyright (C) 2012-2013 Eloy Durán , Julien Blanchard Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Ruby/README.markdown ================================================ # TerminalNotifier A simple Ruby wrapper around the [`terminal-notifier`][HOMEPAGE] command-line tool, which allows you to send User Notifications to the Notification Center on macOS 10.10, or higher. ## Installation ``` $ gem install terminal-notifier ``` ## Usage For full information on all the options, see the tool’s [README][README]. Examples are: ```ruby TerminalNotifier.notify('Hello World') TerminalNotifier.notify('Hello World', :title => 'Ruby', :subtitle => 'Programming Language') TerminalNotifier.notify('Hello World', :activate => 'com.apple.Safari') TerminalNotifier.notify('Hello World', :open => 'http://twitter.com/julienXX') TerminalNotifier.notify('Hello World', :execute => 'say "OMG"') TerminalNotifier.notify('Hello World', :group => Process.pid) TerminalNotifier.notify('Hello World', :sender => 'com.apple.Safari') TerminalNotifier.notify('Hello World', :sound => 'default') TerminalNotifier.remove(Process.pid) TerminalNotifier.list(Process.pid) TerminalNotifier.list ``` ## License All the works are available under the MIT license. **Except** for ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is copyright of Apple. See [LICENSE][LICENSE] for details. [HOMEPAGE]: https://github.com/julienXX/terminal-notifier [README]: https://github.com/julienXX/terminal-notifier/blob/master/README.markdown [LICENSE]: https://github.com/julienXX/terminal-notifier/blob/master/Ruby/LICENSE ================================================ FILE: Ruby/Rakefile ================================================ def version @version ||= begin plist = File.expand_path('../../Terminal Notifier/Terminal Notifier-Info.plist', __FILE__) `/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' '#{plist}'`.strip end end def filename "terminal-notifier-#{version}" end def zipfile "#{version}.zip" end task :clean do rm zipfile rm_rf 'vendor' end desc 'Fetch latest build from the GitHub releases' task :update_build do unless File.exist?(zipfile) sh "curl -L -O 'https://github.com/julienXX/terminal-notifier/archive/#{zipfile}'" end rm_rf 'vendor' mkdir 'vendor' sh "unzip -o -d vendor #{zipfile}" mv "vendor/#{filename}", 'vendor/terminal-notifier' sh 'cd .. && xcodebuild -target terminal-notifier SYMROOT=build -verbose && cd -' mv '../build/Release/terminal-notifier.app', 'vendor/terminal-notifier/' chmod 0755, 'vendor/terminal-notifier/terminal-notifier.app/Contents/MacOS/terminal-notifier' end desc 'Build gem' task :gem => :update_build do sh 'gem build terminal-notifier.gemspec' end desc 'Run specs' task :spec do sh 'bundle exec ruby spec/terminal-notifier_spec.rb' end task :default => :spec ================================================ FILE: Ruby/bin/terminal-notifier ================================================ #!/usr/bin/env ruby if $0 == __FILE__ $:.unshift File.expand_path('../../lib', __FILE__) end require 'terminal-notifier' if !ARGV.include?("-message") && !STDIN.tty? ARGV.push(*["-message", STDIN.read.chomp]) end exec TerminalNotifier::BIN_PATH, *ARGV ================================================ FILE: Ruby/lib/terminal-notifier.rb ================================================ # coding: utf-8 require 'shellwords' require 'rbconfig' module TerminalNotifier BIN_PATH = File.expand_path('../../vendor/terminal-notifier/terminal-notifier.app/Contents/MacOS/terminal-notifier', __FILE__) class UnsupportedPlatformError < StandardError; end # Returns wether or not the current platform is macOS 10.10, or higher. def self.available? @available ||= (/darwin|mac os/ =~ RbConfig::CONFIG['host_os']) && Gem::Version.new(version) > Gem::Version.new('10.10') end def self.version @version ||= `uname`.strip == 'Darwin' && `sw_vers -productVersion`.strip end def self.execute(verbose, options) if available? command = [BIN_PATH, *options.map { |k,v| v = v.to_s; ["-#{k}", "#{v[0] == "-" ? " " : ""}#{Shellwords.escape(v[0,1])}#{v[1..-1]}"] }.flatten] command = Shellwords.join(command) if RUBY_VERSION < '1.9' result = '' IO.popen(command) do |stdout| output = stdout.read STDOUT.print output if verbose result << output end result else STDERR.print "terminal-notifier is only supported on macOS 10.10, or higher." end end # Cleans up the result of a notification, making it easier to work it # # The result of a notification is downcased, then groups of 1 or more # non-word characters are replaced with an underscore, before being # symbolised. # # If the reply option was given, then instead of going through the # above process, the result is returned with no changes as a string. # # If the always_string param is set to true, a the result is returned # with no changes as a string, like above. # # Examples are: # # notify_result('Test', {}) #=> :test # notify_result('No, sir', {}) #=> :no_sir # notify_result('@timeout', {}) #=> :_timeout # notify_result('@closeaction', {}) #=> :_closeaction # notify_result('I like pie', {reply: true}) #=> 'I like pie' # notify_result('I do not like pie', {'reply' => true}) #=> 'I do not like pie' # notify_result('@timeout', {'reply' => true}) #=> '@timeout' # notify_result('I may like pie', {}) #=> :i_may_like_pie def notify_result(result, options, always_string = false) if options[:reply] || options['reply'] || always_string result else result.length == 0 || result.downcase.gsub(/\W+/,'_').to_sym end end module_function :notify_result # Sends a User Notification and returns whether or not it was a success. # # The available options are `:title`, `:group`, `:activate`, `:open`, # `:execute`, `:sender`, and `:sound`. For a description of each option see: # # https://github.com/julienXX/terminal-notifier/blob/master/README.markdown # # Examples are: # # TerminalNotifier.notify('Hello World') # TerminalNotifier.notify('Hello World', :title => 'Ruby') # TerminalNotifier.notify('Hello World', :group => Process.pid) # TerminalNotifier.notify('Hello World', :activate => 'com.apple.Safari') # TerminalNotifier.notify('Hello World', :open => 'http://twitter.com/julienXX') # TerminalNotifier.notify('Hello World', :execute => 'say "OMG"') # TerminalNotifier.notify('Hello World', :sender => 'com.apple.Safari') # TerminalNotifier.notify('Hello World', :sound => 'default') # # Raises if not supported on the current platform. def notify(message, options = {}, verbose = false, always_string = false) result = TerminalNotifier.execute(verbose, options.merge(:message => message)) $? && $?.success? && notify_result(result, options, always_string) end module_function :notify # Removes a notification that was previously sent with the specified # ‘group’ ID, if one exists. # # If no ‘group’ ID is given, all notifications are removed. def remove(group = 'ALL', verbose = false) TerminalNotifier.execute(verbose, :remove => group) $? && $?.success? end module_function :remove LIST_FIELDS = [:group, :title, :subtitle, :message, :delivered_at].freeze # If a ‘group’ ID is given, and a notification for that group exists, # returns a hash with details about the notification. # # If no ‘group’ ID is given, an array of hashes describing all # notifications. # # If no information is available this will return `nil`. def list(group = 'ALL', verbose = false) output = TerminalNotifier.execute(verbose, :list => group) return if output.strip.empty? require 'time' notifications = output.split("\n")[1..-1].map do |line| LIST_FIELDS.zip(line.split("\t")).inject({}) do |hash, (key, value)| hash[key] = key == :delivered_at ? Time.parse(value) : (value unless value == '(null)') hash end end group == 'ALL' ? notifications : notifications.first end module_function :list end ================================================ FILE: Ruby/spec/terminal-notifier_spec.rb ================================================ require 'rubygems' require 'bacon' require 'mocha' require 'mocha-on-bacon' Bacon.summary_at_exit $:.unshift File.expand_path('../../lib', __FILE__) require 'terminal-notifier' describe "TerminalNotifier" do it "executes the tool with the given options and properly escapes the message" do command = [TerminalNotifier::BIN_PATH, '-message', '\[ZOMG] "OH YEAH"'] command = Shellwords.join(command) if RUBY_VERSION < '1.9' IO.expects(:popen).with(command).yields(StringIO.new('output')) TerminalNotifier.execute(false, :message => '[ZOMG] "OH YEAH"') end it "correctly escapes arguments that start with a dash" do command = [TerminalNotifier::BIN_PATH, '-message', ' -kittens', '-title', ' -rule'] command = Shellwords.join(command) if RUBY_VERSION < '1.9' IO.expects(:popen).with(command).yields(StringIO.new('output')) TerminalNotifier.execute(false, :message => '-kittens', :title => '-rule') end it "returns the result output of the command" do TerminalNotifier.execute(false, 'help' => '').should == `'#{TerminalNotifier::BIN_PATH}' -help` end it "sends a notification" do TerminalNotifier.expects(:execute).with(false, :message => 'ZOMG', :group => 'important stuff') TerminalNotifier.notify('ZOMG', :group => 'important stuff') end it "removes a notification" do TerminalNotifier.expects(:execute).with(false, :remove => 'important stuff') TerminalNotifier.remove('important stuff') end it "by default removes all the notifications" do TerminalNotifier.expects(:execute).with(false, :remove => 'ALL') TerminalNotifier.remove end it "returns `nil` if no notification was found to list info for" do TerminalNotifier.expects(:execute).with(false, :list => 'important stuff').returns('') TerminalNotifier.list('important stuff').should == nil end it "returns info about a notification posted in a specific group" do TerminalNotifier.expects(:execute).with(false, :list => 'important stuff'). returns("GroupID\tTitle\tSubtitle\tMessage\tDelivered At\n" \ "important stuff\tTerminal\t(null)\tExecute: rake spec\t2012-08-06 19:45:30 +0000") TerminalNotifier.list('important stuff').should == { :group => 'important stuff', :title => 'Terminal', :subtitle => nil, :message => 'Execute: rake spec', :delivered_at => Time.parse('2012-08-06 19:45:30 +0000') } end it "by default returns a list of all notification" do TerminalNotifier.expects(:execute).with(false, :list => 'ALL'). returns("GroupID\tTitle\tSubtitle\tMessage\tDelivered At\n" \ "important stuff\tTerminal\t(null)\tExecute: rake spec\t2012-08-06 19:45:30 +0000\n" \ "(null)\t(null)\tSubtle\tBe subtle!\t2012-08-07 19:45:30 +0000") TerminalNotifier.list.should == [ { :group => 'important stuff', :title => 'Terminal', :subtitle => nil, :message => 'Execute: rake spec', :delivered_at => Time.parse('2012-08-06 19:45:30 +0000') }, { :group => nil, :title => nil, :subtitle => 'Subtle', :message => 'Be subtle!', :delivered_at => Time.parse('2012-08-07 19:45:30 +0000') } ] end end ================================================ FILE: Ruby/terminal-notifier.gemspec ================================================ # -*- encoding: utf-8 -*- plist = File.expand_path('../../Terminal Notifier/Terminal Notifier-Info.plist', __FILE__) # Also run on non-OSX machines, otherwise bundle installs directly from the repo will fail. # version = `/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' '#{plist}'`.strip version = File.read(plist).match(%r{(\d+\.\d+\.\d+)})[1] Gem::Specification.new do |gem| gem.name = "terminal-notifier" gem.version = version gem.summary = 'Send User Notifications on macOS 10.10 or higher.' gem.authors = ["Eloy Duran", "Julien Blanchard"] gem.email = ["eloy.de.enige@gmail.com", "julien@sideburns.eu"] gem.homepage = 'https://github.com/julienXX/terminal-notifier' gem.license = 'MIT' gem.executables = ['terminal-notifier'] gem.files = ['bin/terminal-notifier', 'lib/terminal-notifier.rb'] + Dir.glob('vendor/terminal-notifier/**/*') gem.require_paths = ['lib'] gem.extra_rdoc_files = ['README.markdown'] gem.add_development_dependency 'bacon' gem.add_development_dependency 'mocha' gem.add_development_dependency 'mocha-on-bacon' end ================================================ FILE: Terminal Notifier/AppDelegate.h ================================================ #import @interface AppDelegate : NSObject @end ================================================ FILE: Terminal Notifier/AppDelegate.m ================================================ #import "AppDelegate.h" #import #import NSString * const TerminalNotifierBundleID = @"fr.julienxx.oss.terminal-notifier"; NSString * const NotificationCenterUIBundleID = @"com.apple.notificationcenterui"; NSString *_fakeBundleIdentifier = nil; @implementation NSBundle (FakeBundleIdentifier) // Overriding bundleIdentifier works, but overriding NSUserNotificationAlertStyle does not work. - (NSString *)__bundleIdentifier; { if (self == [NSBundle mainBundle]) { return _fakeBundleIdentifier ? _fakeBundleIdentifier : TerminalNotifierBundleID; } else { return [self __bundleIdentifier]; } } @end static BOOL InstallFakeBundleIdentifierHook() { Class class = objc_getClass("NSBundle"); if (class) { method_exchangeImplementations(class_getInstanceMethod(class, @selector(bundleIdentifier)), class_getInstanceMethod(class, @selector(__bundleIdentifier))); return YES; } return NO; } @implementation NSUserDefaults (SubscriptAndUnescape) - (id)objectForKeyedSubscript:(id)key; { id obj = [self objectForKey:key]; if ([obj isKindOfClass:[NSString class]] && [(NSString *)obj hasPrefix:@"\\"]) { obj = [(NSString *)obj substringFromIndex:1]; } return obj; } @end @implementation AppDelegate +(void)initializeUserDefaults { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // initialize the dictionary with default values depending on OS level NSDictionary *appDefaults; appDefaults = @{@"sender": @"com.apple.Terminal"}; // and set them appropriately [defaults registerDefaults:appDefaults]; } - (void)printHelpBanner; { const char *appName = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"] UTF8String]; const char *appVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] UTF8String]; printf("%s (%s) is a command-line tool to send macOS User Notifications.\n" \ "\n" \ "Usage: %s -[message|list|remove] [VALUE|ID|ID] [options]\n" \ "\n" \ " Either of these is required (unless message data is piped to the tool):\n" \ "\n" \ " -help Display this help banner.\n" \ " -version Display terminal-notifier version.\n" \ " -message VALUE The notification message.\n" \ " -remove ID Removes a notification with the specified ‘group’ ID.\n" \ " -list ID If the specified ‘group’ ID exists show when it was delivered,\n" \ " or use ‘ALL’ as ID to see all notifications.\n" \ " The output is a tab-separated list.\n" "\n" \ " Optional:\n" \ "\n" \ " -title VALUE The notification title. Defaults to ‘Terminal’.\n" \ " -subtitle VALUE The notification subtitle.\n" \ " -sound NAME The name of a sound to play when the notification appears. The names are listed\n" \ " in Sound Preferences. Use 'default' for the default notification sound.\n" \ " -group ID A string which identifies the group the notifications belong to.\n" \ " Old notifications with the same ID will be removed.\n" \ " -activate ID The bundle identifier of the application to activate when the user clicks the notification.\n" \ " -sender ID The bundle identifier of the application that should be shown as the sender, including its icon.\n" \ " -appIcon URL The URL of a image to display instead of the application icon (Mavericks+ only)\n" \ " -contentImage URL The URL of a image to display attached to the notification (Mavericks+ only)\n" \ " -open URL The URL of a resource to open when the user clicks the notification.\n" \ " -execute COMMAND A shell command to perform when the user clicks the notification.\n" \ " -ignoreDnD Send notification even if Do Not Disturb is enabled.\n" \ "\n" \ "When the user activates a notification, the results are logged to the system logs.\n" \ "Use Console.app to view these logs.\n" \ "\n" \ "Note that in some circumstances the first character of a message has to be escaped in order to be recognized.\n" \ "An example of this is when using an open bracket, which has to be escaped like so: ‘\\[’.\n" \ "\n" \ "For more information see https://github.com/julienXX/terminal-notifier.\n", appName, appVersion, appName); } - (void)printVersion; { const char *appName = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"] UTF8String]; const char *appVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] UTF8String]; printf("%s %s.\n", appName, appVersion); } - (void)applicationDidFinishLaunching:(NSNotification *)notification; { NSUserNotification *userNotification = notification.userInfo[NSApplicationLaunchUserNotificationKey]; if (userNotification) { [self userActivatedNotification:userNotification]; } else { if ([[[NSProcessInfo processInfo] arguments] indexOfObject:@"-help"] != NSNotFound) { [self printHelpBanner]; exit(0); } if ([[[NSProcessInfo processInfo] arguments] indexOfObject:@"-version"] != NSNotFound) { [self printVersion]; exit(0); } NSArray *runningProcesses = [[[NSWorkspace sharedWorkspace] runningApplications] valueForKey:@"bundleIdentifier"]; if ([runningProcesses indexOfObject:NotificationCenterUIBundleID] == NSNotFound) { NSLog(@"[!] Unable to post a notification for the current user (%@), as it has no running NotificationCenter instance.", NSUserName()); exit(1); } NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *subtitle = defaults[@"subtitle"]; NSString *message = defaults[@"message"]; NSString *remove = defaults[@"remove"]; NSString *list = defaults[@"list"]; NSString *sound = defaults[@"sound"]; // If there is no message and data is piped to the application, use that // instead. if (message == nil && !isatty(STDIN_FILENO)) { NSData *inputData = [NSData dataWithData:[[NSFileHandle fileHandleWithStandardInput] readDataToEndOfFile]]; message = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding]; } if (message == nil && remove == nil && list == nil) { [self printHelpBanner]; exit(1); } if (list) { [self listNotificationWithGroupID:list]; exit(0); } // Install the fake bundle ID hook so we can fake the sender. This also // needs to be done to be able to remove a message. if (defaults[@"sender"]) { @autoreleasepool { if (InstallFakeBundleIdentifierHook()) { _fakeBundleIdentifier = defaults[@"sender"]; } } } if (remove) { [self removeNotificationWithGroupID:remove]; if (message == nil || ([message length] == 0)) { exit(0); } } if (message) { NSMutableDictionary *options = [NSMutableDictionary dictionary]; if (defaults[@"activate"]) options[@"bundleID"] = defaults[@"activate"]; if (defaults[@"group"]) options[@"groupID"] = defaults[@"group"]; if (defaults[@"execute"]) options[@"command"] = defaults[@"execute"]; if (defaults[@"appIcon"]) options[@"appIcon"] = defaults[@"appIcon"]; if (defaults[@"contentImage"]) options[@"contentImage"] = defaults[@"contentImage"]; if (defaults[@"open"]) { NSURL *url = [NSURL URLWithString:defaults[@"open"]]; if ((url && url.scheme && url.host) || [url isFileURL]) { options[@"open"] = defaults[@"open"]; }else{ NSLog(@"'%@' is not a valid URI.", defaults[@"open"]); exit(1); } } if([[[NSProcessInfo processInfo] arguments] containsObject:@"-ignoreDnD"] == true) { options[@"ignoreDnD"] = @YES; } [self deliverNotificationWithTitle:defaults[@"title"] ?: @"Terminal" subtitle:subtitle message:message options:options sound:sound]; } } } - (NSImage*)getImageFromURL:(NSString *) url; { NSURL *imageURL = [NSURL URLWithString:url]; if([[imageURL scheme] length] == 0){ // Prefix 'file://' if no scheme imageURL = [NSURL fileURLWithPath:url]; } return [[NSImage alloc] initWithContentsOfURL:imageURL]; } /** * Decode fragment identifier * * @see http://tools.ietf.org/html/rfc3986#section-2.1 * @see http://en.wikipedia.org/wiki/URI_scheme */ - (NSString*)decodeFragmentInURL:(NSString *) encodedURL fragment:(NSString *) framgent { NSString *beforeStr = [@"%23" stringByAppendingString:framgent]; NSString *afterStr = [@"#" stringByAppendingString:framgent]; NSString *decodedURL = [encodedURL stringByReplacingOccurrencesOfString:beforeStr withString:afterStr]; return decodedURL; } - (void)deliverNotificationWithTitle:(NSString *)title subtitle:(NSString *)subtitle message:(NSString *)message options:(NSDictionary *)options sound:(NSString *)sound; { // First remove earlier notification with the same group ID. if (options[@"groupID"]) [self removeNotificationWithGroupID:options[@"groupID"]]; NSUserNotification *userNotification = [NSUserNotification new]; userNotification.title = title; userNotification.subtitle = subtitle; userNotification.informativeText = message; userNotification.userInfo = options; if(options[@"appIcon"]){ [userNotification setValue:[self getImageFromURL:options[@"appIcon"]] forKey:@"_identityImage"]; [userNotification setValue:@(false) forKey:@"_identityImageHasBorder"]; } if(options[@"contentImage"]){ userNotification.contentImage = [self getImageFromURL:options[@"contentImage"]]; } if (sound != nil) { userNotification.soundName = [sound isEqualToString: @"default"] ? NSUserNotificationDefaultSoundName : sound ; } if(options[@"ignoreDnD"]){ [userNotification setValue:@YES forKey:@"_ignoresDoNotDisturb"]; } NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; center.delegate = self; [center scheduleNotification:userNotification]; } - (void)removeNotificationWithGroupID:(NSString *)groupID; { NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; for (NSUserNotification *userNotification in center.deliveredNotifications) { if ([@"ALL" isEqualToString:groupID] || [userNotification.userInfo[@"groupID"] isEqualToString:groupID]) { NSString *deliveredAt = [userNotification.actualDeliveryDate description]; printf("* Removing previously sent notification, which was sent on: %s\n", [deliveredAt UTF8String]); [center removeDeliveredNotification:userNotification]; } } } - (void)listNotificationWithGroupID:(NSString *)listGroupID; { NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; NSMutableArray *lines = [NSMutableArray array]; for (NSUserNotification *userNotification in center.deliveredNotifications) { NSString *deliveredgroupID = userNotification.userInfo[@"groupID"]; NSString *title = userNotification.title; NSString *subtitle = userNotification.subtitle; NSString *message = userNotification.informativeText; NSString *deliveredAt = [userNotification.actualDeliveryDate description]; if ([@"ALL" isEqualToString:listGroupID] || [deliveredgroupID isEqualToString:listGroupID]) { [lines addObject:[NSString stringWithFormat:@"%@\t%@\t%@\t%@\t%@", deliveredgroupID, title, subtitle, message, deliveredAt]]; } } if (lines.count > 0) { printf("GroupID\tTitle\tSubtitle\tMessage\tDelivered At\n"); for (NSString *line in lines) { printf("%s\n", [line UTF8String]); } } } - (void)userActivatedNotification:(NSUserNotification *)userNotification; { [[NSUserNotificationCenter defaultUserNotificationCenter] removeDeliveredNotification:userNotification]; NSString *groupID = userNotification.userInfo[@"groupID"]; NSString *bundleID = userNotification.userInfo[@"bundleID"]; NSString *command = userNotification.userInfo[@"command"]; NSString *open = userNotification.userInfo[@"open"]; NSLog(@"User activated notification:"); NSLog(@" group ID: %@", groupID); NSLog(@" title: %@", userNotification.title); NSLog(@" subtitle: %@", userNotification.subtitle); NSLog(@" message: %@", userNotification.informativeText); NSLog(@"bundle ID: %@", bundleID); NSLog(@" command: %@", command); NSLog(@" open: %@", open); BOOL success = YES; if (bundleID) success &= [self activateAppWithBundleID:bundleID]; if (command) success &= [self executeShellCommand:command]; if (open) success &= [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:open]]; exit(success ? 0 : 1); } - (BOOL)activateAppWithBundleID:(NSString *)bundleID; { id app = [SBApplication applicationWithBundleIdentifier:bundleID]; if (app) { [app activate]; return YES; } else { NSLog(@"Unable to find an application with the specified bundle indentifier."); return NO; } } - (BOOL)executeShellCommand:(NSString *)command; { NSPipe *pipe = [NSPipe pipe]; NSFileHandle *fileHandle = [pipe fileHandleForReading]; NSTask *task = [NSTask new]; task.launchPath = @"/bin/sh"; task.arguments = @[@"-c", command]; task.standardOutput = pipe; task.standardError = pipe; [task launch]; NSData *data = nil; NSMutableData *accumulatedData = [NSMutableData data]; while ((data = [fileHandle availableData]) && [data length]) { [accumulatedData appendData:data]; } [task waitUntilExit]; NSLog(@"command output:\n%@", [[NSString alloc] initWithData:accumulatedData encoding:NSUTF8StringEncoding]); return [task terminationStatus] == 0; } - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)userNotification; { return YES; } // Once the notification is delivered we can exit. - (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)userNotification; { exit(0); } @end ================================================ FILE: Terminal Notifier/Terminal Notifier-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile Terminal CFBundleIdentifier fr.julienxx.oss.terminal-notifier CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString 2.0.0 CFBundleSignature ???? CFBundleVersion 15 LSMinimumSystemVersion 10.10 LSUIElement NSHumanReadableCopyright Copyright © 2012-2017 Eloy Durán, Julien Blanchard. All rights reserved. NSMainNibFile MainMenu NSPrincipalClass NSApplication NSAppTransportSecurity NSAllowsArbitraryLoads NSUserNotificationAlertStyle banner ================================================ FILE: Terminal Notifier/Terminal Notifier-Prefix.pch ================================================ // // Prefix header for all source files of the 'Terminal Notifier' target in the 'Terminal Notifier' project // #ifdef __OBJC__ #import #endif ================================================ FILE: Terminal Notifier/en.lproj/Credits.rtf ================================================ {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} {\colortbl;\red255\green255\blue255;} \paperw9840\paperh8400 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural \f0\b\fs24 \cf0 Engineering: \b0 \ Some people\ \ \b Human Interface Design: \b0 \ Some other people\ \ \b Testing: \b0 \ Hopefully not nobody\ \ \b Documentation: \b0 \ Whoever\ \ \b With special thanks to: \b0 \ Mom\ } ================================================ FILE: Terminal Notifier/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: Terminal Notifier/en.lproj/MainMenu.xib ================================================ 1080 14A388a 6250 1343.14 755.00 com.apple.InterfaceBuilder.CocoaPlugin 6250 NSCustomObject NSMenu NSMenuItem com.apple.InterfaceBuilder.CocoaPlugin PluginDependencyRecalculationVersion NSApplication FirstResponder NSApplication AMainMenu Terminal Notifier 1048576 2147483647 NSImage NSMenuCheckmark NSImage NSMenuMixedState submenuAction: Terminal Notifier About Terminal Notifier 2147483647 YES YES 1048576 2147483647 Preferences… , 1048576 2147483647 YES YES 1048576 2147483647 Services 1048576 2147483647 submenuAction: Services _NSServicesMenu YES YES 1048576 2147483647 Hide Terminal Notifier h 1048576 2147483647 Hide Others h 1572864 2147483647 Show All 1048576 2147483647 YES YES 1048576 2147483647 Quit Terminal Notifier q 1048576 2147483647 _NSAppleMenu File 1048576 2147483647 submenuAction: File New n 1048576 2147483647 Open… o 1048576 2147483647 Open Recent 1048576 2147483647 submenuAction: Open Recent Clear Menu 1048576 2147483647 _NSRecentDocumentsMenu YES YES 1048576 2147483647 Close w 1048576 2147483647 Save… s 1048576 2147483647 Revert to Saved 2147483647 YES YES 1048576 2147483647 Page Setup... P 1179648 2147483647 Print… p 1048576 2147483647 Edit 1048576 2147483647 submenuAction: Edit Undo z 1048576 2147483647 Redo Z 1179648 2147483647 YES YES 1048576 2147483647 Cut x 1048576 2147483647 Copy c 1048576 2147483647 Paste v 1048576 2147483647 Paste and Match Style V 1572864 2147483647 Delete 1048576 2147483647 Select All a 1048576 2147483647 YES YES 1048576 2147483647 Find 1048576 2147483647 submenuAction: Find Find… f 1048576 2147483647 1 Find and Replace… f 1572864 2147483647 12 Find Next g 1048576 2147483647 2 Find Previous G 1179648 2147483647 3 Use Selection for Find e 1048576 2147483647 7 Jump to Selection j 1048576 2147483647 Spelling and Grammar 1048576 2147483647 submenuAction: Spelling and Grammar Show Spelling and Grammar : 1048576 2147483647 Check Document Now ; 1048576 2147483647 YES YES 2147483647 Check Spelling While Typing 1048576 2147483647 Check Grammar With Spelling 1048576 2147483647 Correct Spelling Automatically 2147483647 Substitutions 1048576 2147483647 submenuAction: Substitutions Show Substitutions 2147483647 YES YES 2147483647 Smart Copy/Paste f 1048576 2147483647 1 Smart Quotes g 1048576 2147483647 2 Smart Dashes 2147483647 Smart Links G 1179648 2147483647 3 Text Replacement 2147483647 Transformations 2147483647 submenuAction: Transformations Make Upper Case 2147483647 Make Lower Case 2147483647 Capitalize 2147483647 Speech 1048576 2147483647 submenuAction: Speech Start Speaking 1048576 2147483647 Stop Speaking 1048576 2147483647 Format 2147483647 submenuAction: Format Font 2147483647 submenuAction: Font Show Fonts t 1048576 2147483647 Bold b 1048576 2147483647 2 Italic i 1048576 2147483647 1 Underline u 1048576 2147483647 YES YES 2147483647 Bigger + 1048576 2147483647 3 Smaller - 1048576 2147483647 4 YES YES 2147483647 Kern 2147483647 submenuAction: Kern Use Default 2147483647 Use None 2147483647 Tighten 2147483647 Loosen 2147483647 Ligatures 2147483647 submenuAction: Ligatures Use Default 2147483647 Use None 2147483647 Use All 2147483647 Baseline 2147483647 submenuAction: Baseline Use Default 2147483647 Superscript 2147483647 Subscript 2147483647 Raise 2147483647 Lower 2147483647 YES YES 2147483647 Show Colors C 1048576 2147483647 YES YES 2147483647 Copy Style c 1572864 2147483647 Paste Style v 1572864 2147483647 _NSFontMenu Text 2147483647 submenuAction: Text Align Left { 1048576 2147483647 Center | 1048576 2147483647 Justify 2147483647 Align Right } 1048576 2147483647 YES YES 2147483647 Writing Direction 2147483647 submenuAction: Writing Direction YES Paragraph 2147483647 CURlZmF1bHQ 2147483647 CUxlZnQgdG8gUmlnaHQ 2147483647 CVJpZ2h0IHRvIExlZnQ 2147483647 YES YES 2147483647 YES Selection 2147483647 CURlZmF1bHQ 2147483647 CUxlZnQgdG8gUmlnaHQ 2147483647 CVJpZ2h0IHRvIExlZnQ 2147483647 YES YES 2147483647 Show Ruler 2147483647 Copy Ruler c 1310720 2147483647 Paste Ruler v 1310720 2147483647 View 1048576 2147483647 submenuAction: View Show Toolbar t 1572864 2147483647 Customize Toolbar… 1048576 2147483647 Window 1048576 2147483647 submenuAction: Window Minimize m 1048576 2147483647 Zoom 1048576 2147483647 YES YES 1048576 2147483647 Bring All to Front 1048576 2147483647 _NSWindowsMenu Help 2147483647 submenuAction: Help Terminal Notifier Help ? 1048576 2147483647 _NSHelpMenu _NSMainMenu AppDelegate NSFontManager terminate: 449 orderFrontStandardAboutPanel: 142 delegate 495 performMiniaturize: 37 arrangeInFront: 39 print: 86 runPageLayout: 87 clearRecentDocuments: 127 performClose: 193 toggleContinuousSpellChecking: 222 undo: 223 copy: 224 checkSpelling: 225 paste: 226 stopSpeaking: 227 cut: 228 showGuessPanel: 230 redo: 231 selectAll: 232 startSpeaking: 233 delete: 235 performZoom: 240 performFindPanelAction: 241 centerSelectionInVisibleArea: 245 toggleGrammarChecking: 347 toggleSmartInsertDelete: 355 toggleAutomaticQuoteSubstitution: 356 toggleAutomaticLinkDetection: 357 saveDocument: 362 revertDocumentToSaved: 364 runToolbarCustomizationPalette: 365 toggleToolbarShown: 366 hide: 367 hideOtherApplications: 368 unhideAllApplications: 370 newDocument: 373 openDocument: 374 raiseBaseline: 426 lowerBaseline: 427 copyFont: 428 subscript: 429 superscript: 430 tightenKerning: 431 underline: 432 orderFrontColorPanel: 433 useAllLigatures: 434 loosenKerning: 435 pasteFont: 436 unscript: 437 useStandardKerning: 438 useStandardLigatures: 439 turnOffLigatures: 440 turnOffKerning: 441 toggleAutomaticSpellingCorrection: 456 orderFrontSubstitutionsPanel: 458 toggleAutomaticDashSubstitution: 461 toggleAutomaticTextReplacement: 463 uppercaseWord: 464 capitalizeWord: 467 lowercaseWord: 468 pasteAsPlainText: 486 performFindPanelAction: 487 performFindPanelAction: 488 performFindPanelAction: 489 showHelp: 493 alignCenter: 518 pasteRuler: 519 toggleRuler: 520 alignRight: 521 copyRuler: 522 alignJustified: 523 alignLeft: 524 makeBaseWritingDirectionNatural: 525 makeBaseWritingDirectionLeftToRight: 526 makeBaseWritingDirectionRightToLeft: 527 makeTextWritingDirectionNatural: 528 makeTextWritingDirectionLeftToRight: 529 makeTextWritingDirectionRightToLeft: 530 performFindPanelAction: 535 addFontTrait: 421 addFontTrait: 422 modifyFont: 423 orderFrontFontPanel: 424 modifyFont: 425 0 -2 File's Owner -1 First Responder -3 Application 29 19 56 217 83 81 75 78 72 82 124 77 73 79 112 74 125 126 205 202 198 207 214 199 203 197 206 215 218 216 200 219 201 204 220 213 210 221 208 209 57 58 134 150 136 144 129 143 236 131 149 145 130 24 92 5 239 23 295 296 297 298 211 212 195 196 346 348 349 350 351 354 375 376 377 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 450 451 452 453 454 457 459 460 462 465 466 485 490 491 492 494 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 534 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin 535 AppDelegate NSObject IBProjectSource ../Terminal Notifier/AppDelegate.h NSApplication NSResponder IBFrameworkSource AppKit.framework/Headers/NSApplication.h NSBrowser NSControl IBFrameworkSource AppKit.framework/Headers/NSBrowser.h NSControl NSView IBFrameworkSource AppKit.framework/Headers/NSControl.h NSDocument NSObject id id id id id id printDocument: id revertDocumentToSaved: id runPageLayout: id saveDocument: id saveDocumentAs: id saveDocumentTo: id IBFrameworkSource AppKit.framework/Headers/NSDocument.h NSDocumentController NSObject id id id id clearRecentDocuments: id newDocument: id openDocument: id saveAllDocuments: id IBFrameworkSource AppKit.framework/Headers/NSDocumentController.h NSFontManager NSObject IBFrameworkSource AppKit.framework/Headers/NSFontManager.h NSFormatter NSObject IBFrameworkSource Foundation.framework/Headers/NSFormatter.h NSMatrix NSControl IBFrameworkSource AppKit.framework/Headers/NSMatrix.h NSMenu NSObject IBFrameworkSource AppKit.framework/Headers/NSMenu.h NSMenuItem NSObject IBFrameworkSource AppKit.framework/Headers/NSMenuItem.h NSMovieView NSView IBFrameworkSource AppKit.framework/Headers/NSMovieView.h NSPopover NSResponder IBFrameworkSource AppKit.framework/Headers/NSPopover.h NSResponder NSObject IBFrameworkSource AppKit.framework/Headers/NSResponder.h NSTableView NSControl IBFrameworkSource AppKit.framework/Headers/NSTableView.h NSText NSView IBFrameworkSource AppKit.framework/Headers/NSText.h NSTextView NSText IBFrameworkSource AppKit.framework/Headers/NSTextView.h NSView NSResponder IBFrameworkSource AppKit.framework/Headers/NSView.h NSViewController NSResponder view NSView view view NSView IBFrameworkSource AppKit.framework/Headers/NSViewController.h NSWindow NSResponder IBFrameworkSource AppKit.framework/Headers/NSWindow.h 0 IBCocoaFramework NO com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 YES 3 {12, 12} {10, 2} YES ================================================ FILE: Terminal Notifier/main.m ================================================ #import int main(int argc, char *argv[]) { return NSApplicationMain(argc, (const char **)argv); } ================================================ FILE: Terminal Notifier.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 5199791915B1F92B003AFC57 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5199791815B1F92B003AFC57 /* Cocoa.framework */; }; 5199792315B1F92B003AFC57 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5199792115B1F92B003AFC57 /* InfoPlist.strings */; }; 5199792515B1F92B003AFC57 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5199792415B1F92B003AFC57 /* main.m */; }; 5199792915B1F92B003AFC57 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5199792715B1F92B003AFC57 /* Credits.rtf */; }; 5199792C15B1F92B003AFC57 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5199792B15B1F92B003AFC57 /* AppDelegate.m */; }; 5199792F15B1F92B003AFC57 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5199792D15B1F92B003AFC57 /* MainMenu.xib */; }; 5199794215B2F908003AFC57 /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5199794115B2F908003AFC57 /* ScriptingBridge.framework */; }; 5199794C15B302F1003AFC57 /* Terminal.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5199794B15B302F1003AFC57 /* Terminal.icns */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 5199791415B1F92B003AFC57 /* terminal-notifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "terminal-notifier.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 5199791815B1F92B003AFC57 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 5199791B15B1F92B003AFC57 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 5199791C15B1F92B003AFC57 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 5199791D15B1F92B003AFC57 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 5199792015B1F92B003AFC57 /* Terminal Notifier-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Terminal Notifier-Info.plist"; sourceTree = ""; }; 5199792215B1F92B003AFC57 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5199792415B1F92B003AFC57 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 5199792615B1F92B003AFC57 /* Terminal Notifier-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Terminal Notifier-Prefix.pch"; sourceTree = ""; }; 5199792815B1F92B003AFC57 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 5199792A15B1F92B003AFC57 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 5199792B15B1F92B003AFC57 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 5199792E15B1F92B003AFC57 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 5199794115B2F908003AFC57 /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = System/Library/Frameworks/ScriptingBridge.framework; sourceTree = SDKROOT; }; 5199794B15B302F1003AFC57 /* Terminal.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Terminal.icns; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 5199791115B1F92B003AFC57 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 5199794215B2F908003AFC57 /* ScriptingBridge.framework in Frameworks */, 5199791915B1F92B003AFC57 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5199790915B1F92B003AFC57 = { isa = PBXGroup; children = ( 5199794B15B302F1003AFC57 /* Terminal.icns */, 5199794115B2F908003AFC57 /* ScriptingBridge.framework */, 5199791E15B1F92B003AFC57 /* Terminal Notifier */, 5199791715B1F92B003AFC57 /* Frameworks */, 5199791515B1F92B003AFC57 /* Products */, ); sourceTree = ""; }; 5199791515B1F92B003AFC57 /* Products */ = { isa = PBXGroup; children = ( 5199791415B1F92B003AFC57 /* terminal-notifier.app */, ); name = Products; sourceTree = ""; }; 5199791715B1F92B003AFC57 /* Frameworks */ = { isa = PBXGroup; children = ( 5199791815B1F92B003AFC57 /* Cocoa.framework */, 5199791A15B1F92B003AFC57 /* Other Frameworks */, ); name = Frameworks; sourceTree = ""; }; 5199791A15B1F92B003AFC57 /* Other Frameworks */ = { isa = PBXGroup; children = ( 5199791B15B1F92B003AFC57 /* AppKit.framework */, 5199791C15B1F92B003AFC57 /* CoreData.framework */, 5199791D15B1F92B003AFC57 /* Foundation.framework */, ); name = "Other Frameworks"; sourceTree = ""; }; 5199791E15B1F92B003AFC57 /* Terminal Notifier */ = { isa = PBXGroup; children = ( 5199792A15B1F92B003AFC57 /* AppDelegate.h */, 5199792B15B1F92B003AFC57 /* AppDelegate.m */, 5199792D15B1F92B003AFC57 /* MainMenu.xib */, 5199791F15B1F92B003AFC57 /* Supporting Files */, ); path = "Terminal Notifier"; sourceTree = ""; }; 5199791F15B1F92B003AFC57 /* Supporting Files */ = { isa = PBXGroup; children = ( 5199792015B1F92B003AFC57 /* Terminal Notifier-Info.plist */, 5199792115B1F92B003AFC57 /* InfoPlist.strings */, 5199792415B1F92B003AFC57 /* main.m */, 5199792615B1F92B003AFC57 /* Terminal Notifier-Prefix.pch */, 5199792715B1F92B003AFC57 /* Credits.rtf */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 5199791315B1F92B003AFC57 /* terminal-notifier */ = { isa = PBXNativeTarget; buildConfigurationList = 5199793215B1F92B003AFC57 /* Build configuration list for PBXNativeTarget "terminal-notifier" */; buildPhases = ( 5199791015B1F92B003AFC57 /* Sources */, 5199791115B1F92B003AFC57 /* Frameworks */, 5199791215B1F92B003AFC57 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "terminal-notifier"; productName = "Terminal Notifier"; productReference = 5199791415B1F92B003AFC57 /* terminal-notifier.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 5199790B15B1F92B003AFC57 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0440; ORGANIZATIONNAME = "Eloy Durán"; }; buildConfigurationList = 5199790E15B1F92B003AFC57 /* Build configuration list for PBXProject "Terminal Notifier" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = 5199790915B1F92B003AFC57; productRefGroup = 5199791515B1F92B003AFC57 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 5199791315B1F92B003AFC57 /* terminal-notifier */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 5199791215B1F92B003AFC57 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 5199792315B1F92B003AFC57 /* InfoPlist.strings in Resources */, 5199792915B1F92B003AFC57 /* Credits.rtf in Resources */, 5199792F15B1F92B003AFC57 /* MainMenu.xib in Resources */, 5199794C15B302F1003AFC57 /* Terminal.icns in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 5199791015B1F92B003AFC57 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 5199792515B1F92B003AFC57 /* main.m in Sources */, 5199792C15B1F92B003AFC57 /* AppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 5199792115B1F92B003AFC57 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 5199792215B1F92B003AFC57 /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; 5199792715B1F92B003AFC57 /* Credits.rtf */ = { isa = PBXVariantGroup; children = ( 5199792815B1F92B003AFC57 /* en */, ); name = Credits.rtf; sourceTree = ""; }; 5199792D15B1F92B003AFC57 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( 5199792E15B1F92B003AFC57 /* en */, ); name = MainMenu.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 5199793015B1F92B003AFC57 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; }; 5199793115B1F92B003AFC57 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; SDKROOT = macosx; }; name = Release; }; 5199793315B1F92B003AFC57 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Terminal Notifier/Terminal Notifier-Prefix.pch"; INFOPLIST_FILE = "Terminal Notifier/Terminal Notifier-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SDKROOT = macosx; WRAPPER_EXTENSION = app; }; name = Debug; }; 5199793415B1F92B003AFC57 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Terminal Notifier/Terminal Notifier-Prefix.pch"; INFOPLIST_FILE = "Terminal Notifier/Terminal Notifier-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SDKROOT = macosx; WRAPPER_EXTENSION = app; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 5199790E15B1F92B003AFC57 /* Build configuration list for PBXProject "Terminal Notifier" */ = { isa = XCConfigurationList; buildConfigurations = ( 5199793015B1F92B003AFC57 /* Debug */, 5199793115B1F92B003AFC57 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 5199793215B1F92B003AFC57 /* Build configuration list for PBXNativeTarget "terminal-notifier" */ = { isa = XCConfigurationList; buildConfigurations = ( 5199793315B1F92B003AFC57 /* Debug */, 5199793415B1F92B003AFC57 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 5199790B15B1F92B003AFC57 /* Project object */; } ================================================ FILE: Terminal Notifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Terminal Notifier.xcodeproj/project.xcworkspace/xcshareddata/Terminal Notifier.xccheckout ================================================ IDESourceControlProjectFavoriteDictionaryKey IDESourceControlProjectIdentifier A55309C1-2ABD-460A-B080-5A322DCAF4B5 IDESourceControlProjectName Terminal Notifier IDESourceControlProjectOriginsDictionary 9F67DD19109869B0F5A85172DA9B0D3E8F7EF383 github.com:julienXX/terminal-notifier.git IDESourceControlProjectPath Terminal Notifier.xcodeproj IDESourceControlProjectRelativeInstallPathDictionary 9F67DD19109869B0F5A85172DA9B0D3E8F7EF383 ../.. IDESourceControlProjectURL github.com:julienXX/terminal-notifier.git IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier 9F67DD19109869B0F5A85172DA9B0D3E8F7EF383 IDESourceControlProjectWCConfigurations IDESourceControlRepositoryExtensionIdentifierKey public.vcs.git IDESourceControlWCCIdentifierKey 9F67DD19109869B0F5A85172DA9B0D3E8F7EF383 IDESourceControlWCCName terminal-notifier ================================================ FILE: Terminal Notifier.xcodeproj/xcshareddata/xcschemes/Terminal Notifier.xcscheme ================================================