├── Resources ├── Preferences │ ├── Preferences.tiff │ ├── Info.plist │ └── Base.lproj │ │ └── Preferences.xib └── EmojiIM │ ├── InputMethodIcon.tiff │ ├── InputMethodIcon@2x.tiff │ ├── Base.lproj │ ├── InfoPlist.strings │ └── MainMenu.xib │ ├── EmojiIM.entitlements │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ └── Info.plist ├── fastlane ├── Gymfile ├── Scanfile ├── embed_buildinfo ├── Appfile ├── Fastfile └── README.md ├── docs └── sushi.gif ├── Gemfile ├── EmojiIM.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── EmojiIM.xcscheme └── project.pbxproj ├── Scripts └── emoji.rb ├── EmojiIM.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── Sources ├── Automaton │ ├── InputMethodState.swift │ ├── Mapping │ │ ├── NormalMapping.swift │ │ ├── SelectionMapping.swift │ │ ├── MappingDefinition.swift │ │ └── ComposingMapping.swift │ ├── EmojiAutomaton.swift │ ├── UserInput.swift │ └── ReactiveAutomaton+Action.swift ├── BridgeHeader.h ├── Extension │ ├── Collection+Every.swift │ ├── NSTextField+Label.swift │ └── TISInputSource+Property.swift ├── AppDelegate.swift ├── Setting │ └── SettingStore.swift ├── Dictionary │ └── EmojiDictionary.swift ├── Preferences │ └── Preferences.swift └── InputMethodKit │ └── EmojiInputController.swift ├── Podfile ├── .gitignore ├── Tests ├── Info.plist ├── Extension │ └── TISInputSourceTest.swift ├── Dictionary │ └── EmojiDictionaryTest.swift ├── Tests.swift └── Automaton │ └── AutomatonTest.swift ├── .swiftlint.yml ├── LICENSE ├── Podfile.lock ├── bitrise.yml ├── README.md └── Gemfile.lock /Resources/Preferences/Preferences.tiff: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fastlane/Gymfile: -------------------------------------------------------------------------------- 1 | scheme 'EmojiIM' 2 | output_directory './Build' 3 | -------------------------------------------------------------------------------- /docs/sushi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mzp/EmojiIM/HEAD/docs/sushi.gif -------------------------------------------------------------------------------- /Resources/EmojiIM/InputMethodIcon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mzp/EmojiIM/HEAD/Resources/EmojiIM/InputMethodIcon.tiff -------------------------------------------------------------------------------- /Resources/EmojiIM/InputMethodIcon@2x.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mzp/EmojiIM/HEAD/Resources/EmojiIM/InputMethodIcon@2x.tiff -------------------------------------------------------------------------------- /fastlane/Scanfile: -------------------------------------------------------------------------------- 1 | workspace 'EmojiIM.xcworkspace' 2 | scheme 'EmojiIM' 3 | configuration 'Release' 4 | output_directory 'Reports' 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | source "https://rubygems.org" 3 | 4 | gem 'cocoapods' 5 | gem 'fastlane' 6 | gem 'gemoji' 7 | gem 'xcode-install' 8 | -------------------------------------------------------------------------------- /Resources/EmojiIM/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | CFBundleName = "Emoji IM"; 2 | 3 | com.apple.inputmethod.Roman = "Emoji(Alphabet)"; 4 | 5 | jp.mzp.inputmethod.EmojiIM = "Emoji"; 6 | -------------------------------------------------------------------------------- /EmojiIM.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fastlane/embed_buildinfo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "let kRevision = \"$(git rev-parse HEAD)\"" > $(pwd)/$(git rev-parse --show-cdup)/BuildInfo.swift 3 | echo "let kBuiltDate = \"$(date)\"" >> $(pwd)/$(git rev-parse --show-cdup)/BuildInfo.swift 4 | -------------------------------------------------------------------------------- /Scripts/emoji.rb: -------------------------------------------------------------------------------- 1 | require 'gemoji' 2 | require 'json' 3 | 4 | entries = Emoji.all.flat_map do |emoji| 5 | next [] unless emoji.raw 6 | emoji.aliases.map do |name| 7 | { name: ":#{name}:", emoji: emoji.raw } 8 | end 9 | end 10 | puts JSON.pretty_generate(entries) 11 | -------------------------------------------------------------------------------- /EmojiIM.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /EmojiIM.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sources/Automaton/InputMethodState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InputMethodState.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/19. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | internal enum InputMethodState { 10 | case composing 11 | case normal 12 | case selection 13 | } 14 | -------------------------------------------------------------------------------- /EmojiIM.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Latest 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sources/BridgeHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // BridgeHeader.h 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/11/12. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | #ifndef BridgeHeader_h 10 | #define BridgeHeader_h 11 | 12 | #include 13 | 14 | extern const CFStringRef kTISPropertyScriptCode; 15 | 16 | #endif /* BridgeHeader_h */ 17 | -------------------------------------------------------------------------------- /Sources/Extension/Collection+Every.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Collection+Every.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | extension Collection { 10 | func every(where predicate: @escaping (Element) -> Bool) -> Bool { 11 | return !contains { !predicate($0) } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier "" # The bundle identifier of your app 2 | apple_id "mzpppp+apple@gmail.com" # Your Apple email address 3 | 4 | team_id "[[DEV_PORTAL_TEAM_ID]]" # Developer Portal Team ID 5 | 6 | # you can even provide different app identifiers, Apple IDs and team names per lane: 7 | # More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md 8 | -------------------------------------------------------------------------------- /Sources/Extension/NSTextField+Label.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSTextField+Label.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/11/12. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | import Ikemen 9 | 10 | extension NSTextField { 11 | class func label(text: String) -> NSTextField { 12 | return NSTextField() ※ { 13 | $0.stringValue = text 14 | $0.drawsBackground = false 15 | $0.isBordered = false 16 | $0.isEditable = false 17 | $0.isSelectable = false 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Resources/EmojiIM/EmojiIM.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.temporary-exception.mach-register.global-name 8 | jp.mzp.inputmethod.EmojiIM_Connection 9 | com.apple.security.temporary-exception.shared-preference.read-only 10 | jp.mzp.inputmethod.EmojiIM 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sources/Automaton/Mapping/NormalMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NormalMapping.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import ReactiveAutomaton 10 | 11 | internal class NormalMapping: MappingDefinition { 12 | func mapping(context: MappingContext) -> [ActionMapping] { 13 | return [ 14 | UserInput.typeof(.colon) <|> .normal => .composing <|> { _ in 15 | context.markedText.swap(":") 16 | context.candidates.swap([]) 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | abstract_target 'App' do 4 | use_frameworks! 5 | pod 'NorthLayout' 6 | pod 'ReactiveAutomaton' 7 | pod 'ReactiveCocoa' 8 | pod 'ReactiveSwift' 9 | pod 'Result' 10 | pod '※ikemen' 11 | 12 | target 'EmojiIM' 13 | target 'Preferences' 14 | 15 | target 'Tests' 16 | end 17 | 18 | pod 'SwiftLint' 19 | 20 | LegacySwiftPods = %w(ReactiveCocoa ReactiveSwift ReactiveAutomaton) 21 | 22 | post_install do |installer| 23 | installer.pods_project.targets.each do |target| 24 | target.build_configurations.each do |config| 25 | if LegacySwiftPods.include? target.name 26 | config.build_settings['SWIFT_VERSION'] = '3.0' 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /Pods 2 | 3 | # Fastlane 4 | /fastlane/README.md 5 | /fastlane/report.xml 6 | /fastlane/test_output 7 | 8 | ### https://raw.github.com/github/gitignore/0f88fa75def7ed7d96935b8630793e51953df9b0/Global/xcode.gitignore 9 | 10 | # Xcode 11 | # 12 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 13 | 14 | ## Build generated 15 | /Reports 16 | /BuildInfo.swift 17 | build/ 18 | DerivedData/ 19 | 20 | ## Various settings 21 | *.pbxuser 22 | !default.pbxuser 23 | *.mode1v3 24 | !default.mode1v3 25 | *.mode2v3 26 | !default.mode2v3 27 | *.perspectivev3 28 | !default.perspectivev3 29 | xcuserdata/ 30 | 31 | ## Other 32 | *.moved-aside 33 | *.xccheckout 34 | *.xcscmblueprint 35 | 36 | 37 | -------------------------------------------------------------------------------- /Sources/Automaton/Mapping/SelectionMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionMapping.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import ReactiveAutomaton 10 | 11 | internal class SelectionMapping: MappingDefinition { 12 | func mapping(context: MappingContext) -> [ActionMapping] { 13 | return [ 14 | UserInput.isSelected <|> .selection => .normal <|> { 15 | $0.ifSelected { 16 | context.text.send(value: $0) 17 | } 18 | context.clear() 19 | }, 20 | UserInput.any <|> .selection => .selection <|> context.forward 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | fastlane_version "2.56.0" 2 | 3 | default_platform :mac 4 | xcversion(version: '10.0') 5 | 6 | platform :mac do 7 | before_all do 8 | cocoapods 9 | end 10 | 11 | desc 'Install input method to local' 12 | lane :try do 13 | input_methods = Pathname.new('~/Library/Input Methods').expand_path 14 | system 'killall EmojiIM' 15 | input_methods.join('EmojiIM.app').rmtree rescue nil 16 | input_methods.join('EmojiIM.app.dSYM.zip').rmtree rescue nil 17 | gym(output_directory: input_methods.to_s) 18 | system 'killall EmojiIM' 19 | end 20 | 21 | desc 'Runs all the tests' 22 | lane :test do 23 | sh('./embed_buildinfo') 24 | # swiftlint(executable: './Pods/SwiftLint/swiftlint') 25 | scan 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Extension/TISInputSourceTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TISInputSourceTest.swift 3 | // Tests 4 | // 5 | // Created by mzp on 2018/07/16. 6 | // Copyright © 2018 mzp. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | internal class TISInputSourceTest: XCTestCase { 12 | func testKeyboardLayouts() { 13 | let xs = TISInputSource.keyboardLayouts() 14 | XCTAssertNotNil(xs) 15 | XCTAssertFalse(xs?.isEmpty ?? false) 16 | } 17 | 18 | func testScriptCode() { 19 | let xs = TISInputSource.keyboardLayouts()? 20 | .filter { $0.scriptCode == 0 } 21 | .map { $0.localizedName } 22 | XCTAssertNotNil(xs) 23 | XCTAssertTrue(xs?.contains("ABC") ?? false) 24 | XCTAssertFalse(xs?.contains("Azeri") ?? false) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/11. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import InputMethodKit 11 | 12 | private var server: IMKServer? 13 | 14 | @NSApplicationMain 15 | internal class AppDelegate: NSObject, NSApplicationDelegate { 16 | 17 | @IBOutlet private weak var window: NSWindow! 18 | 19 | func applicationDidFinishLaunching(_ aNotification: Notification) { 20 | NSLog("EmojiIM launching: \(kBuiltDate)(\(kRevision))") 21 | let bundle = Bundle.main 22 | server = IMKServer(name: bundle.infoDictionary?["InputMethodConnectionName"] as? String, 23 | bundleIdentifier: bundle.bundleIdentifier) 24 | } 25 | 26 | func applicationWillTerminate(_ aNotification: Notification) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Tests/Dictionary/EmojiDictionaryTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmojiDictionaryTest.swift 3 | // Tests 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | internal class EmojiDictionaryTest: XCTestCase { 12 | private let dictionary: EmojiDictionary = EmojiDictionary() 13 | 14 | func testFind() { 15 | let sushi = dictionary.find(prefix: ":sus") 16 | XCTAssertTrue(sushi.contains("🍣"), "\(sushi) doesn't contain 🍣") 17 | 18 | let beer = dictionary.find(prefix: ":beer") 19 | XCTAssertTrue(beer.contains("🍺"), "\(beer) doesn't contain 🍺") 20 | XCTAssertTrue(beer.contains("🍻"), "\(beer) doesn't contain 🍻") 21 | } 22 | 23 | func testSizeLimit() { 24 | let all = dictionary.find(prefix: ":") 25 | XCTAssertEqual(all.count, 6) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew cask install fastlane` 16 | 17 | # Available Actions 18 | ## Mac 19 | ### mac try 20 | ``` 21 | fastlane mac try 22 | ``` 23 | Install input method to local 24 | ### mac test 25 | ``` 26 | fastlane mac test 27 | ``` 28 | Runs all the tests 29 | 30 | ---- 31 | 32 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 33 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 34 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 35 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | included: 2 | - Sources/ 3 | - Tests/ 4 | excluded: 5 | - Pods/ 6 | opt_in_rules: 7 | - attributes 8 | - closure_end_indentation 9 | - closure_spacing 10 | - conditional_returns_on_newline 11 | - empty_count 12 | - explicit_init 13 | - explicit_top_level_acl 14 | - explicit_type_interface 15 | - extension_access_modifier 16 | - fatal_error_message 17 | - first_where 18 | - force_unwrapping 19 | - implicit_return 20 | - implicitly_unwrapped_optional 21 | - multiline_parameters 22 | - nimble_operator 23 | - no_extension_access_modifier 24 | - number_separator 25 | - object_literal 26 | - operator_usage_whitespace 27 | - overridden_super_call 28 | - private_outlet 29 | - prohibited_super_call 30 | - redundant_nil_coalescing 31 | - sorted_imports 32 | - switch_case_on_newline 33 | - vertical_parameter_alignment_on_call 34 | disabled_rules: 35 | - todo 36 | -------------------------------------------------------------------------------- /Sources/Automaton/Mapping/MappingDefinition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MappingDefinition.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import ReactiveSwift 10 | import Result 11 | 12 | internal struct MappingContext { 13 | let candidateEvent: Signal.Observer 14 | let candidates: MutableProperty<[String]> 15 | let dictionary: EmojiDictionary 16 | let markedText: MutableProperty 17 | let text: Signal.Observer 18 | 19 | func clear() { 20 | markedText.swap("") 21 | candidates.swap([]) 22 | } 23 | 24 | func forward(userInput: UserInput) { 25 | _ = userInput.originalEvent.map { 26 | candidateEvent.send(value: $0) 27 | } 28 | } 29 | } 30 | 31 | internal protocol MappingDefinition { 32 | func mapping(context: MappingContext) -> [ActionMapping] 33 | } 34 | -------------------------------------------------------------------------------- /Sources/Setting/SettingStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingStore.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/11/13. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | import Cocoa 9 | 10 | internal class SettingStore { 11 | private let kSuiteName: String = "jp.mzp.inputmethod.EmojiIM" 12 | 13 | func setKeyboardLayout(inputSourceID: String) { 14 | userDefaults?.set(inputSourceID, forKey: "keyboardLayout") 15 | userDefaults?.synchronize() 16 | } 17 | 18 | func keyboardLayout() -> String { 19 | return (userDefaults?.value(forKey: "keyboardLayout") as? String) ?? "com.apple.keylayout.US" 20 | } 21 | 22 | private var inSandbox: Bool { 23 | return Bundle.main.bundleIdentifier == kSuiteName 24 | } 25 | 26 | private lazy var userDefaults: UserDefaults? = { 27 | if inSandbox { 28 | return UserDefaults.standard 29 | } else { 30 | return UserDefaults(suiteName: kSuiteName) 31 | } 32 | }() 33 | } 34 | -------------------------------------------------------------------------------- /Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests.swift 3 | // Tests 4 | // 5 | // Created by mzp on 2017/09/21. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | internal class Tests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testExample() { 24 | // This is an example of a functional test case. 25 | // Use XCTAssert and related functions to verify your tests produce the correct results. 26 | } 27 | 28 | func testPerformanceExample() { 29 | // This is an example of a performance test case. 30 | self.measure { 31 | // Put the code you want to measure the time of here. 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2017 mzp. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Resources/Preferences/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | NSHumanReadableCopyright 22 | Copyright © 2017 mzp. All rights reserved. 23 | NSMainNibFile 24 | Preferences 25 | NSPrefPaneIconFile 26 | Preferences.tiff 27 | NSPrefPaneIconLabel 28 | Preferences 29 | NSPrincipalClass 30 | Preferences 31 | 32 | 33 | -------------------------------------------------------------------------------- /Resources/EmojiIM/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Sources/Dictionary/EmojiDictionary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmojiDictionary.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/13. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | import AppKit 9 | 10 | // TODO: introduce some protocol 11 | internal class EmojiDictionary { 12 | private struct Entry: Codable { 13 | let name: String 14 | let emoji: String 15 | } 16 | private let entries: [Entry] 17 | private let limit: Int 18 | 19 | init(limit: Int = 6) { 20 | self.limit = limit 21 | guard let url = Bundle.main.url(forResource: "EmojiDefinition", withExtension: "json") else { 22 | fatalError("cannot find Emojidefinition.json") 23 | } 24 | do { 25 | let data = try Data(contentsOf: url) 26 | entries = try JSONDecoder().decode([Entry].self, from: data) 27 | } catch { 28 | fatalError("load error") 29 | } 30 | } 31 | 32 | func find(prefix: String) -> [String] { 33 | let xs = entries.compactMap { (entry: Entry) -> String? in 34 | if entry.name.starts(with: prefix) { 35 | return entry.emoji 36 | } else { 37 | return nil 38 | } 39 | }.prefix(self.limit) 40 | return Array(xs) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FootlessParser (0.5.0) 3 | - NorthLayout (5.1.0): 4 | - FootlessParser (~> 0.4) 5 | - ReactiveAutomaton (0.2.0): 6 | - ReactiveSwift (~> 1.0.0) 7 | - ReactiveCocoa (5.0.0): 8 | - ReactiveSwift (~> 1.0.0) 9 | - ReactiveSwift (1.0.1): 10 | - Result (~> 3.1) 11 | - Result (3.2.4) 12 | - SwiftLint (0.26.0) 13 | - "※ikemen (0.5.0)" 14 | 15 | DEPENDENCIES: 16 | - NorthLayout 17 | - ReactiveAutomaton 18 | - ReactiveCocoa 19 | - ReactiveSwift 20 | - Result 21 | - SwiftLint 22 | - "※ikemen" 23 | 24 | SPEC REPOS: 25 | https://github.com/cocoapods/specs.git: 26 | - FootlessParser 27 | - NorthLayout 28 | - ReactiveAutomaton 29 | - ReactiveCocoa 30 | - ReactiveSwift 31 | - Result 32 | - SwiftLint 33 | - "※ikemen" 34 | 35 | SPEC CHECKSUMS: 36 | FootlessParser: bc75547b0ccd696a0496993f394fdef3a2d481d0 37 | NorthLayout: 157045b4ef9e94019f00ec9dc66192c2b17c0c61 38 | ReactiveAutomaton: f5f04f0c1066d9b5e74a29da43d27029845c5379 39 | ReactiveCocoa: 60ef0da915b4f70c34ebecc3f4fb8f96af0e53d6 40 | ReactiveSwift: b1453c8885ebfb9b09b6d60bc5bc3303f56dc72c 41 | Result: d2d07204ce72856f1fd9130bbe42c35a7b0fea10 42 | SwiftLint: f6b83e8d95ee1e91e11932d843af4fdcbf3fc764 43 | "※ikemen": 0cf85af52790db21a846ad31abca356e99da1ffb 44 | 45 | PODFILE CHECKSUM: 3f7caa38017983cd739a9f06e0d6e55e987e6977 46 | 47 | COCOAPODS: 1.5.3 48 | -------------------------------------------------------------------------------- /bitrise.yml: -------------------------------------------------------------------------------- 1 | --- 2 | format_version: '4' 3 | default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git 4 | project_type: macos 5 | trigger_map: 6 | - push_branch: "*" 7 | workflow: primary 8 | - pull_request_source_branch: "*" 9 | workflow: primary 10 | workflows: 11 | deploy: 12 | steps: 13 | - activate-ssh-key@3.1.1: 14 | run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' 15 | - git-clone@3.5.2: {} 16 | - cache-pull@1.0.0: {} 17 | - script@1.1.4: 18 | title: Do anything with Script step 19 | - certificate-and-profile-installer@1.8.8: {} 20 | - cocoapods-install@1.7.1: {} 21 | - xcode-test-mac@1.1.0: 22 | inputs: 23 | - project_path: "$BITRISE_PROJECT_PATH" 24 | - scheme: "$BITRISE_SCHEME" 25 | - xcode-archive-mac@1.5.1: 26 | inputs: 27 | - project_path: "$BITRISE_PROJECT_PATH" 28 | - scheme: "$BITRISE_SCHEME" 29 | - deploy-to-bitrise-io@1.3.7: {} 30 | - cache-push@1.1.4: {} 31 | primary: 32 | steps: 33 | - activate-ssh-key: {} 34 | - git-clone: {} 35 | - cache-pull: {} 36 | - certificate-and-profile-installer: {} 37 | - fastlane: 38 | inputs: 39 | - lane: test 40 | - deploy-to-bitrise-io: {} 41 | - cache-push: {} 42 | app: 43 | envs: 44 | - opts: 45 | is_expand: false 46 | BITRISE_PROJECT_PATH: EmojiIM.xcworkspace 47 | - opts: 48 | is_expand: false 49 | BITRISE_SCHEME: EmojiIM 50 | - BITRISE_DEPLOY_DIR: Reports 51 | -------------------------------------------------------------------------------- /Sources/Automaton/Mapping/ComposingMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComposingMapping.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/10/15. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | import ReactiveAutomaton 9 | 10 | internal class ComposingMapping: MappingDefinition { 11 | func mapping(context: MappingContext) -> [ActionMapping] { 12 | return [ 13 | UserInput.isInput <|> .composing => .composing <|> { 14 | $0.ifInput { text in 15 | context.markedText.modify { $0.append(text) } 16 | context.candidates.swap(context.dictionary.find(prefix: context.markedText.value)) 17 | } 18 | }, 19 | UserInput.typeof(.backspace) <|> { 20 | $0 == .composing && (context.markedText.value.utf8.count <= 1) 21 | } => .normal <|> context.clear(), 22 | UserInput.typeof(.backspace) <|> .composing => .composing <|> { _ in 23 | context.markedText.modify { $0.removeLast() } 24 | context.candidates.swap(context.dictionary.find(prefix: context.markedText.value)) 25 | }, 26 | UserInput.typeof(.enter) <|> .composing => .normal <|> { _ in 27 | context.text.send(value: context.markedText.value) 28 | context.clear() 29 | }, 30 | UserInput.isSelected <|> .composing => .normal <|> { 31 | $0.ifSelected { 32 | context.text.send(value: $0) 33 | } 34 | context.clear() 35 | }, 36 | UserInput.typeof(.navigation) <|> .composing => .selection <|> context.forward 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Resources/Preferences/Base.lproj/Preferences.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sources/Extension/TISInputSource+Property.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TISInputSource+Property.swift 3 | // Preferences 4 | // 5 | // Created by mzp on 2017/11/13. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | extension TISInputSource { 10 | var localizedName: String { 11 | return unsafeBitCast( 12 | TISGetInputSourceProperty(self, kTISPropertyLocalizedName), 13 | to: NSString.self) as String 14 | } 15 | 16 | var inputSourceID: String { 17 | return unsafeBitCast( 18 | TISGetInputSourceProperty(self, kTISPropertyInputSourceID), 19 | to: NSString.self) as String 20 | } 21 | 22 | var scriptCode: Int? { 23 | let r = TISGetInputSourceProperty(self, kTISPropertyScriptCode) 24 | let n = unsafeBitCast(r, to: NSString.self).integerValue 25 | return n 26 | } 27 | 28 | class func keyboardLayouts() -> [TISInputSource]? { 29 | let conditions = CFDictionaryCreateMutable(nil, 2, nil, nil) 30 | CFDictionaryAddValue(conditions, 31 | unsafeBitCast(kTISPropertyInputSourceType, to: UnsafeRawPointer.self), 32 | unsafeBitCast(kTISTypeKeyboardLayout, to: UnsafeRawPointer.self)) 33 | CFDictionaryAddValue(conditions, 34 | unsafeBitCast(kTISPropertyInputSourceIsASCIICapable, to: UnsafeRawPointer.self), 35 | unsafeBitCast(kCFBooleanTrue, to: UnsafeRawPointer.self)) 36 | 37 | guard let array = TISCreateInputSourceList(conditions, true) else { 38 | return nil 39 | } 40 | guard let keyboards = array.takeRetainedValue() as? [TISInputSource] else { 41 | return nil 42 | } 43 | return keyboards.sorted { 44 | $0.localizedName < $1.localizedName 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/Automaton/EmojiAutomaton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Automaton.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/19. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import ReactiveAutomaton 10 | import ReactiveSwift 11 | import Result 12 | 13 | internal class EmojiAutomaton { 14 | let candidateEvent: Signal 15 | let candidates: Property<[String]> 16 | let markedText: Property 17 | let text: Signal 18 | 19 | private let automaton: Automaton 20 | private let observer: Signal.Observer 21 | private var handled: Bool = false 22 | private let mappingDefinition: [MappingDefinition] = [ 23 | ComposingMapping(), 24 | NormalMapping(), 25 | SelectionMapping() 26 | ] 27 | 28 | init() { 29 | let (candidateEvent, candidateEventObserver) = Signal.pipe() 30 | self.candidateEvent = candidateEvent 31 | 32 | let candidatesProperty = MutableProperty<[String]>([]) 33 | self.candidates = Property(candidatesProperty) 34 | 35 | let markedTextProperty = MutableProperty("") 36 | self.markedText = Property(markedTextProperty) 37 | 38 | let (text, textObserver) = Signal.pipe() 39 | self.text = text 40 | 41 | let dictionary: EmojiDictionary = EmojiDictionary() 42 | 43 | let context = MappingContext(candidateEvent: candidateEventObserver, 44 | candidates: candidatesProperty, 45 | dictionary: dictionary, 46 | markedText: markedTextProperty, 47 | text: textObserver) 48 | let mappings = mappingDefinition.flatMap { $0.mapping(context: context) } 49 | 50 | let (inputSignal, observer) = Signal.pipe() 51 | self.automaton = Automaton(state: .normal, input: inputSignal, mapping: reduce(mappings)) 52 | self.observer = observer 53 | observeAction(automaton: automaton, mappings: mappings) 54 | automaton.replies.observeValues { [weak self] in 55 | switch $0 { 56 | case .success: 57 | self?.handled = true 58 | default: 59 | () 60 | } 61 | } 62 | } 63 | 64 | func handle(_ input: UserInput) -> Bool { 65 | handled = false 66 | observer.send(value: input) 67 | return handled 68 | } 69 | 70 | var state: Property { 71 | return self.automaton.state 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :sushi: EmojiIM: Emoji Input Method for macOS 2 | 3 | [![Build Status](https://www.bitrise.io/app/0741e1b8cd1b5086/status.svg?token=79CGJwB83qmYoe5XcqqJbw)](https://www.bitrise.io/app/0741e1b8cd1b5086) 4 | 5 | EmojiIM converts github style emoji code to emoji. 6 | 7 | ![](/docs/sushi.gif) 8 | 9 | ## :circus_tent: Project goal: Playground for input method 10 | This project goal is not only to prodive emoji input methods, but also to investigate inside of input method. To achive this, some advanced features(e.g. touchbar supports) are implemented and described details at [label:article](https://github.com/mzp/EmojiIM/pulls?utf8=✓&q=label%3Aarticle%20). 11 | 12 | ## :star: Dowwnload/Install 13 | :construction: 14 | 15 | ## :wrench: Build 16 | 17 | ``` 18 | bundle install 19 | bundle exec fastlane try 20 | ``` 21 | 22 | After logout/login, EmojiIM appears at input sources of keyboard preferences. 23 | 24 | ## :smile: Commit symbol 25 | 26 | #### What's mean of this task 27 | |emoji |mean | 28 | |-------------------|----------------------------------------| 29 | |:rotating_light: |add/improve test | 30 | |:sparkles: |add new feature | 31 | |:lipstick: |improve the format/structure of the code| 32 | |:bug: |fix bug | 33 | |:wrench: |improve development environment | 34 | |:memo: |improve document | 35 | 36 | #### What's do for this task 37 | |emoji |mean | 38 | |-------------------|----------------------------------------| 39 | |:hocho: |split code | 40 | |:truck: |move files | 41 | |:fire: |remove code/files/... | 42 | |:chocolate_bar: |install/remove new cocoapods | 43 | |:see_no_evil: |ignore something | 44 | 45 | ### Where's updated for this task 46 | |emoji |mean | 47 | |-------------------|----------------------------------------| 48 | |:fountain_pen: |update something around InputMethodKit | 49 | |:twisted_rightwards_arrows: |update state machine definition| 50 | |:books: |update something around dictionary | 51 | 52 | ### Other 53 | |emoji |mean | 54 | |-------------------|----------------------------------------| 55 | |:police_car:|improve code format drived by lint police| 56 | |:lock: |improve something related with signing | 57 | 58 | ## :copyright: LICENSE 59 | MIT 60 | -------------------------------------------------------------------------------- /Sources/Automaton/UserInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserInput.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/19. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | import AppKit 9 | 10 | internal class UserInput { 11 | enum EventType { 12 | case backspace 13 | case colon 14 | case enter 15 | case input(text: String) 16 | case navigation 17 | case selected(candidate: String) 18 | } 19 | let eventType: EventType 20 | let originalEvent: NSEvent? 21 | 22 | // MARK: - predicate 23 | static func typeof(_ eventType: EventType) -> (UserInput) -> Bool { 24 | return { $0.eventType == eventType } 25 | } 26 | 27 | static func any(_ state: UserInput) -> Bool { 28 | return true 29 | } 30 | 31 | static func isInput(_ state: UserInput) -> Bool { 32 | switch state.eventType { 33 | case .input: 34 | return true 35 | default: 36 | return false 37 | } 38 | } 39 | 40 | static func isSelected(_ state: UserInput) -> Bool { 41 | switch state.eventType { 42 | case .selected: 43 | return true 44 | default: 45 | return false 46 | } 47 | } 48 | 49 | func ifInput(action: (String) -> Void) { 50 | switch self.eventType { 51 | case .input(text: let text): 52 | action(text) 53 | default: 54 | () 55 | } 56 | } 57 | 58 | func ifSelected(action: (String) -> Void) { 59 | switch self.eventType { 60 | case .selected(candidate: let candidate): 61 | action(candidate) 62 | default: 63 | () 64 | } 65 | } 66 | 67 | // MARK: - initialize 68 | init(eventType: EventType, originalEvent: NSEvent? = nil) { 69 | self.eventType = eventType 70 | self.originalEvent = originalEvent 71 | } 72 | } 73 | 74 | extension UserInput.EventType: Equatable { 75 | static func == (lhs: UserInput.EventType, rhs: UserInput.EventType) -> Bool { 76 | switch (lhs, rhs) { 77 | case (.backspace, .backspace): 78 | return true 79 | case (.colon, .colon): 80 | return true 81 | case (.enter, .enter): 82 | return true 83 | case (.input(text: let text1), .input(text: let text2)): 84 | return text1 == text2 85 | case (.navigation, .navigation): 86 | return true 87 | case (.selected(candidate: let candidate1), .selected(candidate: let candidate2)): 88 | return candidate1 == candidate2 89 | default: 90 | return false 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Sources/Preferences/Preferences.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Preferences.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/11/04. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import CoreFoundation 10 | import Ikemen 11 | import NorthLayout 12 | import PreferencePanes 13 | import ReactiveCocoa 14 | 15 | @objc(Preferences) 16 | public class Preferences: NSPreferencePane { 17 | private let store: SettingStore = SettingStore() 18 | private lazy var keyboardLayouts: [TISInputSource]? = TISInputSource.keyboardLayouts()?.filter { 19 | // 0 means English keyboard layout 20 | $0.scriptCode == 0 21 | } 22 | 23 | override public func mainViewDidLoad() { 24 | let keyboardLabel = NSTextField.label(text: "Keybaord:") ※ { 25 | $0.alignment = .right 26 | } 27 | let keyboard = NSPopUpButton() ※ { 28 | for layout in keyboardLayouts ?? [] { 29 | $0.addItem(withTitle: layout.localizedName) 30 | } 31 | $0.reactive.selectedIndexes.observeValues { 32 | if let layout = self.keyboardLayouts?[$0] { 33 | self.store.setKeyboardLayout(inputSourceID: layout.inputSourceID) 34 | } 35 | } 36 | if let index = keyboardLayouts?.index(where: { $0.inputSourceID == store.keyboardLayout() }) { 37 | $0.selectItem(at: index) 38 | } 39 | } 40 | let revisionLabel = NSTextField.label(text: "Revision:") ※ { 41 | $0.alignment = .right 42 | } 43 | let revision = NSTextField.label(text: kRevision) 44 | let builtDateLabel = NSTextField.label(text: "Built date:") ※ { 45 | $0.alignment = .right 46 | } 47 | let builtDate = NSTextField.label(text: kBuiltDate) 48 | 49 | let autolayout = mainView.northLayoutFormat( 50 | [ 51 | "p": 20, 52 | "m": 10, 53 | "w": 60, 54 | "h": 16 55 | ], 56 | [ 57 | "keyboardLabel": keyboardLabel, 58 | "keyboard": keyboard, 59 | "revisionLabel": revisionLabel, 60 | "revision": revision, 61 | "builtDateLabel": builtDateLabel, 62 | "builtDate": builtDate 63 | ] 64 | ) 65 | autolayout("H:|-p-[keyboardLabel(==w)]-m-[keyboard]-p-|") 66 | autolayout("H:|-p-[builtDateLabel(==w)]-m-[builtDate]-p-|") 67 | autolayout("H:|-p-[revisionLabel(==w)]-m-[revision]-p-|") 68 | autolayout("V:|-p-[keyboardLabel(==h)]-m-[builtDateLabel(==h)]-m-[revisionLabel(==h)]|") 69 | autolayout("V:|-p-[keyboard(==h)]-m-[builtDate(==h)]-m-[revision(==h)]|") 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Sources/Automaton/ReactiveAutomaton+Action.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReactiveAutomaton+Action.swit 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/20. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import ReactiveAutomaton 10 | 11 | public struct ActionMapping { 12 | let input: (Input) -> Bool 13 | let transition: Transition 14 | let action: (State, State, Input) -> Void 15 | } 16 | 17 | infix operator <|>: AdditionPrecedence // same as | 18 | 19 | public func <|> ( 20 | input: @escaping (Input) -> Bool, 21 | transition: Transition 22 | ) -> ActionMapping { 23 | return ActionMapping(input: input, transition: transition, action: { (_, _, _) in }) 24 | } 25 | 26 | public func <|> ( 27 | input: Input, 28 | transition: Transition 29 | ) -> ActionMapping { 30 | return { $0 == input } <|> transition 31 | } 32 | 33 | public func <|> ( 34 | mapping: ActionMapping, 35 | action: @escaping (State, State, Input) -> Void 36 | ) -> ActionMapping { 37 | return ActionMapping(input: mapping.input, transition: mapping.transition) { (fromState, toState, input) in 38 | action(fromState, toState, input) 39 | mapping.action(fromState, toState, input) 40 | } 41 | } 42 | 43 | public func <|> ( 44 | mapping: ActionMapping, 45 | action: @escaping (Input) -> Void 46 | ) -> ActionMapping { 47 | return mapping <|> { (_, _, input) in action(input) } 48 | } 49 | 50 | public func <|> ( 51 | mapping: ActionMapping, 52 | action: @autoclosure @escaping () -> Void 53 | ) -> ActionMapping { 54 | return mapping <|> { (_, _, input) in action() } 55 | } 56 | 57 | public func reduce(_ mappings: Mappings) -> Automaton.Mapping 58 | where Mappings.Iterator.Element == ActionMapping { 59 | return { fromState, input in 60 | for mapping in mappings { 61 | if mapping.input(input) && mapping.transition.fromState(fromState) { 62 | return mapping.transition.toState 63 | } 64 | } 65 | return nil 66 | } 67 | } 68 | 69 | public func observeAction( 70 | automaton: Automaton, mappings: Mappings 71 | ) where Mappings.Iterator.Element == ActionMapping { 72 | automaton.replies.observeValues { reply in 73 | guard let toState = reply.toState else { 74 | return 75 | } 76 | 77 | for mapping in mappings { 78 | if mapping.input(reply.input) && 79 | mapping.transition.fromState(reply.fromState) && 80 | mapping.transition.toState == toState { 81 | mapping.action(reply.fromState, reply.fromState, reply.input) 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Resources/EmojiIM/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | InputMethodConnectionName 24 | jp.mzp.inputmethod.EmojiIM_Connection 25 | InputMethodServerControllerClass 26 | EmojiInputController 27 | LSApplicationCategoryType 28 | public.app-category.utilities 29 | LSBackgroundOnly 30 | YES 31 | LSHasLocalizedDisplayName 32 | 33 | LSMinimumSystemVersion 34 | $(MACOSX_DEPLOYMENT_TARGET) 35 | NSHumanReadableCopyright 36 | Copyright © 2017 mzp. All rights reserved. 37 | NSMainNibFile 38 | MainMenu 39 | NSPrincipalClass 40 | NSApplication 41 | tsInputMethodCharacterRepertoireKey 42 | 43 | Hira 44 | Kana 45 | Latn 46 | 47 | tsInputMethodIconFileKey 48 | InputMethodIcon.tiff 49 | ComponentInputModeDict 50 | 51 | TISUnifiedUIForInputMethodEnabling 52 | 53 | tsInputModeListKey 54 | 55 | jp.mzp.inputmethod.EmojiIM 56 | 57 | TISDoubleSpaceSubstitution 58 | 🍣 59 | TISInputSourceID 60 | jp.mzp.inputmethod.EmojiIM.emoji 61 | TISIntendedLanguage 62 | en 63 | tsInputModeScriptKey 64 | smUnicode 65 | tsInputModeMenuIconFileKey 66 | InputMethodIcon.tiff 67 | tsInputModeAlternateMenuIconFileKey 68 | InputMethodIcon.tiff 69 | tsInputModeDefaultStateKey 70 | 71 | tsInputModeIsVisibleKey 72 | 73 | 74 | com.apple.inputmethod.Roman 75 | 76 | TISInputSourceID 77 | jp.mzp.inputmethod.EmojiIM.roman 78 | TISIntendedLanguage 79 | en 80 | tsInputModeScriptKey 81 | smRoman 82 | tsInputModeMenuIconFileKey 83 | InputMethodIcon.tiff 84 | tsInputModeAlternateMenuIconFileKey 85 | InputMethodIcon.tiff 86 | tsInputModeDefaultStateKey 87 | 88 | tsInputModeIsVisibleKey 89 | 90 | 91 | 92 | tsVisibleInputModeOrderedArrayKey 93 | 94 | jp.mzp.inputmethod.EmojiIM 95 | com.apple.inputmethod.Roman 96 | 97 | 98 | TISIntendedLanguage 99 | en 100 | 101 | 102 | -------------------------------------------------------------------------------- /EmojiIM.xcodeproj/xcshareddata/xcschemes/EmojiIM.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 68 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 87 | 93 | 94 | 95 | 96 | 98 | 99 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Sources/InputMethodKit/EmojiInputController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmojiInputController.swift 3 | // EmojiIM 4 | // 5 | // Created by mzp on 2017/09/14. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import Ikemen 10 | import InputMethodKit 11 | 12 | @objc(EmojiInputController) 13 | internal class EmojiInputController: IMKInputController { 14 | private let automaton: EmojiAutomaton = EmojiAutomaton() 15 | private let candidates: IMKCandidates 16 | private var directMode: Bool = false 17 | private let printable: CharacterSet = [ 18 | CharacterSet.alphanumerics, 19 | CharacterSet.symbols, 20 | CharacterSet.punctuationCharacters 21 | ].reduce(CharacterSet()) { $0.union($1) } 22 | 23 | override init!(server: IMKServer, delegate: Any, client inputClient: Any) { 24 | self.candidates = IMKCandidates(server: server, panelType: kIMKSingleColumnScrollingCandidatePanel) 25 | super.init(server: server, delegate: delegate, client: inputClient) 26 | 27 | guard let client = inputClient as? IMKTextInput else { 28 | return 29 | } 30 | automaton.markedText.signal.observeValues { 31 | let notFound = NSRange(location: NSNotFound, length: NSNotFound) 32 | client.setMarkedText($0, selectionRange: notFound, replacementRange: notFound) 33 | } 34 | automaton.text.observeValues { 35 | let notFound = NSRange(location: NSNotFound, length: NSNotFound) 36 | client.insertText($0, replacementRange: notFound) 37 | } 38 | automaton.candidates.signal.observeValues { 39 | if $0.isEmpty { 40 | self.candidates.hide() 41 | } else { 42 | self.candidates.update() 43 | self.candidates.show() 44 | } 45 | } 46 | automaton.candidateEvent.observeValues { 47 | self.candidates.interpretKeyEvents([$0]) 48 | } 49 | } 50 | 51 | override func handle(_ event: NSEvent, client sender: Any) -> Bool { 52 | NSLog("%@", "\(#function)((\(event), client: \(sender))") 53 | if directMode { 54 | return false 55 | } 56 | 57 | return automaton.handle(UserInput(eventType: convert(event: event), originalEvent: event)) 58 | } 59 | 60 | override func menu() -> NSMenu! { 61 | return NSMenu(title: "EmojiIM") ※ { menu in 62 | menu.addItem(NSMenuItem(title: kBuiltDate, action: nil, keyEquivalent: "")) 63 | menu.addItem(NSMenuItem(title: kRevision, action: nil, keyEquivalent: "")) 64 | } 65 | } 66 | 67 | private func convert(event: NSEvent) -> UserInput.EventType { 68 | if event.keyCode == 36 { 69 | return .enter 70 | } else if event.keyCode == 51 { 71 | return .backspace 72 | } else if let text = event.characters { 73 | switch text { 74 | case ":": 75 | return .colon 76 | default: 77 | if text.unicodeScalars.every(where: printable.contains) { 78 | return .input(text: text) 79 | } else { 80 | return .navigation 81 | } 82 | } 83 | } else { 84 | return .navigation 85 | } 86 | } 87 | } 88 | 89 | extension EmojiInputController /* IMKStateSetting*/ { 90 | override func activateServer(_ sender: Any) { 91 | NSLog("%@", "\(#function)((\(sender))") 92 | 93 | guard let client = sender as? IMKTextInput else { 94 | return 95 | } 96 | client.overrideKeyboard(withKeyboardNamed: SettingStore().keyboardLayout()) 97 | } 98 | 99 | override func deactivateServer(_ sender: Any) { 100 | NSLog("%@", "\(#function)((\(sender))") 101 | self.candidates.hide() 102 | } 103 | 104 | override func setValue(_ value: Any, forTag tag: Int, client sender: Any) { 105 | NSLog("%@", "\(#function)(\(value), forTag: \(tag))") 106 | guard let value = value as? NSString else { 107 | return 108 | } 109 | guard let sender = sender as? IMKTextInput else { 110 | return 111 | } 112 | directMode = value == "com.apple.inputmethod.Roman" 113 | sender.overrideKeyboard(withKeyboardNamed: SettingStore().keyboardLayout()) 114 | } 115 | } 116 | 117 | extension EmojiInputController { 118 | override func candidates(_ sender: Any) -> [Any] { 119 | return automaton.candidates.value 120 | } 121 | 122 | override func candidateSelected(_ candidateString: NSAttributedString) { 123 | NSLog("%@", "\(#function)") 124 | DispatchQueue.main.async { 125 | _ = self.automaton.handle(UserInput(eventType: .selected(candidate: candidateString.string))) 126 | } 127 | } 128 | 129 | override func candidateSelectionChanged(_ candidateString: NSAttributedString) { 130 | NSLog("%@", "\(#function)") 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /Tests/Automaton/AutomatonTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutomatonTest.swift 3 | // UnitTest 4 | // 5 | // Created by mzp on 2017/09/19. 6 | // Copyright © 2017 mzp. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | internal class AutomatonTest: XCTestCase { 12 | // swiftlint:disable:next implicitly_unwrapped_optional 13 | private var automaton: EmojiAutomaton! 14 | 15 | override func setUp() { 16 | super.setUp() 17 | self.automaton = EmojiAutomaton() 18 | } 19 | 20 | func testDeinit() { 21 | weak var target = EmojiAutomaton() 22 | XCTAssertNil(target) 23 | } 24 | 25 | func testTransition() { 26 | XCTAssertEqual(automaton.state.value, .normal) 27 | 28 | _ = automaton.handle(UserInput(eventType: .enter)) 29 | XCTAssertEqual(automaton.state.value, .normal) 30 | 31 | _ = automaton.handle(UserInput(eventType: .input(text: "a"))) 32 | XCTAssertEqual(automaton.state.value, .normal) 33 | 34 | _ = automaton.handle(UserInput(eventType: .colon)) 35 | XCTAssertEqual(automaton.state.value, .composing) 36 | 37 | _ = automaton.handle(UserInput(eventType: .input(text: "b"))) 38 | XCTAssertEqual(automaton.state.value, .composing) 39 | 40 | _ = automaton.handle(UserInput(eventType: .enter)) 41 | XCTAssertEqual(automaton.state.value, .normal) 42 | } 43 | 44 | func testTransitionSelection() { 45 | _ = automaton.handle(UserInput(eventType: .colon)) 46 | XCTAssertEqual(automaton.state.value, .composing) 47 | 48 | _ = automaton.handle(UserInput(eventType: .input(text: "a"))) 49 | XCTAssertEqual(automaton.state.value, .composing) 50 | 51 | _ = automaton.handle(UserInput(eventType: .navigation)) 52 | XCTAssertEqual(automaton.state.value, .selection) 53 | 54 | _ = automaton.handle(UserInput(eventType: .navigation)) 55 | XCTAssertEqual(automaton.state.value, .selection) 56 | 57 | _ = automaton.handle(UserInput(eventType: .enter)) 58 | XCTAssertEqual(automaton.state.value, .selection) 59 | 60 | _ = automaton.handle(UserInput(eventType: .selected(candidate: "a"))) 61 | XCTAssertEqual(automaton.state.value, .normal) 62 | } 63 | 64 | func testComposing() { 65 | var text: String = "" 66 | automaton.text.observeValues { text.append($0) } 67 | 68 | _ = automaton.handle(UserInput(eventType: .colon)) 69 | XCTAssertEqual(automaton.markedText.value, ":") 70 | 71 | _ = automaton.handle(UserInput(eventType: .input(text: "a"))) 72 | XCTAssertEqual(automaton.markedText.value, ":a") 73 | 74 | _ = automaton.handle(UserInput(eventType: .backspace)) 75 | XCTAssertEqual(automaton.markedText.value, ":") 76 | 77 | _ = automaton.handle(UserInput(eventType: .enter)) 78 | XCTAssertEqual(automaton.markedText.value, "") 79 | XCTAssertEqual(text, ":") 80 | } 81 | 82 | func testSelectWhileComposing() { 83 | var text: String = "" 84 | automaton.text.observeValues { text.append($0) } 85 | 86 | _ = automaton.handle(UserInput(eventType: .colon)) 87 | XCTAssertEqual(automaton.candidates.value, []) 88 | 89 | _ = automaton.handle(UserInput(eventType: .input(text: "s"))) 90 | _ = automaton.handle(UserInput(eventType: .input(text: "u"))) 91 | _ = automaton.handle(UserInput(eventType: .input(text: "s"))) 92 | XCTAssertTrue(automaton.candidates.value.contains("🍣"), "\(automaton.candidates.value) doesn't contain 🍣") 93 | 94 | _ = automaton.handle(UserInput(eventType: .selected(candidate: "🍣"))) 95 | XCTAssertEqual(automaton.candidates.value, []) 96 | XCTAssertEqual(text, "🍣") 97 | } 98 | 99 | func testCandidates() { 100 | var text: String = "" 101 | automaton.text.observeValues { text.append($0) } 102 | 103 | _ = automaton.handle(UserInput(eventType: .colon)) 104 | XCTAssertEqual(automaton.candidates.value, []) 105 | 106 | _ = automaton.handle(UserInput(eventType: .input(text: "s"))) 107 | _ = automaton.handle(UserInput(eventType: .input(text: "u"))) 108 | _ = automaton.handle(UserInput(eventType: .input(text: "s"))) 109 | XCTAssertTrue(automaton.candidates.value.contains("🍣"), "\(automaton.candidates.value) doesn't contain 🍣") 110 | 111 | _ = automaton.handle(UserInput(eventType: .input(text: "e"))) 112 | XCTAssertFalse(automaton.candidates.value.contains("🍣"), "\(automaton.candidates.value) contains 🍣") 113 | 114 | _ = automaton.handle(UserInput(eventType: .backspace)) 115 | XCTAssertTrue(automaton.candidates.value.contains("🍣"), "\(automaton.candidates.value) doesn't contain 🍣") 116 | 117 | _ = automaton.handle(UserInput(eventType: .navigation)) 118 | XCTAssertTrue(automaton.candidates.value.contains("🍣"), "\(automaton.candidates.value) doesn't contain 🍣") 119 | 120 | _ = automaton.handle(UserInput(eventType: .selected(candidate: "🍣"))) 121 | XCTAssertEqual(automaton.candidates.value, []) 122 | XCTAssertEqual(text, "🍣") 123 | } 124 | 125 | func testBackspaceReturnNormal() { 126 | _ = automaton.handle(UserInput(eventType: .colon)) 127 | _ = automaton.handle(UserInput(eventType: .input(text: "a"))) 128 | _ = automaton.handle(UserInput(eventType: .backspace)) 129 | XCTAssertEqual(automaton.state.value, .composing) 130 | _ = automaton.handle(UserInput(eventType: .backspace)) 131 | XCTAssertEqual(automaton.state.value, .normal) 132 | } 133 | 134 | func testHandled() { 135 | XCTAssertFalse(automaton.handle(UserInput(eventType: .input(text: "a")))) 136 | XCTAssertFalse(automaton.handle(UserInput(eventType: .navigation))) 137 | XCTAssertTrue(automaton.handle(UserInput(eventType: .colon))) 138 | XCTAssertTrue(automaton.handle(UserInput(eventType: .input(text: "a")))) 139 | XCTAssertTrue(automaton.handle(UserInput(eventType: .navigation))) 140 | XCTAssertTrue(automaton.handle(UserInput(eventType: .selected(candidate: "a")))) 141 | XCTAssertFalse(automaton.handle(UserInput(eventType: .enter))) 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.0) 5 | activesupport (4.2.10) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.5.2) 11 | public_suffix (>= 2.0.2, < 4.0) 12 | atomos (0.1.2) 13 | babosa (1.0.2) 14 | claide (1.0.2) 15 | cocoapods (1.5.3) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.5.3) 19 | cocoapods-deintegrate (>= 1.0.2, < 2.0) 20 | cocoapods-downloader (>= 1.2.0, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.0, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (~> 2.0.1) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.5) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.1) 33 | xcodeproj (>= 1.5.7, < 2.0) 34 | cocoapods-core (1.5.3) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.2) 39 | cocoapods-downloader (1.2.1) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.0.0) 44 | cocoapods-trunk (1.3.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.0.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | domain_name (0.5.20180417) 56 | unf (>= 0.0.5, < 1.0.0) 57 | dotenv (2.5.0) 58 | emoji_regex (0.1.1) 59 | escape (0.0.4) 60 | excon (0.62.0) 61 | faraday (0.15.2) 62 | multipart-post (>= 1.2, < 3) 63 | faraday-cookie_jar (0.0.6) 64 | faraday (>= 0.7.4) 65 | http-cookie (~> 1.0.0) 66 | faraday_middleware (0.12.2) 67 | faraday (>= 0.7.4, < 1.0) 68 | fastimage (2.1.3) 69 | fastlane (2.99.1) 70 | CFPropertyList (>= 2.3, < 4.0.0) 71 | addressable (>= 2.3, < 3.0.0) 72 | babosa (>= 1.0.2, < 2.0.0) 73 | bundler (>= 1.12.0, < 2.0.0) 74 | colored 75 | commander-fastlane (>= 4.4.6, < 5.0.0) 76 | dotenv (>= 2.1.1, < 3.0.0) 77 | emoji_regex (~> 0.1) 78 | excon (>= 0.45.0, < 1.0.0) 79 | faraday (~> 0.9) 80 | faraday-cookie_jar (~> 0.0.6) 81 | faraday_middleware (~> 0.9) 82 | fastimage (>= 2.1.0, < 3.0.0) 83 | gh_inspector (>= 1.1.2, < 2.0.0) 84 | google-api-client (>= 0.21.2, < 0.22.0) 85 | highline (>= 1.7.2, < 2.0.0) 86 | json (< 3.0.0) 87 | mini_magick (~> 4.5.1) 88 | multi_json 89 | multi_xml (~> 0.5) 90 | multipart-post (~> 2.0.0) 91 | plist (>= 3.1.0, < 4.0.0) 92 | public_suffix (~> 2.0.0) 93 | rubyzip (>= 1.2.1, < 2.0.0) 94 | security (= 0.1.3) 95 | simctl (~> 1.6.3) 96 | slack-notifier (>= 2.0.0, < 3.0.0) 97 | terminal-notifier (>= 1.6.2, < 2.0.0) 98 | terminal-table (>= 1.4.5, < 2.0.0) 99 | tty-screen (>= 0.6.3, < 1.0.0) 100 | tty-spinner (>= 0.8.0, < 1.0.0) 101 | word_wrap (~> 1.0.0) 102 | xcodeproj (>= 1.5.7, < 2.0.0) 103 | xcpretty (~> 0.2.8) 104 | xcpretty-travis-formatter (>= 0.0.3) 105 | fourflusher (2.0.1) 106 | fuzzy_match (2.0.4) 107 | gemoji (3.0.0) 108 | gh_inspector (1.1.3) 109 | google-api-client (0.21.2) 110 | addressable (~> 2.5, >= 2.5.1) 111 | googleauth (>= 0.5, < 0.7.0) 112 | httpclient (>= 2.8.1, < 3.0) 113 | mime-types (~> 3.0) 114 | representable (~> 3.0) 115 | retriable (>= 2.0, < 4.0) 116 | googleauth (0.6.2) 117 | faraday (~> 0.12) 118 | jwt (>= 1.4, < 3.0) 119 | logging (~> 2.0) 120 | memoist (~> 0.12) 121 | multi_json (~> 1.11) 122 | os (~> 0.9) 123 | signet (~> 0.7) 124 | highline (1.7.10) 125 | http-cookie (1.0.3) 126 | domain_name (~> 0.5) 127 | httpclient (2.8.3) 128 | i18n (0.9.5) 129 | concurrent-ruby (~> 1.0) 130 | json (2.1.0) 131 | jwt (2.1.0) 132 | little-plugger (1.1.4) 133 | logging (2.2.2) 134 | little-plugger (~> 1.1) 135 | multi_json (~> 1.10) 136 | memoist (0.16.0) 137 | mime-types (3.1) 138 | mime-types-data (~> 3.2015) 139 | mime-types-data (3.2016.0521) 140 | mini_magick (4.5.1) 141 | minitest (5.11.3) 142 | molinillo (0.6.5) 143 | multi_json (1.13.1) 144 | multi_xml (0.6.0) 145 | multipart-post (2.0.0) 146 | nanaimo (0.2.6) 147 | nap (1.1.0) 148 | naturally (2.2.0) 149 | netrc (0.11.0) 150 | os (0.9.6) 151 | plist (3.4.0) 152 | public_suffix (2.0.5) 153 | representable (3.0.4) 154 | declarative (< 0.1.0) 155 | declarative-option (< 0.2.0) 156 | uber (< 0.2.0) 157 | retriable (3.1.2) 158 | rouge (2.0.7) 159 | ruby-macho (1.2.0) 160 | rubyzip (1.2.1) 161 | security (0.1.3) 162 | signet (0.8.1) 163 | addressable (~> 2.3) 164 | faraday (~> 0.9) 165 | jwt (>= 1.5, < 3.0) 166 | multi_json (~> 1.10) 167 | simctl (1.6.5) 168 | CFPropertyList 169 | naturally 170 | slack-notifier (2.3.2) 171 | terminal-notifier (1.8.0) 172 | terminal-table (1.8.0) 173 | unicode-display_width (~> 1.1, >= 1.1.1) 174 | thread_safe (0.3.6) 175 | tty-cursor (0.6.0) 176 | tty-screen (0.6.5) 177 | tty-spinner (0.8.0) 178 | tty-cursor (>= 0.5.0) 179 | tzinfo (1.2.5) 180 | thread_safe (~> 0.1) 181 | uber (0.1.0) 182 | unf (0.1.4) 183 | unf_ext 184 | unf_ext (0.0.7.5) 185 | unicode-display_width (1.4.0) 186 | word_wrap (1.0.0) 187 | xcode-install (2.4.2) 188 | claide (>= 0.9.1, < 1.1.0) 189 | fastlane (>= 2.1.0, < 3.0.0) 190 | xcodeproj (1.5.9) 191 | CFPropertyList (>= 2.3.3, < 4.0) 192 | atomos (~> 0.1.2) 193 | claide (>= 1.0.2, < 2.0) 194 | colored2 (~> 3.1) 195 | nanaimo (~> 0.2.5) 196 | xcpretty (0.2.8) 197 | rouge (~> 2.0.7) 198 | xcpretty-travis-formatter (1.0.0) 199 | xcpretty (~> 0.2, >= 0.0.7) 200 | 201 | PLATFORMS 202 | ruby 203 | 204 | DEPENDENCIES 205 | cocoapods 206 | fastlane 207 | gemoji 208 | xcode-install 209 | 210 | BUNDLED WITH 211 | 1.16.2 212 | -------------------------------------------------------------------------------- /Resources/EmojiIM/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 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 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | Default 540 | 541 | 542 | 543 | 544 | 545 | 546 | Left to Right 547 | 548 | 549 | 550 | 551 | 552 | 553 | Right to Left 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | Default 565 | 566 | 567 | 568 | 569 | 570 | 571 | Left to Right 572 | 573 | 574 | 575 | 576 | 577 | 578 | Right to Left 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | -------------------------------------------------------------------------------- /EmojiIM.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 130DC5D51F65F91D00BBCB60 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130DC5D41F65F91D00BBCB60 /* AppDelegate.swift */; }; 11 | 130DC5D71F65F91D00BBCB60 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 130DC5D61F65F91D00BBCB60 /* Assets.xcassets */; }; 12 | 130DC5DA1F65F91D00BBCB60 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 130DC5D81F65F91D00BBCB60 /* MainMenu.xib */; }; 13 | 1313B8241F93579E004B6A2F /* EmojiDictionaryTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1313B8231F93579E004B6A2F /* EmojiDictionaryTest.swift */; }; 14 | 1313B8261F935DA9004B6A2F /* EmojiDefinition.json in Resources */ = {isa = PBXBuildFile; fileRef = 1313B8221F935741004B6A2F /* EmojiDefinition.json */; }; 15 | 1313B8271F935DAA004B6A2F /* EmojiDefinition.json in Resources */ = {isa = PBXBuildFile; fileRef = 1313B8221F935741004B6A2F /* EmojiDefinition.json */; }; 16 | 134922DF1F6B33AF000AA483 /* EmojiInputController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134922DE1F6B33AF000AA483 /* EmojiInputController.swift */; }; 17 | 134A02F01F6B36C60050216F /* InputMethodIcon.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 134922E01F6B33B9000AA483 /* InputMethodIcon.tiff */; }; 18 | 134CE31B20FC882200BC4009 /* TISInputSourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134CE31A20FC882200BC4009 /* TISInputSourceTest.swift */; }; 19 | 134CE31C20FC885200BC4009 /* TISInputSource+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EBC3011FB9B1790036A072 /* TISInputSource+Property.swift */; }; 20 | 136A4CCD1F904CA20020BDBE /* EmojiDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136A4CCC1F904CA20020BDBE /* EmojiDictionary.swift */; }; 21 | 13779B981FB3351C001529BF /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13779B971FB3351C001529BF /* Preferences.swift */; }; 22 | 13A455CD1F9F5D2900F2D3EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 13A455CF1F9F5D2900F2D3EA /* InfoPlist.strings */; }; 23 | 13AC72241FAD4D7200585E3B /* Preferences.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 13AC72231FAD4D7200585E3B /* Preferences.tiff */; }; 24 | 13AC72271FAD4D7200585E3B /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13AC72251FAD4D7200585E3B /* Preferences.xib */; }; 25 | 13AC72301FAD4E2400585E3B /* Preferences.prefPane in Copy Preferences Pane */ = {isa = PBXBuildFile; fileRef = 13AC721D1FAD4D7200585E3B /* Preferences.prefPane */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | 13AE25131F9052730073912E /* EmojiDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136A4CCC1F904CA20020BDBE /* EmojiDictionary.swift */; }; 27 | 13B7E6621F6D6327008C528A /* BuildInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B7E6611F6D631F008C528A /* BuildInfo.swift */; }; 28 | 13BE30431F731F7B001D3AF8 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30421F731F7B001D3AF8 /* Tests.swift */; }; 29 | 13BE305B1F7325C8001D3AF8 /* EmojiAutomaton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE305A1F7325BA001D3AF8 /* EmojiAutomaton.swift */; }; 30 | 13BE305C1F7325C9001D3AF8 /* EmojiAutomaton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE305A1F7325BA001D3AF8 /* EmojiAutomaton.swift */; }; 31 | 13BE305D1F7325CC001D3AF8 /* InputMethodState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30581F7325BA001D3AF8 /* InputMethodState.swift */; }; 32 | 13BE305E1F7325CC001D3AF8 /* UserInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30591F7325BA001D3AF8 /* UserInput.swift */; }; 33 | 13BE305F1F7325CD001D3AF8 /* InputMethodState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30581F7325BA001D3AF8 /* InputMethodState.swift */; }; 34 | 13BE30601F7325CD001D3AF8 /* UserInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30591F7325BA001D3AF8 /* UserInput.swift */; }; 35 | 13BE30631F7325F9001D3AF8 /* ReactiveAutomaton+Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30571F732577001D3AF8 /* ReactiveAutomaton+Action.swift */; }; 36 | 13BE30641F7325F9001D3AF8 /* ReactiveAutomaton+Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30571F732577001D3AF8 /* ReactiveAutomaton+Action.swift */; }; 37 | 13BE30651F73260E001D3AF8 /* AutomatonTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE30621F7325E6001D3AF8 /* AutomatonTest.swift */; }; 38 | 13C46F261FB86E10005A8348 /* Collection+Every.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C46F251FB86E0E005A8348 /* Collection+Every.swift */; }; 39 | 13C46F271FB86E14005A8348 /* NSTextField+Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C46F241FB86E0E005A8348 /* NSTextField+Label.swift */; }; 40 | 13C46F281FB86EB3005A8348 /* BuildInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B7E6611F6D631F008C528A /* BuildInfo.swift */; }; 41 | 13D45CD21F9340F600D4CE5D /* ComposingMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D45CD11F9340F600D4CE5D /* ComposingMapping.swift */; }; 42 | 13DD45F41FB9C9D100EE1758 /* SettingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EBC2FE1FB91FA20036A072 /* SettingStore.swift */; }; 43 | 13EBC3001FB91FC90036A072 /* SettingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EBC2FE1FB91FA20036A072 /* SettingStore.swift */; }; 44 | 13EBC3021FB9B1790036A072 /* TISInputSource+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EBC3011FB9B1790036A072 /* TISInputSource+Property.swift */; }; 45 | 13FFA3881F93450200852AC5 /* MappingDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA3871F93450200852AC5 /* MappingDefinition.swift */; }; 46 | 13FFA38A1F93455B00852AC5 /* NormalMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA3891F93455B00852AC5 /* NormalMapping.swift */; }; 47 | 13FFA38C1F9345BF00852AC5 /* SelectionMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA38B1F9345BF00852AC5 /* SelectionMapping.swift */; }; 48 | 13FFA38D1F93469000852AC5 /* MappingDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA3871F93450200852AC5 /* MappingDefinition.swift */; }; 49 | 13FFA38E1F93469000852AC5 /* ComposingMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D45CD11F9340F600D4CE5D /* ComposingMapping.swift */; }; 50 | 13FFA38F1F93469000852AC5 /* NormalMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA3891F93455B00852AC5 /* NormalMapping.swift */; }; 51 | 13FFA3901F93469000852AC5 /* SelectionMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FFA38B1F9345BF00852AC5 /* SelectionMapping.swift */; }; 52 | 5D1F7FDD665FF9804AF7D101 /* Pods_App_Preferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B494E87050783B4832BE9B16 /* Pods_App_Preferences.framework */; }; 53 | 5E7D0D81BC08254996EC1B33 /* Pods_App_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A18E5675D99E8F48FCF12A7 /* Pods_App_Tests.framework */; }; 54 | 62C3338358EABF73DAE424C3 /* Pods_App_EmojiIM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56A1EA7CC6D607D11255E39C /* Pods_App_EmojiIM.framework */; }; 55 | /* End PBXBuildFile section */ 56 | 57 | /* Begin PBXContainerItemProxy section */ 58 | 13AC722D1FAD4E0400585E3B /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 130DC5C91F65F91D00BBCB60 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = 13AC721C1FAD4D7200585E3B; 63 | remoteInfo = Preferences; 64 | }; 65 | 13BE30451F731F7B001D3AF8 /* PBXContainerItemProxy */ = { 66 | isa = PBXContainerItemProxy; 67 | containerPortal = 130DC5C91F65F91D00BBCB60 /* Project object */; 68 | proxyType = 1; 69 | remoteGlobalIDString = 130DC5D01F65F91D00BBCB60; 70 | remoteInfo = EmojiIM; 71 | }; 72 | /* End PBXContainerItemProxy section */ 73 | 74 | /* Begin PBXCopyFilesBuildPhase section */ 75 | 13AC722F1FAD4E1400585E3B /* Copy Preferences Pane */ = { 76 | isa = PBXCopyFilesBuildPhase; 77 | buildActionMask = 2147483647; 78 | dstPath = ""; 79 | dstSubfolderSpec = 7; 80 | files = ( 81 | 13AC72301FAD4E2400585E3B /* Preferences.prefPane in Copy Preferences Pane */, 82 | ); 83 | name = "Copy Preferences Pane"; 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXCopyFilesBuildPhase section */ 87 | 88 | /* Begin PBXFileReference section */ 89 | 130423681F6C9927008989B1 /* InputMethodIcon@2x.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "InputMethodIcon@2x.tiff"; sourceTree = ""; }; 90 | 130DC5D11F65F91D00BBCB60 /* EmojiIM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EmojiIM.app; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | 130DC5D41F65F91D00BBCB60 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 92 | 130DC5D61F65F91D00BBCB60 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 93 | 130DC5D91F65F91D00BBCB60 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 94 | 130DC5DB1F65F91D00BBCB60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 95 | 130DC5DC1F65F91D00BBCB60 /* EmojiIM.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EmojiIM.entitlements; sourceTree = ""; }; 96 | 1313B8221F935741004B6A2F /* EmojiDefinition.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = EmojiDefinition.json; sourceTree = ""; }; 97 | 1313B8231F93579E004B6A2F /* EmojiDictionaryTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiDictionaryTest.swift; sourceTree = ""; }; 98 | 134427A11FB88D39002C68F9 /* BridgeHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgeHeader.h; sourceTree = ""; }; 99 | 134922DE1F6B33AF000AA483 /* EmojiInputController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiInputController.swift; sourceTree = ""; }; 100 | 134922E01F6B33B9000AA483 /* InputMethodIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = InputMethodIcon.tiff; sourceTree = ""; }; 101 | 134CE31A20FC882200BC4009 /* TISInputSourceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TISInputSourceTest.swift; sourceTree = ""; }; 102 | 136A4CCC1F904CA20020BDBE /* EmojiDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiDictionary.swift; sourceTree = ""; }; 103 | 13779B971FB3351C001529BF /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 104 | 13A455D01F9F5E1D00F2D3EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = ""; }; 105 | 13AC721D1FAD4D7200585E3B /* Preferences.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Preferences.prefPane; sourceTree = BUILT_PRODUCTS_DIR; }; 106 | 13AC72231FAD4D7200585E3B /* Preferences.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Preferences.tiff; sourceTree = ""; }; 107 | 13AC72261FAD4D7200585E3B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Preferences.xib; sourceTree = ""; }; 108 | 13AC72281FAD4D7200585E3B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 109 | 13B7E6611F6D631F008C528A /* BuildInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildInfo.swift; sourceTree = ""; }; 110 | 13BE30401F731F7B001D3AF8 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 111 | 13BE30421F731F7B001D3AF8 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 112 | 13BE30441F731F7B001D3AF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 113 | 13BE30571F732577001D3AF8 /* ReactiveAutomaton+Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReactiveAutomaton+Action.swift"; sourceTree = ""; }; 114 | 13BE30581F7325BA001D3AF8 /* InputMethodState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputMethodState.swift; sourceTree = ""; }; 115 | 13BE30591F7325BA001D3AF8 /* UserInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInput.swift; sourceTree = ""; }; 116 | 13BE305A1F7325BA001D3AF8 /* EmojiAutomaton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiAutomaton.swift; sourceTree = ""; }; 117 | 13BE30621F7325E6001D3AF8 /* AutomatonTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomatonTest.swift; sourceTree = ""; }; 118 | 13C46F241FB86E0E005A8348 /* NSTextField+Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextField+Label.swift"; sourceTree = ""; }; 119 | 13C46F251FB86E0E005A8348 /* Collection+Every.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Every.swift"; sourceTree = ""; }; 120 | 13D45CD11F9340F600D4CE5D /* ComposingMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposingMapping.swift; sourceTree = ""; }; 121 | 13EBC2FE1FB91FA20036A072 /* SettingStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingStore.swift; sourceTree = ""; }; 122 | 13EBC3011FB9B1790036A072 /* TISInputSource+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TISInputSource+Property.swift"; sourceTree = ""; }; 123 | 13FFA3871F93450200852AC5 /* MappingDefinition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MappingDefinition.swift; sourceTree = ""; }; 124 | 13FFA3891F93455B00852AC5 /* NormalMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NormalMapping.swift; sourceTree = ""; }; 125 | 13FFA38B1F9345BF00852AC5 /* SelectionMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionMapping.swift; sourceTree = ""; }; 126 | 2A18E5675D99E8F48FCF12A7 /* Pods_App_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 127 | 56A1EA7CC6D607D11255E39C /* Pods_App_EmojiIM.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App_EmojiIM.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 128 | 6758A5B9F5A7934030A29990 /* Pods-App-EmojiIM.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-EmojiIM.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App-EmojiIM/Pods-App-EmojiIM.debug.xcconfig"; sourceTree = ""; }; 129 | A06EE18786E85339F30239C2 /* Pods-App-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App-Tests/Pods-App-Tests.debug.xcconfig"; sourceTree = ""; }; 130 | B494E87050783B4832BE9B16 /* Pods_App_Preferences.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App_Preferences.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 131 | D0B6E94700E2F417D33648E9 /* Pods-App-Preferences.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Preferences.release.xcconfig"; path = "Pods/Target Support Files/Pods-App-Preferences/Pods-App-Preferences.release.xcconfig"; sourceTree = ""; }; 132 | D153801FDD87A2200FA8B3FE /* Pods-App-EmojiIM.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-EmojiIM.release.xcconfig"; path = "Pods/Target Support Files/Pods-App-EmojiIM/Pods-App-EmojiIM.release.xcconfig"; sourceTree = ""; }; 133 | DDB61C9BCDAD0639BAA71AE3 /* Pods-App-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-App-Tests/Pods-App-Tests.release.xcconfig"; sourceTree = ""; }; 134 | F6584D07C0ED724FC517EC11 /* Pods-App-Preferences.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Preferences.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App-Preferences/Pods-App-Preferences.debug.xcconfig"; sourceTree = ""; }; 135 | /* End PBXFileReference section */ 136 | 137 | /* Begin PBXFrameworksBuildPhase section */ 138 | 130DC5CE1F65F91D00BBCB60 /* Frameworks */ = { 139 | isa = PBXFrameworksBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | 62C3338358EABF73DAE424C3 /* Pods_App_EmojiIM.framework in Frameworks */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | 13AC72191FAD4D7200585E3B /* Frameworks */ = { 147 | isa = PBXFrameworksBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 5D1F7FDD665FF9804AF7D101 /* Pods_App_Preferences.framework in Frameworks */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | 13BE303D1F731F7B001D3AF8 /* Frameworks */ = { 155 | isa = PBXFrameworksBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 5E7D0D81BC08254996EC1B33 /* Pods_App_Tests.framework in Frameworks */, 159 | ); 160 | runOnlyForDeploymentPostprocessing = 0; 161 | }; 162 | /* End PBXFrameworksBuildPhase section */ 163 | 164 | /* Begin PBXGroup section */ 165 | 130DC5C81F65F91D00BBCB60 = { 166 | isa = PBXGroup; 167 | children = ( 168 | 13B7E6611F6D631F008C528A /* BuildInfo.swift */, 169 | 130DC5E21F65F95E00BBCB60 /* Sources */, 170 | 13BE30411F731F7B001D3AF8 /* Tests */, 171 | 130DC5D31F65F91D00BBCB60 /* Resources */, 172 | 130DC5D21F65F91D00BBCB60 /* Products */, 173 | 2D2EACD9BFBC3224766BFCB3 /* Pods */, 174 | D64E41A34C7490A75ED1353D /* Frameworks */, 175 | ); 176 | sourceTree = ""; 177 | }; 178 | 130DC5D21F65F91D00BBCB60 /* Products */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 130DC5D11F65F91D00BBCB60 /* EmojiIM.app */, 182 | 13BE30401F731F7B001D3AF8 /* Tests.xctest */, 183 | 13AC721D1FAD4D7200585E3B /* Preferences.prefPane */, 184 | ); 185 | name = Products; 186 | sourceTree = ""; 187 | }; 188 | 130DC5D31F65F91D00BBCB60 /* Resources */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 13AC72171FAD4D1100585E3B /* EmojiIM */, 192 | 13AC722C1FAD4D8B00585E3B /* Preferences */, 193 | ); 194 | path = Resources; 195 | sourceTree = ""; 196 | }; 197 | 130DC5E21F65F95E00BBCB60 /* Sources */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 130DC5D41F65F91D00BBCB60 /* AppDelegate.swift */, 201 | 134427A11FB88D39002C68F9 /* BridgeHeader.h */, 202 | 13BE30541F73255D001D3AF8 /* Automaton */, 203 | 136A4CCB1F904C870020BDBE /* Dictionary */, 204 | 13C46F231FB86DF4005A8348 /* Extension */, 205 | 13BE304A1F73222F001D3AF8 /* InputMethodKit */, 206 | 13AC721E1FAD4D7200585E3B /* Preferences */, 207 | 13EBC2FD1FB91F410036A072 /* Setting */, 208 | ); 209 | path = Sources; 210 | sourceTree = ""; 211 | }; 212 | 1313B8251F9357B0004B6A2F /* Dictionary */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 1313B8231F93579E004B6A2F /* EmojiDictionaryTest.swift */, 216 | ); 217 | path = Dictionary; 218 | sourceTree = ""; 219 | }; 220 | 134CE31920FC880100BC4009 /* Extension */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 134CE31A20FC882200BC4009 /* TISInputSourceTest.swift */, 224 | ); 225 | path = Extension; 226 | sourceTree = ""; 227 | }; 228 | 136A4CCB1F904C870020BDBE /* Dictionary */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 136A4CCC1F904CA20020BDBE /* EmojiDictionary.swift */, 232 | ); 233 | path = Dictionary; 234 | sourceTree = ""; 235 | }; 236 | 13AC72171FAD4D1100585E3B /* EmojiIM */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 130DC5DB1F65F91D00BBCB60 /* Info.plist */, 240 | 13A455CF1F9F5D2900F2D3EA /* InfoPlist.strings */, 241 | 130DC5D61F65F91D00BBCB60 /* Assets.xcassets */, 242 | 130DC5D81F65F91D00BBCB60 /* MainMenu.xib */, 243 | 134922E01F6B33B9000AA483 /* InputMethodIcon.tiff */, 244 | 130423681F6C9927008989B1 /* InputMethodIcon@2x.tiff */, 245 | 130DC5DC1F65F91D00BBCB60 /* EmojiIM.entitlements */, 246 | 1313B8221F935741004B6A2F /* EmojiDefinition.json */, 247 | ); 248 | path = EmojiIM; 249 | sourceTree = ""; 250 | }; 251 | 13AC721E1FAD4D7200585E3B /* Preferences */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | 13779B971FB3351C001529BF /* Preferences.swift */, 255 | ); 256 | path = Preferences; 257 | sourceTree = ""; 258 | }; 259 | 13AC722C1FAD4D8B00585E3B /* Preferences */ = { 260 | isa = PBXGroup; 261 | children = ( 262 | 13AC72231FAD4D7200585E3B /* Preferences.tiff */, 263 | 13AC72251FAD4D7200585E3B /* Preferences.xib */, 264 | 13AC72281FAD4D7200585E3B /* Info.plist */, 265 | ); 266 | path = Preferences; 267 | sourceTree = ""; 268 | }; 269 | 13BE30411F731F7B001D3AF8 /* Tests */ = { 270 | isa = PBXGroup; 271 | children = ( 272 | 13BE30611F7325E6001D3AF8 /* Automaton */, 273 | 1313B8251F9357B0004B6A2F /* Dictionary */, 274 | 134CE31920FC880100BC4009 /* Extension */, 275 | 13BE30421F731F7B001D3AF8 /* Tests.swift */, 276 | 13BE30441F731F7B001D3AF8 /* Info.plist */, 277 | ); 278 | path = Tests; 279 | sourceTree = ""; 280 | }; 281 | 13BE304A1F73222F001D3AF8 /* InputMethodKit */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | 134922DE1F6B33AF000AA483 /* EmojiInputController.swift */, 285 | ); 286 | path = InputMethodKit; 287 | sourceTree = ""; 288 | }; 289 | 13BE30541F73255D001D3AF8 /* Automaton */ = { 290 | isa = PBXGroup; 291 | children = ( 292 | 13FFA3861F9344F200852AC5 /* Mapping */, 293 | 13BE30571F732577001D3AF8 /* ReactiveAutomaton+Action.swift */, 294 | 13BE305A1F7325BA001D3AF8 /* EmojiAutomaton.swift */, 295 | 13BE30581F7325BA001D3AF8 /* InputMethodState.swift */, 296 | 13BE30591F7325BA001D3AF8 /* UserInput.swift */, 297 | ); 298 | path = Automaton; 299 | sourceTree = ""; 300 | }; 301 | 13BE30611F7325E6001D3AF8 /* Automaton */ = { 302 | isa = PBXGroup; 303 | children = ( 304 | 13BE30621F7325E6001D3AF8 /* AutomatonTest.swift */, 305 | ); 306 | path = Automaton; 307 | sourceTree = ""; 308 | }; 309 | 13C46F231FB86DF4005A8348 /* Extension */ = { 310 | isa = PBXGroup; 311 | children = ( 312 | 13C46F251FB86E0E005A8348 /* Collection+Every.swift */, 313 | 13C46F241FB86E0E005A8348 /* NSTextField+Label.swift */, 314 | 13EBC3011FB9B1790036A072 /* TISInputSource+Property.swift */, 315 | ); 316 | path = Extension; 317 | sourceTree = ""; 318 | }; 319 | 13EBC2FD1FB91F410036A072 /* Setting */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | 13EBC2FE1FB91FA20036A072 /* SettingStore.swift */, 323 | ); 324 | path = Setting; 325 | sourceTree = ""; 326 | }; 327 | 13FFA3861F9344F200852AC5 /* Mapping */ = { 328 | isa = PBXGroup; 329 | children = ( 330 | 13FFA3871F93450200852AC5 /* MappingDefinition.swift */, 331 | 13D45CD11F9340F600D4CE5D /* ComposingMapping.swift */, 332 | 13FFA3891F93455B00852AC5 /* NormalMapping.swift */, 333 | 13FFA38B1F9345BF00852AC5 /* SelectionMapping.swift */, 334 | ); 335 | path = Mapping; 336 | sourceTree = ""; 337 | }; 338 | 2D2EACD9BFBC3224766BFCB3 /* Pods */ = { 339 | isa = PBXGroup; 340 | children = ( 341 | 6758A5B9F5A7934030A29990 /* Pods-App-EmojiIM.debug.xcconfig */, 342 | D153801FDD87A2200FA8B3FE /* Pods-App-EmojiIM.release.xcconfig */, 343 | A06EE18786E85339F30239C2 /* Pods-App-Tests.debug.xcconfig */, 344 | DDB61C9BCDAD0639BAA71AE3 /* Pods-App-Tests.release.xcconfig */, 345 | F6584D07C0ED724FC517EC11 /* Pods-App-Preferences.debug.xcconfig */, 346 | D0B6E94700E2F417D33648E9 /* Pods-App-Preferences.release.xcconfig */, 347 | ); 348 | name = Pods; 349 | sourceTree = ""; 350 | }; 351 | D64E41A34C7490A75ED1353D /* Frameworks */ = { 352 | isa = PBXGroup; 353 | children = ( 354 | 56A1EA7CC6D607D11255E39C /* Pods_App_EmojiIM.framework */, 355 | 2A18E5675D99E8F48FCF12A7 /* Pods_App_Tests.framework */, 356 | B494E87050783B4832BE9B16 /* Pods_App_Preferences.framework */, 357 | ); 358 | name = Frameworks; 359 | sourceTree = ""; 360 | }; 361 | /* End PBXGroup section */ 362 | 363 | /* Begin PBXHeadersBuildPhase section */ 364 | 13AC721A1FAD4D7200585E3B /* Headers */ = { 365 | isa = PBXHeadersBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | /* End PBXHeadersBuildPhase section */ 372 | 373 | /* Begin PBXNativeTarget section */ 374 | 130DC5D01F65F91D00BBCB60 /* EmojiIM */ = { 375 | isa = PBXNativeTarget; 376 | buildConfigurationList = 130DC5DF1F65F91D00BBCB60 /* Build configuration list for PBXNativeTarget "EmojiIM" */; 377 | buildPhases = ( 378 | 68A350217DEEF2B9CFBE52DD /* [CP] Check Pods Manifest.lock */, 379 | 13B7E6601F6D6288008C528A /* EmbedBuildInfo */, 380 | 130DC5E31F65FB5A00BBCB60 /* SwiftLint */, 381 | 130DC5CD1F65F91D00BBCB60 /* Sources */, 382 | 130DC5CE1F65F91D00BBCB60 /* Frameworks */, 383 | 130DC5CF1F65F91D00BBCB60 /* Resources */, 384 | 653CC9549B17E6922B7DC7B8 /* [CP] Embed Pods Frameworks */, 385 | 13AC722F1FAD4E1400585E3B /* Copy Preferences Pane */, 386 | ); 387 | buildRules = ( 388 | ); 389 | dependencies = ( 390 | 13AC722E1FAD4E0400585E3B /* PBXTargetDependency */, 391 | ); 392 | name = EmojiIM; 393 | productName = EmojiIM; 394 | productReference = 130DC5D11F65F91D00BBCB60 /* EmojiIM.app */; 395 | productType = "com.apple.product-type.application"; 396 | }; 397 | 13AC721C1FAD4D7200585E3B /* Preferences */ = { 398 | isa = PBXNativeTarget; 399 | buildConfigurationList = 13AC72291FAD4D7200585E3B /* Build configuration list for PBXNativeTarget "Preferences" */; 400 | buildPhases = ( 401 | 04CB663ABD2571D5069DCACF /* [CP] Check Pods Manifest.lock */, 402 | 13AC72181FAD4D7200585E3B /* Sources */, 403 | 13AC72191FAD4D7200585E3B /* Frameworks */, 404 | 13AC721A1FAD4D7200585E3B /* Headers */, 405 | 13AC721B1FAD4D7200585E3B /* Resources */, 406 | ); 407 | buildRules = ( 408 | ); 409 | dependencies = ( 410 | ); 411 | name = Preferences; 412 | productName = Preferences; 413 | productReference = 13AC721D1FAD4D7200585E3B /* Preferences.prefPane */; 414 | productType = "com.apple.product-type.bundle"; 415 | }; 416 | 13BE303F1F731F7B001D3AF8 /* Tests */ = { 417 | isa = PBXNativeTarget; 418 | buildConfigurationList = 13BE30491F731F7B001D3AF8 /* Build configuration list for PBXNativeTarget "Tests" */; 419 | buildPhases = ( 420 | EC78CF836CE60D31DBDD9ACB /* [CP] Check Pods Manifest.lock */, 421 | 13BE303C1F731F7B001D3AF8 /* Sources */, 422 | 13BE303D1F731F7B001D3AF8 /* Frameworks */, 423 | 13BE303E1F731F7B001D3AF8 /* Resources */, 424 | 4423F8C02B3FB0B96398F1CE /* [CP] Embed Pods Frameworks */, 425 | ); 426 | buildRules = ( 427 | ); 428 | dependencies = ( 429 | 13BE30461F731F7B001D3AF8 /* PBXTargetDependency */, 430 | ); 431 | name = Tests; 432 | productName = Tests; 433 | productReference = 13BE30401F731F7B001D3AF8 /* Tests.xctest */; 434 | productType = "com.apple.product-type.bundle.unit-test"; 435 | }; 436 | /* End PBXNativeTarget section */ 437 | 438 | /* Begin PBXProject section */ 439 | 130DC5C91F65F91D00BBCB60 /* Project object */ = { 440 | isa = PBXProject; 441 | attributes = { 442 | LastSwiftUpdateCheck = 0900; 443 | LastUpgradeCheck = 0900; 444 | ORGANIZATIONNAME = mzp; 445 | TargetAttributes = { 446 | 130DC5D01F65F91D00BBCB60 = { 447 | CreatedOnToolsVersion = 9.0; 448 | ProvisioningStyle = Automatic; 449 | SystemCapabilities = { 450 | com.apple.Sandbox = { 451 | enabled = 1; 452 | }; 453 | }; 454 | }; 455 | 13AC721C1FAD4D7200585E3B = { 456 | CreatedOnToolsVersion = 9.1; 457 | ProvisioningStyle = Automatic; 458 | }; 459 | 13BE303F1F731F7B001D3AF8 = { 460 | CreatedOnToolsVersion = 9.0; 461 | ProvisioningStyle = Automatic; 462 | TestTargetID = 130DC5D01F65F91D00BBCB60; 463 | }; 464 | }; 465 | }; 466 | buildConfigurationList = 130DC5CC1F65F91D00BBCB60 /* Build configuration list for PBXProject "EmojiIM" */; 467 | compatibilityVersion = "Xcode 8.0"; 468 | developmentRegion = en; 469 | hasScannedForEncodings = 0; 470 | knownRegions = ( 471 | en, 472 | Base, 473 | ); 474 | mainGroup = 130DC5C81F65F91D00BBCB60; 475 | productRefGroup = 130DC5D21F65F91D00BBCB60 /* Products */; 476 | projectDirPath = ""; 477 | projectRoot = ""; 478 | targets = ( 479 | 130DC5D01F65F91D00BBCB60 /* EmojiIM */, 480 | 13BE303F1F731F7B001D3AF8 /* Tests */, 481 | 13AC721C1FAD4D7200585E3B /* Preferences */, 482 | ); 483 | }; 484 | /* End PBXProject section */ 485 | 486 | /* Begin PBXResourcesBuildPhase section */ 487 | 130DC5CF1F65F91D00BBCB60 /* Resources */ = { 488 | isa = PBXResourcesBuildPhase; 489 | buildActionMask = 2147483647; 490 | files = ( 491 | 134A02F01F6B36C60050216F /* InputMethodIcon.tiff in Resources */, 492 | 13A455CD1F9F5D2900F2D3EA /* InfoPlist.strings in Resources */, 493 | 1313B8271F935DAA004B6A2F /* EmojiDefinition.json in Resources */, 494 | 130DC5D71F65F91D00BBCB60 /* Assets.xcassets in Resources */, 495 | 130DC5DA1F65F91D00BBCB60 /* MainMenu.xib in Resources */, 496 | ); 497 | runOnlyForDeploymentPostprocessing = 0; 498 | }; 499 | 13AC721B1FAD4D7200585E3B /* Resources */ = { 500 | isa = PBXResourcesBuildPhase; 501 | buildActionMask = 2147483647; 502 | files = ( 503 | 13AC72271FAD4D7200585E3B /* Preferences.xib in Resources */, 504 | 13AC72241FAD4D7200585E3B /* Preferences.tiff in Resources */, 505 | ); 506 | runOnlyForDeploymentPostprocessing = 0; 507 | }; 508 | 13BE303E1F731F7B001D3AF8 /* Resources */ = { 509 | isa = PBXResourcesBuildPhase; 510 | buildActionMask = 2147483647; 511 | files = ( 512 | 1313B8261F935DA9004B6A2F /* EmojiDefinition.json in Resources */, 513 | ); 514 | runOnlyForDeploymentPostprocessing = 0; 515 | }; 516 | /* End PBXResourcesBuildPhase section */ 517 | 518 | /* Begin PBXShellScriptBuildPhase section */ 519 | 04CB663ABD2571D5069DCACF /* [CP] Check Pods Manifest.lock */ = { 520 | isa = PBXShellScriptBuildPhase; 521 | buildActionMask = 2147483647; 522 | files = ( 523 | ); 524 | inputPaths = ( 525 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 526 | "${PODS_ROOT}/Manifest.lock", 527 | ); 528 | name = "[CP] Check Pods Manifest.lock"; 529 | outputPaths = ( 530 | "$(DERIVED_FILE_DIR)/Pods-App-Preferences-checkManifestLockResult.txt", 531 | ); 532 | runOnlyForDeploymentPostprocessing = 0; 533 | shellPath = /bin/sh; 534 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 535 | showEnvVarsInLog = 0; 536 | }; 537 | 130DC5E31F65FB5A00BBCB60 /* SwiftLint */ = { 538 | isa = PBXShellScriptBuildPhase; 539 | buildActionMask = 2147483647; 540 | files = ( 541 | ); 542 | inputPaths = ( 543 | ); 544 | name = SwiftLint; 545 | outputPaths = ( 546 | ); 547 | runOnlyForDeploymentPostprocessing = 0; 548 | shellPath = /bin/sh; 549 | shellScript = "# disable swiftlint temporary. \n# cd \"${PODS_ROOT}/..\"\n# \"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; 550 | }; 551 | 13B7E6601F6D6288008C528A /* EmbedBuildInfo */ = { 552 | isa = PBXShellScriptBuildPhase; 553 | buildActionMask = 2147483647; 554 | files = ( 555 | ); 556 | inputPaths = ( 557 | ); 558 | name = EmbedBuildInfo; 559 | outputPaths = ( 560 | ); 561 | runOnlyForDeploymentPostprocessing = 0; 562 | shellPath = /bin/sh; 563 | shellScript = fastlane/embed_buildinfo; 564 | }; 565 | 4423F8C02B3FB0B96398F1CE /* [CP] Embed Pods Frameworks */ = { 566 | isa = PBXShellScriptBuildPhase; 567 | buildActionMask = 2147483647; 568 | files = ( 569 | ); 570 | inputPaths = ( 571 | "${SRCROOT}/Pods/Target Support Files/Pods-App-Tests/Pods-App-Tests-frameworks.sh", 572 | "${BUILT_PRODUCTS_DIR}/FootlessParser/FootlessParser.framework", 573 | "${BUILT_PRODUCTS_DIR}/NorthLayout/NorthLayout.framework", 574 | "${BUILT_PRODUCTS_DIR}/ReactiveAutomaton/ReactiveAutomaton.framework", 575 | "${BUILT_PRODUCTS_DIR}/ReactiveCocoa/ReactiveCocoa.framework", 576 | "${BUILT_PRODUCTS_DIR}/ReactiveSwift/ReactiveSwift.framework", 577 | "${BUILT_PRODUCTS_DIR}/Result/Result.framework", 578 | "${BUILT_PRODUCTS_DIR}/※ikemen/Ikemen.framework", 579 | ); 580 | name = "[CP] Embed Pods Frameworks"; 581 | outputPaths = ( 582 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FootlessParser.framework", 583 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NorthLayout.framework", 584 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveAutomaton.framework", 585 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveCocoa.framework", 586 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveSwift.framework", 587 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Result.framework", 588 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Ikemen.framework", 589 | ); 590 | runOnlyForDeploymentPostprocessing = 0; 591 | shellPath = /bin/sh; 592 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-App-Tests/Pods-App-Tests-frameworks.sh\"\n"; 593 | showEnvVarsInLog = 0; 594 | }; 595 | 653CC9549B17E6922B7DC7B8 /* [CP] Embed Pods Frameworks */ = { 596 | isa = PBXShellScriptBuildPhase; 597 | buildActionMask = 2147483647; 598 | files = ( 599 | ); 600 | inputPaths = ( 601 | "${SRCROOT}/Pods/Target Support Files/Pods-App-EmojiIM/Pods-App-EmojiIM-frameworks.sh", 602 | "${BUILT_PRODUCTS_DIR}/FootlessParser/FootlessParser.framework", 603 | "${BUILT_PRODUCTS_DIR}/NorthLayout/NorthLayout.framework", 604 | "${BUILT_PRODUCTS_DIR}/ReactiveAutomaton/ReactiveAutomaton.framework", 605 | "${BUILT_PRODUCTS_DIR}/ReactiveCocoa/ReactiveCocoa.framework", 606 | "${BUILT_PRODUCTS_DIR}/ReactiveSwift/ReactiveSwift.framework", 607 | "${BUILT_PRODUCTS_DIR}/Result/Result.framework", 608 | "${BUILT_PRODUCTS_DIR}/※ikemen/Ikemen.framework", 609 | ); 610 | name = "[CP] Embed Pods Frameworks"; 611 | outputPaths = ( 612 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FootlessParser.framework", 613 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NorthLayout.framework", 614 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveAutomaton.framework", 615 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveCocoa.framework", 616 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveSwift.framework", 617 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Result.framework", 618 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Ikemen.framework", 619 | ); 620 | runOnlyForDeploymentPostprocessing = 0; 621 | shellPath = /bin/sh; 622 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-App-EmojiIM/Pods-App-EmojiIM-frameworks.sh\"\n"; 623 | showEnvVarsInLog = 0; 624 | }; 625 | 68A350217DEEF2B9CFBE52DD /* [CP] Check Pods Manifest.lock */ = { 626 | isa = PBXShellScriptBuildPhase; 627 | buildActionMask = 2147483647; 628 | files = ( 629 | ); 630 | inputPaths = ( 631 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 632 | "${PODS_ROOT}/Manifest.lock", 633 | ); 634 | name = "[CP] Check Pods Manifest.lock"; 635 | outputPaths = ( 636 | "$(DERIVED_FILE_DIR)/Pods-App-EmojiIM-checkManifestLockResult.txt", 637 | ); 638 | runOnlyForDeploymentPostprocessing = 0; 639 | shellPath = /bin/sh; 640 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 641 | showEnvVarsInLog = 0; 642 | }; 643 | EC78CF836CE60D31DBDD9ACB /* [CP] Check Pods Manifest.lock */ = { 644 | isa = PBXShellScriptBuildPhase; 645 | buildActionMask = 2147483647; 646 | files = ( 647 | ); 648 | inputPaths = ( 649 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 650 | "${PODS_ROOT}/Manifest.lock", 651 | ); 652 | name = "[CP] Check Pods Manifest.lock"; 653 | outputPaths = ( 654 | "$(DERIVED_FILE_DIR)/Pods-App-Tests-checkManifestLockResult.txt", 655 | ); 656 | runOnlyForDeploymentPostprocessing = 0; 657 | shellPath = /bin/sh; 658 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 659 | showEnvVarsInLog = 0; 660 | }; 661 | /* End PBXShellScriptBuildPhase section */ 662 | 663 | /* Begin PBXSourcesBuildPhase section */ 664 | 130DC5CD1F65F91D00BBCB60 /* Sources */ = { 665 | isa = PBXSourcesBuildPhase; 666 | buildActionMask = 2147483647; 667 | files = ( 668 | 13D45CD21F9340F600D4CE5D /* ComposingMapping.swift in Sources */, 669 | 13DD45F41FB9C9D100EE1758 /* SettingStore.swift in Sources */, 670 | 130DC5D51F65F91D00BBCB60 /* AppDelegate.swift in Sources */, 671 | 13FFA38C1F9345BF00852AC5 /* SelectionMapping.swift in Sources */, 672 | 13FFA3881F93450200852AC5 /* MappingDefinition.swift in Sources */, 673 | 13BE305E1F7325CC001D3AF8 /* UserInput.swift in Sources */, 674 | 136A4CCD1F904CA20020BDBE /* EmojiDictionary.swift in Sources */, 675 | 13B7E6621F6D6327008C528A /* BuildInfo.swift in Sources */, 676 | 13BE305D1F7325CC001D3AF8 /* InputMethodState.swift in Sources */, 677 | 134922DF1F6B33AF000AA483 /* EmojiInputController.swift in Sources */, 678 | 13BE30631F7325F9001D3AF8 /* ReactiveAutomaton+Action.swift in Sources */, 679 | 13C46F261FB86E10005A8348 /* Collection+Every.swift in Sources */, 680 | 13BE305B1F7325C8001D3AF8 /* EmojiAutomaton.swift in Sources */, 681 | 13FFA38A1F93455B00852AC5 /* NormalMapping.swift in Sources */, 682 | ); 683 | runOnlyForDeploymentPostprocessing = 0; 684 | }; 685 | 13AC72181FAD4D7200585E3B /* Sources */ = { 686 | isa = PBXSourcesBuildPhase; 687 | buildActionMask = 2147483647; 688 | files = ( 689 | 13EBC3021FB9B1790036A072 /* TISInputSource+Property.swift in Sources */, 690 | 13EBC3001FB91FC90036A072 /* SettingStore.swift in Sources */, 691 | 13779B981FB3351C001529BF /* Preferences.swift in Sources */, 692 | 13C46F281FB86EB3005A8348 /* BuildInfo.swift in Sources */, 693 | 13C46F271FB86E14005A8348 /* NSTextField+Label.swift in Sources */, 694 | ); 695 | runOnlyForDeploymentPostprocessing = 0; 696 | }; 697 | 13BE303C1F731F7B001D3AF8 /* Sources */ = { 698 | isa = PBXSourcesBuildPhase; 699 | buildActionMask = 2147483647; 700 | files = ( 701 | 13BE30431F731F7B001D3AF8 /* Tests.swift in Sources */, 702 | 13BE30601F7325CD001D3AF8 /* UserInput.swift in Sources */, 703 | 1313B8241F93579E004B6A2F /* EmojiDictionaryTest.swift in Sources */, 704 | 13AE25131F9052730073912E /* EmojiDictionary.swift in Sources */, 705 | 13BE305C1F7325C9001D3AF8 /* EmojiAutomaton.swift in Sources */, 706 | 13BE305F1F7325CD001D3AF8 /* InputMethodState.swift in Sources */, 707 | 134CE31B20FC882200BC4009 /* TISInputSourceTest.swift in Sources */, 708 | 134CE31C20FC885200BC4009 /* TISInputSource+Property.swift in Sources */, 709 | 13BE30651F73260E001D3AF8 /* AutomatonTest.swift in Sources */, 710 | 13BE30641F7325F9001D3AF8 /* ReactiveAutomaton+Action.swift in Sources */, 711 | 13FFA38F1F93469000852AC5 /* NormalMapping.swift in Sources */, 712 | 13FFA38E1F93469000852AC5 /* ComposingMapping.swift in Sources */, 713 | 13FFA38D1F93469000852AC5 /* MappingDefinition.swift in Sources */, 714 | 13FFA3901F93469000852AC5 /* SelectionMapping.swift in Sources */, 715 | ); 716 | runOnlyForDeploymentPostprocessing = 0; 717 | }; 718 | /* End PBXSourcesBuildPhase section */ 719 | 720 | /* Begin PBXTargetDependency section */ 721 | 13AC722E1FAD4E0400585E3B /* PBXTargetDependency */ = { 722 | isa = PBXTargetDependency; 723 | target = 13AC721C1FAD4D7200585E3B /* Preferences */; 724 | targetProxy = 13AC722D1FAD4E0400585E3B /* PBXContainerItemProxy */; 725 | }; 726 | 13BE30461F731F7B001D3AF8 /* PBXTargetDependency */ = { 727 | isa = PBXTargetDependency; 728 | target = 130DC5D01F65F91D00BBCB60 /* EmojiIM */; 729 | targetProxy = 13BE30451F731F7B001D3AF8 /* PBXContainerItemProxy */; 730 | }; 731 | /* End PBXTargetDependency section */ 732 | 733 | /* Begin PBXVariantGroup section */ 734 | 130DC5D81F65F91D00BBCB60 /* MainMenu.xib */ = { 735 | isa = PBXVariantGroup; 736 | children = ( 737 | 130DC5D91F65F91D00BBCB60 /* Base */, 738 | ); 739 | name = MainMenu.xib; 740 | sourceTree = ""; 741 | }; 742 | 13A455CF1F9F5D2900F2D3EA /* InfoPlist.strings */ = { 743 | isa = PBXVariantGroup; 744 | children = ( 745 | 13A455D01F9F5E1D00F2D3EA /* Base */, 746 | ); 747 | name = InfoPlist.strings; 748 | sourceTree = ""; 749 | }; 750 | 13AC72251FAD4D7200585E3B /* Preferences.xib */ = { 751 | isa = PBXVariantGroup; 752 | children = ( 753 | 13AC72261FAD4D7200585E3B /* Base */, 754 | ); 755 | name = Preferences.xib; 756 | sourceTree = ""; 757 | }; 758 | /* End PBXVariantGroup section */ 759 | 760 | /* Begin XCBuildConfiguration section */ 761 | 130DC5DD1F65F91D00BBCB60 /* Debug */ = { 762 | isa = XCBuildConfiguration; 763 | buildSettings = { 764 | ALWAYS_SEARCH_USER_PATHS = NO; 765 | CLANG_ANALYZER_NONNULL = YES; 766 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 767 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 768 | CLANG_CXX_LIBRARY = "libc++"; 769 | CLANG_ENABLE_MODULES = YES; 770 | CLANG_ENABLE_OBJC_ARC = YES; 771 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 772 | CLANG_WARN_BOOL_CONVERSION = YES; 773 | CLANG_WARN_COMMA = YES; 774 | CLANG_WARN_CONSTANT_CONVERSION = YES; 775 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 776 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 777 | CLANG_WARN_EMPTY_BODY = YES; 778 | CLANG_WARN_ENUM_CONVERSION = YES; 779 | CLANG_WARN_INFINITE_RECURSION = YES; 780 | CLANG_WARN_INT_CONVERSION = YES; 781 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 782 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 783 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 784 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 785 | CLANG_WARN_STRICT_PROTOTYPES = YES; 786 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 787 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 788 | CLANG_WARN_UNREACHABLE_CODE = YES; 789 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 790 | CODE_SIGN_IDENTITY = "-"; 791 | COPY_PHASE_STRIP = NO; 792 | DEBUG_INFORMATION_FORMAT = dwarf; 793 | ENABLE_STRICT_OBJC_MSGSEND = YES; 794 | ENABLE_TESTABILITY = YES; 795 | GCC_C_LANGUAGE_STANDARD = gnu11; 796 | GCC_DYNAMIC_NO_PIC = NO; 797 | GCC_NO_COMMON_BLOCKS = YES; 798 | GCC_OPTIMIZATION_LEVEL = 0; 799 | GCC_PREPROCESSOR_DEFINITIONS = ( 800 | "DEBUG=1", 801 | "$(inherited)", 802 | ); 803 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 804 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 805 | GCC_WARN_UNDECLARED_SELECTOR = YES; 806 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 807 | GCC_WARN_UNUSED_FUNCTION = YES; 808 | GCC_WARN_UNUSED_VARIABLE = YES; 809 | MACOSX_DEPLOYMENT_TARGET = 10.12; 810 | MTL_ENABLE_DEBUG_INFO = YES; 811 | ONLY_ACTIVE_ARCH = YES; 812 | SDKROOT = macosx; 813 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 814 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 815 | }; 816 | name = Debug; 817 | }; 818 | 130DC5DE1F65F91D00BBCB60 /* Release */ = { 819 | isa = XCBuildConfiguration; 820 | buildSettings = { 821 | ALWAYS_SEARCH_USER_PATHS = NO; 822 | CLANG_ANALYZER_NONNULL = YES; 823 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 824 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 825 | CLANG_CXX_LIBRARY = "libc++"; 826 | CLANG_ENABLE_MODULES = YES; 827 | CLANG_ENABLE_OBJC_ARC = YES; 828 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 829 | CLANG_WARN_BOOL_CONVERSION = YES; 830 | CLANG_WARN_COMMA = YES; 831 | CLANG_WARN_CONSTANT_CONVERSION = YES; 832 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 833 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 834 | CLANG_WARN_EMPTY_BODY = YES; 835 | CLANG_WARN_ENUM_CONVERSION = YES; 836 | CLANG_WARN_INFINITE_RECURSION = YES; 837 | CLANG_WARN_INT_CONVERSION = YES; 838 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 839 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 840 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 841 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 842 | CLANG_WARN_STRICT_PROTOTYPES = YES; 843 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 844 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 845 | CLANG_WARN_UNREACHABLE_CODE = YES; 846 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 847 | CODE_SIGN_IDENTITY = "-"; 848 | COPY_PHASE_STRIP = NO; 849 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 850 | ENABLE_NS_ASSERTIONS = NO; 851 | ENABLE_STRICT_OBJC_MSGSEND = YES; 852 | GCC_C_LANGUAGE_STANDARD = gnu11; 853 | GCC_NO_COMMON_BLOCKS = YES; 854 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 855 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 856 | GCC_WARN_UNDECLARED_SELECTOR = YES; 857 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 858 | GCC_WARN_UNUSED_FUNCTION = YES; 859 | GCC_WARN_UNUSED_VARIABLE = YES; 860 | MACOSX_DEPLOYMENT_TARGET = 10.12; 861 | MTL_ENABLE_DEBUG_INFO = NO; 862 | SDKROOT = macosx; 863 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 864 | }; 865 | name = Release; 866 | }; 867 | 130DC5E01F65F91D00BBCB60 /* Debug */ = { 868 | isa = XCBuildConfiguration; 869 | baseConfigurationReference = 6758A5B9F5A7934030A29990 /* Pods-App-EmojiIM.debug.xcconfig */; 870 | buildSettings = { 871 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 872 | CODE_SIGN_ENTITLEMENTS = Resources/EmojiIM/EmojiIM.entitlements; 873 | CODE_SIGN_IDENTITY = "Mac Developer"; 874 | CODE_SIGN_STYLE = Automatic; 875 | COMBINE_HIDPI_IMAGES = YES; 876 | DEVELOPMENT_TEAM = VG2YYSKSHY; 877 | INFOPLIST_FILE = Resources/EmojiIM/Info.plist; 878 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 879 | MACOSX_DEPLOYMENT_TARGET = 10.12; 880 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.inputmethod.EmojiIM; 881 | PRODUCT_NAME = "$(TARGET_NAME)"; 882 | PROVISIONING_PROFILE_SPECIFIER = ""; 883 | SWIFT_VERSION = 4.2; 884 | }; 885 | name = Debug; 886 | }; 887 | 130DC5E11F65F91D00BBCB60 /* Release */ = { 888 | isa = XCBuildConfiguration; 889 | baseConfigurationReference = D153801FDD87A2200FA8B3FE /* Pods-App-EmojiIM.release.xcconfig */; 890 | buildSettings = { 891 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 892 | CODE_SIGN_ENTITLEMENTS = Resources/EmojiIM/EmojiIM.entitlements; 893 | CODE_SIGN_IDENTITY = "Developer ID Application"; 894 | CODE_SIGN_STYLE = Manual; 895 | COMBINE_HIDPI_IMAGES = YES; 896 | DEVELOPMENT_TEAM = VG2YYSKSHY; 897 | INFOPLIST_FILE = Resources/EmojiIM/Info.plist; 898 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 899 | MACOSX_DEPLOYMENT_TARGET = 10.12; 900 | OTHER_CODE_SIGN_FLAGS = "--deep"; 901 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.inputmethod.EmojiIM; 902 | PRODUCT_NAME = "$(TARGET_NAME)"; 903 | PROVISIONING_PROFILE_SPECIFIER = ""; 904 | SWIFT_VERSION = 4.2; 905 | }; 906 | name = Release; 907 | }; 908 | 13AC722A1FAD4D7200585E3B /* Debug */ = { 909 | isa = XCBuildConfiguration; 910 | baseConfigurationReference = F6584D07C0ED724FC517EC11 /* Pods-App-Preferences.debug.xcconfig */; 911 | buildSettings = { 912 | CODE_SIGN_IDENTITY = "Mac Developer"; 913 | CODE_SIGN_STYLE = Automatic; 914 | COMBINE_HIDPI_IMAGES = YES; 915 | DEVELOPMENT_TEAM = VG2YYSKSHY; 916 | INFOPLIST_FILE = Resources/Preferences/Info.plist; 917 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/../../../../Frameworks"; 918 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.emojiim.Preferences; 919 | PRODUCT_NAME = "$(TARGET_NAME)"; 920 | PROVISIONING_PROFILE_SPECIFIER = ""; 921 | SWIFT_OBJC_BRIDGING_HEADER = Sources/BridgeHeader.h; 922 | SWIFT_VERSION = 4.2; 923 | WRAPPER_EXTENSION = prefPane; 924 | }; 925 | name = Debug; 926 | }; 927 | 13AC722B1FAD4D7200585E3B /* Release */ = { 928 | isa = XCBuildConfiguration; 929 | baseConfigurationReference = D0B6E94700E2F417D33648E9 /* Pods-App-Preferences.release.xcconfig */; 930 | buildSettings = { 931 | CODE_SIGN_IDENTITY = "Developer ID Application"; 932 | CODE_SIGN_STYLE = Manual; 933 | COMBINE_HIDPI_IMAGES = YES; 934 | DEVELOPMENT_TEAM = VG2YYSKSHY; 935 | INFOPLIST_FILE = Resources/Preferences/Info.plist; 936 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/../../../../Frameworks"; 937 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.emojiim.Preferences; 938 | PRODUCT_NAME = "$(TARGET_NAME)"; 939 | PROVISIONING_PROFILE_SPECIFIER = ""; 940 | SWIFT_OBJC_BRIDGING_HEADER = Sources/BridgeHeader.h; 941 | SWIFT_VERSION = 4.2; 942 | WRAPPER_EXTENSION = prefPane; 943 | }; 944 | name = Release; 945 | }; 946 | 13BE30471F731F7B001D3AF8 /* Debug */ = { 947 | isa = XCBuildConfiguration; 948 | baseConfigurationReference = A06EE18786E85339F30239C2 /* Pods-App-Tests.debug.xcconfig */; 949 | buildSettings = { 950 | BUNDLE_LOADER = "$(TEST_HOST)"; 951 | CODE_SIGN_IDENTITY = "Mac Developer"; 952 | CODE_SIGN_STYLE = Automatic; 953 | COMBINE_HIDPI_IMAGES = YES; 954 | DEVELOPMENT_TEAM = VG2YYSKSHY; 955 | INFOPLIST_FILE = Tests/Info.plist; 956 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 957 | MACOSX_DEPLOYMENT_TARGET = 10.13; 958 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.inputmethod.Tests; 959 | PRODUCT_NAME = "$(TARGET_NAME)"; 960 | PROVISIONING_PROFILE_SPECIFIER = ""; 961 | SWIFT_OBJC_BRIDGING_HEADER = Sources/BridgeHeader.h; 962 | SWIFT_VERSION = 4.2; 963 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EmojiIM.app/Contents/MacOS/EmojiIM"; 964 | }; 965 | name = Debug; 966 | }; 967 | 13BE30481F731F7B001D3AF8 /* Release */ = { 968 | isa = XCBuildConfiguration; 969 | baseConfigurationReference = DDB61C9BCDAD0639BAA71AE3 /* Pods-App-Tests.release.xcconfig */; 970 | buildSettings = { 971 | BUNDLE_LOADER = "$(TEST_HOST)"; 972 | CODE_SIGN_IDENTITY = "Developer ID Application"; 973 | CODE_SIGN_STYLE = Manual; 974 | COMBINE_HIDPI_IMAGES = YES; 975 | DEVELOPMENT_TEAM = VG2YYSKSHY; 976 | INFOPLIST_FILE = Tests/Info.plist; 977 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 978 | MACOSX_DEPLOYMENT_TARGET = 10.13; 979 | OTHER_CODE_SIGN_FLAGS = "--deep"; 980 | PRODUCT_BUNDLE_IDENTIFIER = jp.mzp.inputmethod.Tests; 981 | PRODUCT_NAME = "$(TARGET_NAME)"; 982 | PROVISIONING_PROFILE_SPECIFIER = ""; 983 | SWIFT_OBJC_BRIDGING_HEADER = Sources/BridgeHeader.h; 984 | SWIFT_VERSION = 4.2; 985 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EmojiIM.app/Contents/MacOS/EmojiIM"; 986 | }; 987 | name = Release; 988 | }; 989 | /* End XCBuildConfiguration section */ 990 | 991 | /* Begin XCConfigurationList section */ 992 | 130DC5CC1F65F91D00BBCB60 /* Build configuration list for PBXProject "EmojiIM" */ = { 993 | isa = XCConfigurationList; 994 | buildConfigurations = ( 995 | 130DC5DD1F65F91D00BBCB60 /* Debug */, 996 | 130DC5DE1F65F91D00BBCB60 /* Release */, 997 | ); 998 | defaultConfigurationIsVisible = 0; 999 | defaultConfigurationName = Release; 1000 | }; 1001 | 130DC5DF1F65F91D00BBCB60 /* Build configuration list for PBXNativeTarget "EmojiIM" */ = { 1002 | isa = XCConfigurationList; 1003 | buildConfigurations = ( 1004 | 130DC5E01F65F91D00BBCB60 /* Debug */, 1005 | 130DC5E11F65F91D00BBCB60 /* Release */, 1006 | ); 1007 | defaultConfigurationIsVisible = 0; 1008 | defaultConfigurationName = Release; 1009 | }; 1010 | 13AC72291FAD4D7200585E3B /* Build configuration list for PBXNativeTarget "Preferences" */ = { 1011 | isa = XCConfigurationList; 1012 | buildConfigurations = ( 1013 | 13AC722A1FAD4D7200585E3B /* Debug */, 1014 | 13AC722B1FAD4D7200585E3B /* Release */, 1015 | ); 1016 | defaultConfigurationIsVisible = 0; 1017 | defaultConfigurationName = Release; 1018 | }; 1019 | 13BE30491F731F7B001D3AF8 /* Build configuration list for PBXNativeTarget "Tests" */ = { 1020 | isa = XCConfigurationList; 1021 | buildConfigurations = ( 1022 | 13BE30471F731F7B001D3AF8 /* Debug */, 1023 | 13BE30481F731F7B001D3AF8 /* Release */, 1024 | ); 1025 | defaultConfigurationIsVisible = 0; 1026 | defaultConfigurationName = Release; 1027 | }; 1028 | /* End XCConfigurationList section */ 1029 | }; 1030 | rootObject = 130DC5C91F65F91D00BBCB60 /* Project object */; 1031 | } 1032 | --------------------------------------------------------------------------------