Repo // Massive nomenclature changes, etc.

This commit is contained in:
ShikiSuen 2022-10-11 09:09:38 +08:00
parent 458e7fa613
commit 6168cc32d0
21 changed files with 194 additions and 193 deletions

2
FAQ.md
View File

@ -90,6 +90,6 @@ xattr -dr com.apple.quarantine ~/Downloads/vChewingInstaller.app
### 威注音 2.7.0 版好像改很兇,但又幾乎沒有新功能。究竟改了哪些內容? ### 威注音 2.7.0 版好像改很兇,但又幾乎沒有新功能。究竟改了哪些內容?
威注音 2.7.0 是威注音的 Dezonblization 行動的一部分,旨在讓在此之後的研發流程更能順利進行。藉由將整個專案大卸八塊、拆成各個以 Swift Package 為單位的各種組件以及對大中心派發技術Grand Central Dispatch的合理運用威注音得以做到更快的專案建置速度、更快的辭典載入速度、更清晰且更易於維護的專案結構框架。至於放棄 macOS 10.11-10.12 的支援,則是因為 NSGridView 以及 Xcode 14 的雙雙限制使然。藉由這些改動,威注音今後在理論上就可以引入對 KeyHandler 等元件的更有效的單元測試。 威注音 2.7.0 是威注音的 Dezonblization 行動的一部分,旨在讓在此之後的研發流程更能順利進行。藉由將整個專案大卸八塊、拆成各個以 Swift Package 為單位的各種組件以及對大中心派發技術Grand Central Dispatch的合理運用威注音得以做到更快的專案建置速度、更快的辭典載入速度、更清晰且更易於維護的專案結構框架。至於放棄 macOS 10.11-10.12 的支援,則是因為 NSGridView 以及 Xcode 14 的雙雙限制使然。藉由這些改動,威注音今後在理論上就可以引入對 InputHandler 等元件的更有效的單元測試。
$ EOF. $ EOF.

View File

@ -106,7 +106,7 @@ extension NSEvent {
// //
public var mainAreaNumKeyChar: String? { mapMainAreaNumKey[keyCode] } public var mainAreaNumKeyChar: String? { mapMainAreaNumKey[keyCode] }
// ANSI charCode Swift KeyHandler // ANSI charCode InputHandler
public var isInvalid: Bool { public var isInvalid: Bool {
(0x20...0xFF).contains(charCode) ? false : !(isReservedKey && !isKeyCodeBlacklisted) (0x20...0xFF).contains(charCode) ? false : !(isReservedKey && !isKeyCodeBlacklisted)
} }

View File

@ -13,11 +13,11 @@ Megrez Engine is a module made for processing lingual data of an input method. T
### §1. 初期化 ### §1. 初期化
在你的 IMKInputController 或者 KeyHandler 內初期化一份 Megrez.Compositor 組字器副本(這裡將該副本命名為「`compositor`」)。由於 Megrez.Compositor 的型別是 Struct 型別(為了讓 Compositor 可以 deep copy所以其副本可以用 var 來宣告。 在你的 IMKInputController 或者 InputHandler 內初期化一份 Megrez.Compositor 組字器副本(這裡將該副本命名為「`compositor`」)。由於 Megrez.Compositor 的型別是 Struct 型別(為了讓 Compositor 可以 deep copy所以其副本可以用 var 來宣告。
KeyHandler 為例: InputHandler 為例:
```swift ```swift
class KeyHandler { class InputHandler {
// 先設定好變數 // 先設定好變數
var compositor: Megrez.Compositor = .init() var compositor: Megrez.Compositor = .init()
... ...
@ -34,7 +34,7 @@ class IMKMyInputController: IMKInputController {
} }
``` ```
由於 Swift 會在某個大副本(KeyHandler 或者 IMKInputController 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Megrez.Compositor 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所對接的語言模組型別、以及其可以允許的最大詞長。 由於 Swift 會在某個大副本(InputHandler 或者 IMKInputController 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Megrez.Compositor 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所對接的語言模組型別、以及其可以允許的最大詞長。
這裡就需要在 init() 時使用參數: 這裡就需要在 init() 時使用參數:
```swift ```swift

View File

@ -11,7 +11,7 @@ import Cocoa
// IMEState // IMEState
public protocol IMEStateProtocol { public protocol IMEStateProtocol {
var type: StateType { get } var type: StateType { get }
var data: StateDataProtocol { get } var data: IMEStateDataProtocol { get }
var isASCIIMode: Bool { get set } var isASCIIMode: Bool { get set }
var isVerticalTyping: Bool { get set } var isVerticalTyping: Bool { get set }
var isVerticalCandidateWindow: Bool { get set } var isVerticalCandidateWindow: Bool { get set }
@ -36,7 +36,7 @@ public protocol IMEStateProtocol {
var marker: Int { get set } var marker: Int { get set }
} }
public protocol StateDataProtocol { public protocol IMEStateDataProtocol {
var cursor: Int { get set } var cursor: Int { get set }
var marker: Int { get set } var marker: Int { get set }
var markedRange: Range<Int> { get } var markedRange: Range<Int> { get }

View File

@ -23,11 +23,11 @@ Regarding pinyin input support, we only support: Hanyu Pinyin, Secondary Pinyin,
### §1. 初期化 ### §1. 初期化
在你的 IMKInputController (InputMethodController) 或者 KeyHandler 內初期化一份 Tekkon.Composer 注拼槽副本(這裡將該副本命名為「`_composer`」)。由於 Tekkon.Composer 的型別是 Struct 型別所以其副本必須為變數var否則無法自我 mutate。 在你的 IMKInputController (InputMethodController) 或者 InputHandler 內初期化一份 Tekkon.Composer 注拼槽副本(這裡將該副本命名為「`_composer`」)。由於 Tekkon.Composer 的型別是 Struct 型別所以其副本必須為變數var否則無法自我 mutate。
KeyHandler 為例: InputHandler 為例:
```swift ```swift
class KeyHandler: NSObject { class InputHandler: NSObject {
// 先設定好變數 // 先設定好變數
var _composer: Tekkon.Composer = .init() var _composer: Tekkon.Composer = .init()
... ...
@ -45,7 +45,7 @@ class IMKMyInputController: IMKInputController {
``` ```
由於 Swift 會在某個大副本(KeyHandler 或者 IMKInputController 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Tekkon.Composer 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所使用的注音排列(是大千?還是倚天傳統?還是神通?等)。 由於 Swift 會在某個大副本(InputHandler 或者 IMKInputController 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Tekkon.Composer 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所使用的注音排列(是大千?還是倚天傳統?還是神通?等)。
這裡就需要在 _composer 這個副本所在的型別當中額外寫一個過程函式。 這裡就需要在 _composer 這個副本所在的型別當中額外寫一個過程函式。
@ -159,7 +159,7 @@ final class TekkonTests: XCTestCase {
#### // 2. 訊號處理 #### // 2. 訊號處理
無論是 KeyHandler 還是 IMKInputController 都得要處理被傳入的 NSEvent 當中的 charCode 訊號。 無論是 InputHandler 還是 IMKInputController 都得要處理被傳入的 NSEvent 當中的 charCode 訊號。
比如 IMKInputController 內: 比如 IMKInputController 內:
```swift ```swift
@ -168,9 +168,9 @@ func handleInputText(_ inputText: String?, key keyCode: Int, modifiers flags: In
} }
``` ```
或者 KeyHandler 內: 或者 InputHandler 內:
```swift ```swift
extension KeyHandler { extension InputHandler {
func handle( func handle(
input: InputHandler, input: InputHandler,
state: InputState, state: InputState,
@ -184,7 +184,7 @@ extension KeyHandler {
但對注拼槽的處理都是一樣的。 但對注拼槽的處理都是一樣的。
這裡分享一下小麥注音輸入法與威注音輸入法在 KeyHandler 內對 _composer 的用法。 這裡分享一下威注音輸入法在 InputHandler 內對 _composer 的用法。
如果收到的按鍵訊號是 BackSpace 的話,可以用 _composer.doBackSpace() 來移除注拼槽內最前方的元素。 如果收到的按鍵訊號是 BackSpace 的話,可以用 _composer.doBackSpace() 來移除注拼槽內最前方的元素。
@ -194,8 +194,6 @@ extension KeyHandler {
> (這裡的範例取自威注音,只用作演示用途。威注音實際的 codebase 可能會有出入。請留意這一段內的漢語註解。) > (這裡的範例取自威注音,只用作演示用途。威注音實際的 codebase 可能會有出入。請留意這一段內的漢語註解。)
> >
> (小麥注音 2.2 沒在用鐵恨引擎,而是在用 OVMandarin 引擎與 Objective-Cpp所以語法會有一些出入。)
>
> (不是所有輸入法都有狀態管理引擎,請根據各自專案的實際情況來結合理解這段程式碼。) > (不是所有輸入法都有狀態管理引擎,請根據各自專案的實際情況來結合理解這段程式碼。)
```swift ```swift
@ -219,7 +217,7 @@ if !skipPhoneticHandling && _composer.inputValidityCheck(key: charCode) {
// 有調號的話,則不需要這樣處理,轉而繼續在此之後的處理。 // 有調號的話,則不需要這樣處理,轉而繼續在此之後的處理。
let composeReading = _composer.hasToneMarker() let composeReading = _composer.hasToneMarker()
if !composeReading { if !composeReading {
stateCallback(buildInputtingState()) stateCallback(generateStateOfInputting())
return true return true
} }
} }
@ -236,7 +234,7 @@ composeReading = composeReading || (!_composer.isEmpty && (input.isSpace || inpu
if composeReading { // 符合按鍵組合條件 if composeReading { // 符合按鍵組合條件
if input.isSpace && !_composer.hasToneMarker() { if input.isSpace && !_composer.hasToneMarker() {
_composer.receiveKey(fromString: " ") // 補上空格,否則倚天忘形與許氏排列某些音無法響應不了陰平聲調。 _composer.receiveKey(fromString: " ") // 補上空格,否則倚天忘形與許氏排列某些音無法響應不了陰平聲調。
// 小麥注音因為使用 OVMandarin 而不是鐵恨引擎,所以不需要這樣補。但鐵恨引擎對所有聲調一視同仁。 // 某些輸入法使用 OVMandarin 而不是鐵恨引擎,所以不需要這樣補。但鐵恨引擎對所有聲調一視同仁。
} }
let reading = _composer.getComposition() // 拿取用來進行索引檢索用的注音 let reading = _composer.getComposition() // 拿取用來進行索引檢索用的注音
// 如果輸入法的辭典索引是漢語拼音的話,要注意上一行拿到的內容得是漢語拼音。 // 如果輸入法的辭典索引是漢語拼音的話,要注意上一行拿到的內容得是漢語拼音。
@ -249,7 +247,7 @@ if composeReading { // 符合按鍵組合條件
_composer.clear() // 清空注拼槽的內容 _composer.clear() // 清空注拼槽的內容
// 根據「天權星引擎 (威注音) 或 Gramambular (小麥) 的組字器是否為空」來判定回呼哪一種狀態 // 根據「天權星引擎 (威注音) 或 Gramambular (小麥) 的組字器是否為空」來判定回呼哪一種狀態
stateCallback( stateCallback(
(getCompositorLength() == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState()) (getCompositorLength() == 0) ? InputState.EmptyIgnoringPreviousState() : generateStateOfInputting())
return true // 向 IMK 報告說這個按鍵訊號已經被輸入法攔截處理了 return true // 向 IMK 報告說這個按鍵訊號已經被輸入法攔截處理了
} }
@ -269,7 +267,7 @@ if composeReading { // 符合按鍵組合條件
// 之後就是更新組字區了。先清空注拼槽的內容。 // 之後就是更新組字區了。先清空注拼槽的內容。
_composer.clear() _composer.clear()
// 再以回呼組字狀態的方式來執行updateClientComposingBuffer() // 再以回呼組字狀態的方式來執行updateClientComposingBuffer()
let inputting = buildInputtingState() let inputting = generateStateOfInputting()
inputting.poppedText = poppedText inputting.poppedText = poppedText
stateCallback(inputting) stateCallback(inputting)

View File

@ -42,17 +42,20 @@ import Shared
/// - .SymbolTable: /// - .SymbolTable:
public struct IMEState: IMEStateProtocol { public struct IMEState: IMEStateProtocol {
public var type: StateType = .ofEmpty public var type: StateType = .ofEmpty
public var data: StateDataProtocol = StateData() as StateDataProtocol public var data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol
public var node: CandidateNode = .init(name: "") public var node: CandidateNode = .init(name: "")
public var isASCIIMode = false public var isASCIIMode = false
public var isVerticalCandidateWindow = false public var isVerticalCandidateWindow = false
init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty) { init(_ data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol, type: StateType = .ofEmpty) {
self.data = data self.data = data
self.type = type self.type = type
isVerticalTyping = SessionCtl.isVerticalTyping isVerticalTyping = SessionCtl.isVerticalTyping
} }
init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty, node: CandidateNode) { init(
_ data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol, type: StateType = .ofEmpty,
node: CandidateNode
) {
self.data = data self.data = data
self.type = type self.type = type
self.node = node self.node = node

View File

@ -10,7 +10,7 @@ import Shared
import Tekkon import Tekkon
import TooltipUI import TooltipUI
public struct StateData: StateDataProtocol { public struct IMEStateData: IMEStateDataProtocol {
private static var minCandidateLength: Int { private static var minCandidateLength: Int {
PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2 PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2
} }
@ -161,7 +161,7 @@ public struct StateData: StateDataProtocol {
// MARK: - IMEState // MARK: - IMEState
extension StateData { extension IMEStateData {
public var doesUserPhraseExist: Bool { public var doesUserPhraseExist: Bool {
let text = displayedText.charComponents[markedRange].joined() let text = displayedText.charComponents[markedRange].joined()
let joined = markedReadings.joined(separator: "-") let joined = markedReadings.joined(separator: "-")
@ -229,19 +229,19 @@ extension StateData {
let text = pair.1 let text = pair.1
let readingDisplay = readingThreadForDisplay let readingDisplay = readingThreadForDisplay
if markedRange.count < StateData.allowedMarkLengthRange.lowerBound { if markedRange.count < IMEStateData.allowedMarkLengthRange.lowerBound {
tooltipColorState = .denialInsufficiency tooltipColorState = .denialInsufficiency
return String( return String(
format: NSLocalizedString( format: NSLocalizedString(
"\"%@\" length must ≥ 2 for a user phrase.", comment: "" "\"%@\" length must ≥ 2 for a user phrase.", comment: ""
) + "\n" + readingDisplay, text ) + "\n" + readingDisplay, text
) )
} else if markedRange.count > StateData.allowedMarkLengthRange.upperBound { } else if markedRange.count > IMEStateData.allowedMarkLengthRange.upperBound {
tooltipColorState = .denialOverflow tooltipColorState = .denialOverflow
return String( return String(
format: NSLocalizedString( format: NSLocalizedString(
"\"%@\" length should ≤ %d for a user phrase.", comment: "" "\"%@\" length should ≤ %d for a user phrase.", comment: ""
) + "\n" + readingDisplay, text, StateData.allowedMarkLengthRange.upperBound ) + "\n" + readingDisplay, text, IMEStateData.allowedMarkLengthRange.upperBound
) )
} }

View File

@ -17,22 +17,22 @@ import Tekkon
// MARK: - (Delegate). // MARK: - (Delegate).
/// KeyHandler /// InputHandler
public protocol KeyHandlerDelegate { public protocol InputHandlerDelegate {
var selectionKeys: String { get } var selectionKeys: String { get }
var clientBundleIdentifier: String { get } var clientBundleIdentifier: String { get }
func candidateController() -> CtlCandidateProtocol func candidateController() -> CtlCandidateProtocol
func candidateSelectionCalledByKeyHandler(at index: Int) func candidateSelectionCalledByInputHandler(at index: Int)
func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool) func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool)
-> Bool -> Bool
} }
// MARK: - (Kernel). // MARK: - (Kernel).
/// KeyHandler 調 /// InputHandler 調
public class KeyHandler { public class InputHandler {
/// (SessionCtl)便 /// (SessionCtl)便
public var delegate: KeyHandlerDelegate? public var delegate: InputHandlerDelegate?
public var prefs: PrefMgrProtocol public var prefs: PrefMgrProtocol
/// ///
@ -74,7 +74,7 @@ public class KeyHandler {
min(compositor.cursor, compositor.marker)..<max(compositor.cursor, compositor.marker) min(compositor.cursor, compositor.marker)..<max(compositor.cursor, compositor.marker)
} }
/// ///
func isCursorCuttingChar(isMarker: Bool = false) -> Bool { func isCursorCuttingChar(isMarker: Bool = false) -> Bool {
let index = isMarker ? compositor.marker : compositor.cursor let index = isMarker ? compositor.marker : compositor.cursor
var isBound = (index == compositor.walkedNodes.contextRange(ofGivenCursor: index).lowerBound) var isBound = (index == compositor.walkedNodes.contextRange(ofGivenCursor: index).lowerBound)
@ -86,7 +86,7 @@ public class KeyHandler {
/// Megrez 使便 /// Megrez 使便
/// ///
/// 使 Node Crossing /// 使 Node Crossing
var actualCandidateCursor: Int { var cursorForCandidate: Int {
compositor.cursor compositor.cursor
- ((compositor.cursor == compositor.width || !prefs.useRearCursorMode) && compositor.cursor > 0 ? 1 : 0) - ((compositor.cursor == compositor.width || !prefs.useRearCursorMode) && compositor.cursor > 0 ? 1 : 0)
} }
@ -116,7 +116,7 @@ public class KeyHandler {
/// - Parameter key: /// - Parameter key:
/// - Returns: /// - Returns:
/// nil /// nil
func buildAssociatePhraseArray(withPair pair: Megrez.Compositor.KeyValuePaired) -> [(String, String)] { func generateArrayOfAssociates(withPair pair: Megrez.Compositor.KeyValuePaired) -> [(String, String)] {
var arrResult: [(String, String)] = [] var arrResult: [(String, String)] = []
if currentLM.hasAssociatedPhrasesFor(pair: pair) { if currentLM.hasAssociatedPhrasesFor(pair: pair) {
arrResult = currentLM.associatedPhrasesFor(pair: pair).map { ("", $0) } arrResult = currentLM.associatedPhrasesFor(pair: pair).map { ("", $0) }
@ -140,18 +140,18 @@ public class KeyHandler {
/// - Parameter theCandidate: /// - Parameter theCandidate:
func consolidateCursorContext(with theCandidate: Megrez.Compositor.KeyValuePaired) { func consolidateCursorContext(with theCandidate: Megrez.Compositor.KeyValuePaired) {
var grid = compositor var grid = compositor
var frontBoundaryEX = actualCandidateCursor + 1 var frontBoundaryEX = cursorForCandidate + 1
var rearBoundaryEX = actualCandidateCursor var rearBoundaryEX = cursorForCandidate
var debugIntelToPrint = "" var debugIntelToPrint = ""
if grid.overrideCandidate(theCandidate, at: actualCandidateCursor) { if grid.overrideCandidate(theCandidate, at: cursorForCandidate) {
grid.walk() grid.walk()
let range = grid.walkedNodes.contextRange(ofGivenCursor: actualCandidateCursor) let range = grid.walkedNodes.contextRange(ofGivenCursor: cursorForCandidate)
rearBoundaryEX = range.lowerBound rearBoundaryEX = range.lowerBound
frontBoundaryEX = range.upperBound frontBoundaryEX = range.upperBound
debugIntelToPrint.append("EX: \(rearBoundaryEX)..<\(frontBoundaryEX), ") debugIntelToPrint.append("EX: \(rearBoundaryEX)..<\(frontBoundaryEX), ")
} }
let range = compositor.walkedNodes.contextRange(ofGivenCursor: actualCandidateCursor) let range = compositor.walkedNodes.contextRange(ofGivenCursor: cursorForCandidate)
var rearBoundary = min(range.lowerBound, rearBoundaryEX) var rearBoundary = min(range.lowerBound, rearBoundaryEX)
var frontBoundary = max(range.upperBound, frontBoundaryEX) var frontBoundary = max(range.upperBound, frontBoundaryEX)
@ -207,14 +207,14 @@ public class KeyHandler {
/// - value: /// - value:
/// - respectCursorPushing: true /// - respectCursorPushing: true
/// - consolidate: /// - consolidate:
func fixNode(candidate: (String, String), respectCursorPushing: Bool = true, preConsolidate: Bool = false) { func consolidateNode(candidate: (String, String), respectCursorPushing: Bool = true, preConsolidate: Bool = false) {
let theCandidate: Megrez.Compositor.KeyValuePaired = .init(key: candidate.0, value: candidate.1) let theCandidate: Megrez.Compositor.KeyValuePaired = .init(key: candidate.0, value: candidate.1)
/// ///
if preConsolidate { consolidateCursorContext(with: theCandidate) } if preConsolidate { consolidateCursorContext(with: theCandidate) }
// //
if !compositor.overrideCandidate(theCandidate, at: actualCandidateCursor) { return } if !compositor.overrideCandidate(theCandidate, at: cursorForCandidate) { return }
let previousWalk = compositor.walkedNodes let previousWalk = compositor.walkedNodes
// //
walk() walk()
@ -222,7 +222,7 @@ public class KeyHandler {
// 使 // 使
var accumulatedCursor = 0 var accumulatedCursor = 0
let currentNode = currentWalk.findNode(at: actualCandidateCursor, target: &accumulatedCursor) let currentNode = currentWalk.findNode(at: cursorForCandidate, target: &accumulatedCursor)
guard let currentNode = currentNode else { return } guard let currentNode = currentNode else { return }
if currentNode.currentUnigram.score > -12, prefs.fetchSuggestionsFromUserOverrideModel { if currentNode.currentUnigram.score > -12, prefs.fetchSuggestionsFromUserOverrideModel {
@ -234,7 +234,7 @@ public class KeyHandler {
// //
// //
currentUOM.performObservation( currentUOM.performObservation(
walkedBefore: previousWalk, walkedAfter: currentWalk, cursor: actualCandidateCursor, walkedBefore: previousWalk, walkedAfter: currentWalk, cursor: cursorForCandidate,
timestamp: Date().timeIntervalSince1970, saveCallback: { self.currentUOM.saveData() } timestamp: Date().timeIntervalSince1970, saveCallback: { self.currentUOM.saveData() }
) )
// //
@ -249,15 +249,15 @@ public class KeyHandler {
} }
/// ///
func getCandidatesArray(fixOrder: Bool = true) -> [(String, String)] { func generateArrayOfCandidates(fixOrder: Bool = true) -> [(String, String)] {
/// 使 nodesCrossing macOS /// 使 nodesCrossing macOS
/// nodeCrossing /// nodeCrossing
var arrCandidates: [Megrez.Compositor.KeyValuePaired] = { var arrCandidates: [Megrez.Compositor.KeyValuePaired] = {
switch prefs.useRearCursorMode { switch prefs.useRearCursorMode {
case false: case false:
return compositor.fetchCandidates(at: actualCandidateCursor, filter: .endAt) return compositor.fetchCandidates(at: cursorForCandidate, filter: .endAt)
case true: case true:
return compositor.fetchCandidates(at: actualCandidateCursor, filter: .beginAt) return compositor.fetchCandidates(at: cursorForCandidate, filter: .beginAt)
} }
}() }()
@ -271,7 +271,7 @@ public class KeyHandler {
return arrCandidates.map { ($0.key, $0.value) } return arrCandidates.map { ($0.key, $0.value) }
} }
let arrSuggestedUnigrams: [(String, Megrez.Unigram)] = fetchSuggestionsFromUOM(apply: false) let arrSuggestedUnigrams: [(String, Megrez.Unigram)] = retrieveUOMSuggestions(apply: false)
let arrSuggestedCandidates: [Megrez.Compositor.KeyValuePaired] = arrSuggestedUnigrams.map { let arrSuggestedCandidates: [Megrez.Compositor.KeyValuePaired] = arrSuggestedUnigrams.map {
Megrez.Compositor.KeyValuePaired(key: $0.0, value: $0.1.value) Megrez.Compositor.KeyValuePaired(key: $0.0, value: $0.1.value)
} }
@ -282,7 +282,7 @@ public class KeyHandler {
} }
/// ///
@discardableResult func fetchSuggestionsFromUOM(apply: Bool) -> [(String, Megrez.Unigram)] { @discardableResult func retrieveUOMSuggestions(apply: Bool) -> [(String, Megrez.Unigram)] {
var arrResult = [(String, Megrez.Unigram)]() var arrResult = [(String, Megrez.Unigram)]()
/// ///
if prefs.useSCPCTypingMode { return arrResult } if prefs.useSCPCTypingMode { return arrResult }
@ -290,7 +290,7 @@ public class KeyHandler {
if !prefs.fetchSuggestionsFromUserOverrideModel { return arrResult } if !prefs.fetchSuggestionsFromUserOverrideModel { return arrResult }
/// ///
let suggestion = currentUOM.fetchSuggestion( let suggestion = currentUOM.fetchSuggestion(
currentWalk: compositor.walkedNodes, cursor: actualCandidateCursor, timestamp: Date().timeIntervalSince1970 currentWalk: compositor.walkedNodes, cursor: cursorForCandidate, timestamp: Date().timeIntervalSince1970
) )
arrResult.append(contentsOf: suggestion.candidates) arrResult.append(contentsOf: suggestion.candidates)
if apply { if apply {
@ -303,9 +303,9 @@ public class KeyHandler {
) )
vCLog( vCLog(
"UOM: Suggestion retrieved, overriding the node score of the selected candidate: \(suggestedPair.toNGramKey)") "UOM: Suggestion retrieved, overriding the node score of the selected candidate: \(suggestedPair.toNGramKey)")
if !compositor.overrideCandidate(suggestedPair, at: actualCandidateCursor, overrideType: overrideBehavior) { if !compositor.overrideCandidate(suggestedPair, at: cursorForCandidate, overrideType: overrideBehavior) {
compositor.overrideCandidateLiteral( compositor.overrideCandidateLiteral(
newestSuggestedCandidate.1.value, at: actualCandidateCursor, overrideType: overrideBehavior newestSuggestedCandidate.1.value, at: cursorForCandidate, overrideType: overrideBehavior
) )
} }
walk() walk()
@ -415,7 +415,7 @@ public class KeyHandler {
/// - Remark: IMKTextInput PrefMgr /// - Remark: IMKTextInput PrefMgr
private let compositorWidthLimit = 20 private let compositorWidthLimit = 20
extension KeyHandler { extension InputHandler {
/// ///
/// ///
/// ///

View File

@ -13,7 +13,7 @@ import Shared
// MARK: - § 調 (Handle Candidate State). // MARK: - § 調 (Handle Candidate State).
extension KeyHandler { extension InputHandler {
/// ///
/// - Parameters: /// - Parameters:
/// - input: /// - input:
@ -49,7 +49,7 @@ extension KeyHandler {
// compositor.isEmpty // compositor.isEmpty
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
} else { } else {
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} }
if state.type == .ofSymbolTable, let nodePrevious = state.node.previous, !nodePrevious.members.isEmpty { if state.type == .ofSymbolTable, let nodePrevious = state.node.previous, !nodePrevious.members.isEmpty {
stateCallback(IMEState.ofSymbolTable(node: nodePrevious)) stateCallback(IMEState.ofSymbolTable(node: nodePrevious))
@ -64,7 +64,7 @@ extension KeyHandler {
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
return true return true
} }
delegate?.candidateSelectionCalledByKeyHandler(at: ctlCandidate.selectedCandidateIndex) delegate?.candidateSelectionCalledByInputHandler(at: ctlCandidate.selectedCandidateIndex)
return true return true
} }
@ -245,7 +245,7 @@ extension KeyHandler {
if index != NSNotFound { if index != NSNotFound {
let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(index) let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(index)
if candidateIndex != -114_514 { if candidateIndex != -114_514 {
delegate?.candidateSelectionCalledByKeyHandler(at: candidateIndex) delegate?.candidateSelectionCalledByInputHandler(at: candidateIndex)
return true return true
} }
} }
@ -285,10 +285,10 @@ extension KeyHandler {
if shouldAutoSelectCandidate { if shouldAutoSelectCandidate {
let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(0) let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(0)
if candidateIndex != -114_514 { if candidateIndex != -114_514 {
delegate?.candidateSelectionCalledByKeyHandler(at: candidateIndex) delegate?.candidateSelectionCalledByInputHandler(at: candidateIndex)
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
return handle( return handleInput(
input: input, state: IMEState.ofEmpty(), stateCallback: stateCallback, errorCallback: errorCallback event: input, state: IMEState.ofEmpty(), stateCallback: stateCallback, errorCallback: errorCallback
) )
} }
return true return true

View File

@ -6,13 +6,13 @@
// marks, or product names of Contributor, except as required to fulfill notice // marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License. // requirements defined in MIT License.
/// KeyHandler.HandleInput() /// InputHandler.HandleInput()
import Shared import Shared
import Tekkon import Tekkon
extension KeyHandler { extension InputHandler {
/// KeyHandler.HandleInput() /// InputHandler.HandleInput()
/// - Parameters: /// - Parameters:
/// - input: /// - input:
/// - stateCallback: /// - stateCallback:
@ -52,7 +52,7 @@ extension KeyHandler {
compositor.dropKey(direction: .rear) compositor.dropKey(direction: .rear)
walk() // Walk walk walk() // Walk walk
composer = theComposer composer = theComposer
// buildInputtingState調 buildInputtingState // generateStateOfInputting()調 generateStateOfInputting()
} else { } else {
errorCallback("4B0DD2D4語彙庫內無「\(temporaryReadingKey)」的匹配記錄,放棄覆寫游標身後的內容。") errorCallback("4B0DD2D4語彙庫內無「\(temporaryReadingKey)」的匹配記錄,放棄覆寫游標身後的內容。")
return true return true
@ -65,7 +65,7 @@ extension KeyHandler {
// 調 setInlineDisplayWithCursor() return true // 調 setInlineDisplayWithCursor() return true
// 調 // 調
if !composer.hasToneMarker() { if !composer.hasToneMarker() {
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
} }
@ -90,14 +90,14 @@ extension KeyHandler {
if prefs.keepReadingUponCompositionError { if prefs.keepReadingUponCompositionError {
composer.intonation.clear() // 調 composer.intonation.clear() // 調
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
composer.clear() composer.clear()
// //
switch compositor.isEmpty { switch compositor.isEmpty {
case false: stateCallback(buildInputtingState) case false: stateCallback(generateStateOfInputting())
case true: case true:
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
} }
@ -114,19 +114,19 @@ extension KeyHandler {
let textToCommit = commitOverflownComposition let textToCommit = commitOverflownComposition
// //
fetchSuggestionsFromUOM(apply: true) retrieveUOMSuggestions(apply: true)
// //
composer.clear() composer.clear()
// setInlineDisplayWithCursor() // setInlineDisplayWithCursor()
var inputting = buildInputtingState var inputting = generateStateOfInputting()
inputting.textToCommit = textToCommit inputting.textToCommit = textToCommit
stateCallback(inputting) stateCallback(inputting)
/// ///
if prefs.useSCPCTypingMode { if prefs.useSCPCTypingMode {
let candidateState: IMEStateProtocol = buildCandidate(state: inputting) let candidateState: IMEStateProtocol = generateStateOfCandidates(state: inputting)
switch candidateState.candidates.count { switch candidateState.candidates.count {
case 2...: stateCallback(candidateState) case 2...: stateCallback(candidateState)
case 1: case 1:
@ -139,7 +139,7 @@ extension KeyHandler {
stateCallback(IMEState.ofEmpty()) stateCallback(IMEState.ofEmpty())
} else { } else {
let associatedPhrases = let associatedPhrases =
buildAssociatePhraseState( generateStateOfAssociates(
withPair: .init(key: reading, value: text) withPair: .init(key: reading, value: text)
) )
stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases) stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases)
@ -154,7 +154,7 @@ extension KeyHandler {
/// 調 /// 調
if keyConsumedByReading { if keyConsumedByReading {
// setInlineDisplayWithCursor() // setInlineDisplayWithCursor()
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
return nil return nil

View File

@ -14,7 +14,7 @@ import Shared
// MARK: - § 調 (Handle Input with States) // MARK: - § 調 (Handle Input with States)
extension KeyHandler { extension InputHandler {
/// ///
/// - Parameters: /// - Parameters:
/// - input: /// - input:
@ -22,8 +22,8 @@ extension KeyHandler {
/// - stateCallback: /// - stateCallback:
/// - errorCallback: /// - errorCallback:
/// - Returns: IMK /// - Returns: IMK
func handle( func handleInput(
input: InputSignalProtocol, event input: InputSignalProtocol,
state: IMEStateProtocol, state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void, stateCallback: @escaping (IMEStateProtocol) -> Void,
errorCallback: @escaping (String) -> Void errorCallback: @escaping (String) -> Void
@ -41,7 +41,7 @@ extension KeyHandler {
if state.type == .ofEmpty || state.type == .ofDeactivated { if state.type == .ofEmpty || state.type == .ofDeactivated {
return false return false
} }
errorCallback("550BCF7B: KeyHandler just refused an invalid input.") errorCallback("550BCF7B: InputHandler just refused an invalid input.")
stateCallback(state) stateCallback(state)
return true return true
} }
@ -164,7 +164,7 @@ extension KeyHandler {
walk() walk()
// App // App
let textToCommit = commitOverflownComposition let textToCommit = commitOverflownComposition
var inputting = buildInputtingState var inputting = generateStateOfInputting()
inputting.textToCommit = textToCommit inputting.textToCommit = textToCommit
stateCallback(inputting) stateCallback(inputting)
} }
@ -176,7 +176,7 @@ extension KeyHandler {
) )
} }
} }
let candidateState: IMEStateProtocol = buildCandidate(state: state) let candidateState: IMEStateProtocol = generateStateOfCandidates(state: state)
if candidateState.candidates.isEmpty { if candidateState.candidates.isEmpty {
errorCallback("3572F238") errorCallback("3572F238")
} else { } else {
@ -291,10 +291,10 @@ extension KeyHandler {
walk() walk()
// App // App
let textToCommit = commitOverflownComposition let textToCommit = commitOverflownComposition
var inputting = buildInputtingState var inputting = generateStateOfInputting()
inputting.textToCommit = textToCommit inputting.textToCommit = textToCommit
stateCallback(inputting) stateCallback(inputting)
let candidateState = buildCandidate(state: inputting) let candidateState = generateStateOfCandidates(state: inputting)
if candidateState.candidates.isEmpty { if candidateState.candidates.isEmpty {
errorCallback("B5127D8A") errorCallback("B5127D8A")
} else { } else {

View File

@ -14,11 +14,11 @@ import Tekkon
// MARK: - § 調 (Functions Interact With States). // MARK: - § 調 (Functions Interact With States).
extension KeyHandler { extension InputHandler {
// MARK: - State Building // MARK: - State Building
/// ///
public var buildInputtingState: IMEStateProtocol { public func generateStateOfInputting() -> IMEStateProtocol {
/// (Update the composing buffer) /// (Update the composing buffer)
/// NSAttributeString /// NSAttributeString
var displayTextSegments: [String] = compositor.walkedNodes.values var displayTextSegments: [String] = compositor.walkedNodes.values
@ -86,11 +86,11 @@ extension KeyHandler {
/// - Parameters: /// - Parameters:
/// - currentState: /// - currentState:
/// - Returns: /// - Returns:
func buildCandidate( func generateStateOfCandidates(
state currentState: IMEStateProtocol state currentState: IMEStateProtocol
) -> IMEStateProtocol { ) -> IMEStateProtocol {
IMEState.ofCandidates( IMEState.ofCandidates(
candidates: getCandidatesArray(fixOrder: prefs.useFixecCandidateOrderOnSelection), candidates: generateArrayOfCandidates(fixOrder: prefs.useFixecCandidateOrderOnSelection),
displayTextSegments: compositor.walkedNodes.values, displayTextSegments: compositor.walkedNodes.values,
cursor: currentState.cursor cursor: currentState.cursor
) )
@ -100,9 +100,9 @@ extension KeyHandler {
/// ///
/// ///
/// buildAssociatePhraseStateWithKey /// generateStateOfAssociates
/// 使 /// 使
/// Core buildAssociatePhraseArray /// Core generateArrayOfAssociates
/// String Swift /// String Swift
/// nil /// nil
/// ///
@ -110,11 +110,11 @@ extension KeyHandler {
/// - Parameters: /// - Parameters:
/// - key: /// - key:
/// - Returns: /// - Returns:
func buildAssociatePhraseState( func generateStateOfAssociates(
withPair pair: Megrez.Compositor.KeyValuePaired withPair pair: Megrez.Compositor.KeyValuePaired
) -> IMEStateProtocol { ) -> IMEStateProtocol {
IMEState.ofAssociates( IMEState.ofAssociates(
candidates: buildAssociatePhraseArray(withPair: pair)) candidates: generateArrayOfAssociates(withPair: pair))
} }
// MARK: - // MARK: -
@ -133,7 +133,7 @@ extension KeyHandler {
errorCallback: @escaping (String) -> Void errorCallback: @escaping (String) -> Void
) -> Bool { ) -> Bool {
if input.isEsc { if input.isEsc {
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
@ -145,7 +145,7 @@ extension KeyHandler {
// Enter // Enter
if input.isEnter { if input.isEnter {
if let ctlIME = delegate { if let sessionCtl = delegate {
// //
if input.isShiftHold, input.isCommandHold, !state.isFilterable { if input.isShiftHold, input.isCommandHold, !state.isFilterable {
errorCallback("2EAC1F7A") errorCallback("2EAC1F7A")
@ -155,28 +155,28 @@ extension KeyHandler {
errorCallback("9AAFAC00") errorCallback("9AAFAC00")
return true return true
} }
if !ctlIME.performUserPhraseOperation(with: state, addToFilter: false) { if !sessionCtl.performUserPhraseOperation(with: state, addToFilter: false) {
errorCallback("5B69CC8D") errorCallback("5B69CC8D")
return true return true
} }
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
// BackSpace & Delete // BackSpace & Delete
if input.isBackSpace || input.isDelete { if input.isBackSpace || input.isDelete {
if let keyHandlerDelegate = delegate { if let inputHandlerDelegate = delegate {
if !state.isFilterable { if !state.isFilterable {
errorCallback("1F88B191") errorCallback("1F88B191")
return true return true
} }
if !keyHandlerDelegate.performUserPhraseOperation(with: state, addToFilter: true) { if !inputHandlerDelegate.performUserPhraseOperation(with: state, addToFilter: true) {
errorCallback("68D3C6C8") errorCallback("68D3C6C8")
return true return true
} }
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
@ -255,14 +255,14 @@ extension KeyHandler {
walk() walk()
// App // App
let textToCommit = commitOverflownComposition let textToCommit = commitOverflownComposition
var inputting = buildInputtingState var inputting = generateStateOfInputting()
inputting.textToCommit = textToCommit inputting.textToCommit = textToCommit
stateCallback(inputting) stateCallback(inputting)
// //
guard prefs.useSCPCTypingMode, composer.isEmpty else { return true } guard prefs.useSCPCTypingMode, composer.isEmpty else { return true }
let candidateState = buildCandidate(state: inputting) let candidateState = generateStateOfCandidates(state: inputting)
switch candidateState.candidates.count { switch candidateState.candidates.count {
case 2...: stateCallback(candidateState) case 2...: stateCallback(candidateState)
case 1: case 1:
@ -386,7 +386,7 @@ extension KeyHandler {
compositor.dropKey(direction: .rear) compositor.dropKey(direction: .rear)
walk() // Walk walk walk() // Walk walk
prevReading.1.charComponents.forEach { composer.receiveKey(fromPhonabet: $0) } prevReading.1.charComponents.forEach { composer.receiveKey(fromPhonabet: $0) }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
case 1: case 1:
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
@ -415,7 +415,7 @@ extension KeyHandler {
} }
switch composer.isEmpty && compositor.isEmpty { switch composer.isEmpty && compositor.isEmpty {
case false: stateCallback(buildInputtingState) case false: stateCallback(generateStateOfInputting())
case true: case true:
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
} }
@ -457,7 +457,7 @@ extension KeyHandler {
composer.clear() composer.clear()
} }
let inputting = buildInputtingState let inputting = generateStateOfInputting()
// count > 0!isEmpty滿 // count > 0!isEmpty滿
switch inputting.displayedText.isEmpty { switch inputting.displayedText.isEmpty {
case false: stateCallback(inputting) case false: stateCallback(inputting)
@ -511,7 +511,7 @@ extension KeyHandler {
if compositor.cursor != 0 { if compositor.cursor != 0 {
compositor.cursor = 0 compositor.cursor = 0
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
errorCallback("66D97F90") errorCallback("66D97F90")
stateCallback(state) stateCallback(state)
@ -543,7 +543,7 @@ extension KeyHandler {
if compositor.cursor != compositor.length { if compositor.cursor != compositor.length {
compositor.cursor = compositor.length compositor.cursor = compositor.length
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
errorCallback("9B69908E") errorCallback("9B69908E")
stateCallback(state) stateCallback(state)
@ -574,7 +574,7 @@ extension KeyHandler {
/// ///
composer.clear() composer.clear()
switch compositor.isEmpty { switch compositor.isEmpty {
case false: stateCallback(buildInputtingState) case false: stateCallback(generateStateOfInputting())
case true: case true:
stateCallback(IMEState.ofAbortion()) stateCallback(IMEState.ofAbortion())
} }
@ -634,14 +634,14 @@ extension KeyHandler {
stateCallback(state) stateCallback(state)
return true return true
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
if compositor.cursor < compositor.length { if compositor.cursor < compositor.length {
compositor.cursor += 1 compositor.cursor += 1
if isCursorCuttingChar() { if isCursorCuttingChar() {
compositor.jumpCursorBySpan(to: .front) compositor.jumpCursorBySpan(to: .front)
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
errorCallback("A96AAD58") errorCallback("A96AAD58")
stateCallback(state) stateCallback(state)
@ -703,14 +703,14 @@ extension KeyHandler {
stateCallback(state) stateCallback(state)
return true return true
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
if compositor.cursor > 0 { if compositor.cursor > 0 {
compositor.cursor -= 1 compositor.cursor -= 1
if isCursorCuttingChar() { if isCursorCuttingChar() {
compositor.jumpCursorBySpan(to: .rear) compositor.jumpCursorBySpan(to: .rear)
} }
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
} else { } else {
errorCallback("7045E6F3") errorCallback("7045E6F3")
stateCallback(state) stateCallback(state)
@ -750,7 +750,7 @@ extension KeyHandler {
return true return true
} }
let candidates = getCandidatesArray(fixOrder: true) let candidates = generateArrayOfCandidates(fixOrder: true)
guard !candidates.isEmpty else { guard !candidates.isEmpty else {
errorCallback("3378A6DF") errorCallback("3378A6DF")
return true return true
@ -758,7 +758,7 @@ extension KeyHandler {
var length = 0 var length = 0
var currentNode: Megrez.Compositor.Node? var currentNode: Megrez.Compositor.Node?
let cursorIndex = actualCandidateCursor let cursorIndex = cursorForCandidate
for node in compositor.walkedNodes { for node in compositor.walkedNodes {
length += node.spanLength length += node.spanLength
if length > cursorIndex { if length > cursorIndex {
@ -812,9 +812,9 @@ extension KeyHandler {
currentIndex = 0 currentIndex = 0
} }
fixNode(candidate: candidates[currentIndex], respectCursorPushing: false, preConsolidate: false) consolidateNode(candidate: candidates[currentIndex], respectCursorPushing: false, preConsolidate: false)
stateCallback(buildInputtingState) stateCallback(generateStateOfInputting())
return true return true
} }
} }

View File

@ -14,7 +14,7 @@ import Shared
/// 使 /// 使
private let kTemplateNameUserPhrases = "template-userphrases" private let kTemplateNameUserPhrases = "template-userphrases"
private let kTemplateNameUserReplacements = "template-replacements" private let kTemplateNameUserReplacements = "template-replacements"
private let kTemplateNameUserExclusions = "template-exclusions" private let kTemplateNameUserFilterList = "template-exclusions"
private let kTemplateNameUserSymbolPhrases = "template-usersymbolphrases" private let kTemplateNameUserSymbolPhrases = "template-usersymbolphrases"
private let kTemplateNameUserAssociatesCHS = "template-associatedPhrases-chs" private let kTemplateNameUserAssociatesCHS = "template-associatedPhrases-chs"
private let kTemplateNameUserAssociatesCHT = "template-associatedPhrases-cht" private let kTemplateNameUserAssociatesCHT = "template-associatedPhrases-cht"
@ -362,7 +362,7 @@ public enum LMMgr {
// MARK: - 使 // MARK: - 使
public static func ensureFileExists( public static func ensureFileExists(
_ fileURL: URL, populateWithTemplate templateBasename: String = "1145141919810", _ fileURL: URL, deployTemplate templateBasename: String = "1145141919810",
extension ext: String = "txt" extension ext: String = "txt"
) -> Bool { ) -> Bool {
let filePath = fileURL.path let filePath = fileURL.path
@ -393,15 +393,15 @@ public enum LMMgr {
/// CandidateNode UserOverrideModel /// CandidateNode UserOverrideModel
/// ///
/// ///
if !ensureFileExists(userPhrasesDataURL(mode), populateWithTemplate: kTemplateNameUserPhrases) if !ensureFileExists(userPhrasesDataURL(mode), deployTemplate: kTemplateNameUserPhrases)
|| !ensureFileExists( || !ensureFileExists(
userAssociatesDataURL(mode), userAssociatesDataURL(mode),
populateWithTemplate: mode == .imeModeCHS ? kTemplateNameUserAssociatesCHS : kTemplateNameUserAssociatesCHT deployTemplate: mode == .imeModeCHS ? kTemplateNameUserAssociatesCHS : kTemplateNameUserAssociatesCHT
) )
|| !ensureFileExists(userSCPCSequencesURL(mode)) || !ensureFileExists(userSCPCSequencesURL(mode))
|| !ensureFileExists(userFilteredDataURL(mode), populateWithTemplate: kTemplateNameUserExclusions) || !ensureFileExists(userFilteredDataURL(mode), deployTemplate: kTemplateNameUserFilterList)
|| !ensureFileExists(userReplacementsDataURL(mode), populateWithTemplate: kTemplateNameUserReplacements) || !ensureFileExists(userReplacementsDataURL(mode), deployTemplate: kTemplateNameUserReplacements)
|| !ensureFileExists(userSymbolDataURL(mode), populateWithTemplate: kTemplateNameUserSymbolPhrases) || !ensureFileExists(userSymbolDataURL(mode), deployTemplate: kTemplateNameUserSymbolPhrases)
{ {
return false return false
} }

View File

@ -55,13 +55,13 @@ public class SessionCtl: IMKInputController {
/// SessionCtl /// SessionCtl
public var isASCIIMode = false { public var isASCIIMode = false {
didSet { didSet {
resetKeyHandler() resetInputHandler()
setKeyLayout() setKeyLayout()
} }
} }
/// 調 /// 調
var keyHandler = KeyHandler(lm: LMMgr.currentLM(), uom: LMMgr.currentUOM(), pref: PrefMgr.shared) var inputHandler = InputHandler(lm: LMMgr.currentLM(), uom: LMMgr.currentUOM(), pref: PrefMgr.shared)
/// ///
public var state: IMEStateProtocol = IMEState.ofEmpty() { public var state: IMEStateProtocol = IMEState.ofEmpty() {
didSet { didSet {
@ -79,7 +79,7 @@ public class SessionCtl: IMKInputController {
useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift) useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift)
/// `handle(event:)` Shift /// `handle(event:)` Shift
public var rencentKeyHandledByKeyHandlerEtc = false public var rencentKeyHandledByInputHandlerEtc = false
/// ///
public static var isVerticalTyping: Bool = false public static var isVerticalTyping: Bool = false
@ -104,13 +104,13 @@ public class SessionCtl: IMKInputController {
didSet { didSet {
if oldValue != inputMode, inputMode != .imeModeNULL { if oldValue != inputMode, inputMode != .imeModeNULL {
UserDefaults.standard.synchronize() UserDefaults.standard.synchronize()
keyHandler.clear() // handle State.Empty() inputHandler.clear() // handle State.Empty()
// ---------------------------- // ----------------------------
/// ///
keyHandler.currentLM = LMMgr.currentLM() // inputHandler.currentLM = LMMgr.currentLM() //
keyHandler.currentUOM = LMMgr.currentUOM() inputHandler.currentUOM = LMMgr.currentUOM()
/// ///
keyHandler.ensureKeyboardParser() inputHandler.ensureKeyboardParser()
/// ///
syncBaseLMPrefs() syncBaseLMPrefs()
// ---------------------------- // ----------------------------
@ -131,7 +131,7 @@ public class SessionCtl: IMKInputController {
/// - inputClient: /// - inputClient:
override public init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) { override public init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
super.init(server: server, delegate: delegate, client: inputClient) super.init(server: server, delegate: delegate, client: inputClient)
keyHandler.delegate = self inputHandler.delegate = self
syncBaseLMPrefs() syncBaseLMPrefs()
// //
activateServer(inputClient) activateServer(inputClient)
@ -163,11 +163,11 @@ extension SessionCtl {
} }
/// 調 /// 調
public func resetKeyHandler() { public func resetInputHandler() {
// //
if state.type == .ofInputting, PrefMgr.shared.trimUnfinishedReadingsOnCommit { if state.type == .ofInputting, PrefMgr.shared.trimUnfinishedReadingsOnCommit {
keyHandler.composer.clear() inputHandler.composer.clear()
handle(state: keyHandler.buildInputtingState) handle(state: inputHandler.generateStateOfInputting())
} }
let isSecureMode = PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) let isSecureMode = PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
if state.hasComposition, !isSecureMode { if state.hasComposition, !isSecureMode {
@ -190,10 +190,10 @@ extension SessionCtl {
// activateServer nil // activateServer nil
// //
if keyHandler.delegate == nil { keyHandler.delegate = self } if inputHandler.delegate == nil { inputHandler.delegate = self }
// setValue() IMK activateServer() setValue() // setValue() IMK activateServer() setValue()
keyHandler.clear() // handle State.Empty() inputHandler.clear() // handle State.Empty()
keyHandler.ensureKeyboardParser() inputHandler.ensureKeyboardParser()
Self.theShiftKeyDetector.alsoToggleWithLShift = PrefMgr.shared.togglingAlphanumericalModeWithLShift Self.theShiftKeyDetector.alsoToggleWithLShift = PrefMgr.shared.togglingAlphanumericalModeWithLShift
@ -213,7 +213,7 @@ extension SessionCtl {
/// - Parameter sender: 使 /// - Parameter sender: 使
public override func deactivateServer(_ sender: Any!) { public override func deactivateServer(_ sender: Any!) {
_ = sender // _ = sender //
resetKeyHandler() // Empty resetInputHandler() // Empty
handle(state: IMEState.ofDeactivated()) handle(state: IMEState.ofDeactivated())
Self.allInstances.remove(self) Self.allInstances.remove(self)
} }
@ -272,7 +272,7 @@ extension SessionCtl {
/// - Parameter sender: 使 /// - Parameter sender: 使
public override func commitComposition(_ sender: Any!) { public override func commitComposition(_ sender: Any!) {
_ = sender // _ = sender //
resetKeyHandler() resetInputHandler()
// super.commitComposition(sender) // // super.commitComposition(sender) //
} }
@ -289,7 +289,7 @@ extension SessionCtl {
/// IMK Bug /// IMK Bug
public override func inputControllerWillClose() { public override func inputControllerWillClose() {
// //
resetKeyHandler() resetInputHandler()
super.inputControllerWillClose() super.inputControllerWillClose()
} }
} }

View File

@ -8,9 +8,9 @@
import Shared import Shared
// MARK: - KeyHandler Delegate // MARK: - InputHandler Delegate
extension SessionCtl: KeyHandlerDelegate { extension SessionCtl: InputHandlerDelegate {
public var clientBundleIdentifier: String { public var clientBundleIdentifier: String {
guard let client = client() else { return "" } guard let client = client() else { return "" }
return client.bundleIdentifier() ?? "" return client.bundleIdentifier() ?? ""
@ -18,7 +18,7 @@ extension SessionCtl: KeyHandlerDelegate {
public func candidateController() -> CtlCandidateProtocol { ctlCandidateCurrent } public func candidateController() -> CtlCandidateProtocol { ctlCandidateCurrent }
public func candidateSelectionCalledByKeyHandler(at index: Int) { public func candidateSelectionCalledByInputHandler(at index: Int) {
candidatePairSelected(at: index) candidatePairSelected(at: index)
} }
@ -86,18 +86,18 @@ extension SessionCtl: CtlCandidateDelegate {
if [.ofCandidates, .ofSymbolTable].contains(state.type) { if [.ofCandidates, .ofSymbolTable].contains(state.type) {
let selectedValue = state.candidates[index] let selectedValue = state.candidates[index]
keyHandler.fixNode( inputHandler.consolidateNode(
candidate: selectedValue, respectCursorPushing: true, candidate: selectedValue, respectCursorPushing: true,
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
) )
let inputting = keyHandler.buildInputtingState let inputting = inputHandler.generateStateOfInputting()
if PrefMgr.shared.useSCPCTypingMode { if PrefMgr.shared.useSCPCTypingMode {
handle(state: IMEState.ofCommitting(textToCommit: inputting.displayedText)) handle(state: IMEState.ofCommitting(textToCommit: inputting.displayedText))
// selectedValue.1 // selectedValue.1
if PrefMgr.shared.associatedPhrasesEnabled { if PrefMgr.shared.associatedPhrasesEnabled {
let associates = keyHandler.buildAssociatePhraseState( let associates = inputHandler.generateStateOfAssociates(
withPair: .init(key: selectedValue.0, value: selectedValue.1) withPair: .init(key: selectedValue.0, value: selectedValue.1)
) )
handle(state: associates.candidates.isEmpty ? IMEState.ofEmpty() : associates) handle(state: associates.candidates.isEmpty ? IMEState.ofEmpty() : associates)
@ -120,7 +120,7 @@ extension SessionCtl: CtlCandidateDelegate {
return return
} }
if PrefMgr.shared.associatedPhrasesEnabled { if PrefMgr.shared.associatedPhrasesEnabled {
let associates = keyHandler.buildAssociatePhraseState( let associates = inputHandler.generateStateOfAssociates(
withPair: .init(key: selectedValue.0, value: String(valueKept)) withPair: .init(key: selectedValue.0, value: String(valueKept))
) )
if !associates.candidates.isEmpty { if !associates.candidates.isEmpty {

View File

@ -38,7 +38,7 @@ extension SessionCtl {
// NSEvent nilApple InputMethodKit // NSEvent nilApple InputMethodKit
// client() // client()
guard let event = event, sender is IMKTextInput else { guard let event = event, sender is IMKTextInput else {
resetKeyHandler() resetInputHandler()
return false return false
} }
@ -73,7 +73,7 @@ extension SessionCtl {
/// event event var Shift /// event event var Shift
if #available(macOS 10.15, *) { if #available(macOS 10.15, *) {
if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode { if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode {
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) { if !shouldUseShiftToggleHandle || (!rencentKeyHandledByInputHandlerEtc && shouldUseShiftToggleHandle) {
let status = NSLocalizedString("NotificationSwitchASCII", comment: "") let status = NSLocalizedString("NotificationSwitchASCII", comment: "")
Notifier.notify( Notifier.notify(
message: isASCIIMode.toggled() message: isASCIIMode.toggled()
@ -82,7 +82,7 @@ extension SessionCtl {
) )
} }
if shouldUseShiftToggleHandle { if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = false rencentKeyHandledByInputHandlerEtc = false
} }
return false return false
} }
@ -93,7 +93,7 @@ extension SessionCtl {
// Shift // Shift
if isASCIIMode, !isCapsLocked { return false } if isASCIIMode, !isCapsLocked { return false }
/// flags使 KeyHandler /// flags使 InputHandler
/// flags /// flags
/// event.type == .flagsChanged return false /// event.type == .flagsChanged return false
/// NSInternalInconsistencyException /// NSInternalInconsistencyException
@ -116,7 +116,7 @@ extension SessionCtl {
} }
// //
if keyHandler.composer.parser.rawValue < 100 { if inputHandler.composer.parser.rawValue < 100 {
eventToDeal = eventToDeal.inAppleABCStaticForm eventToDeal = eventToDeal.inAppleABCStaticForm
} }
@ -132,7 +132,7 @@ extension SessionCtl {
// IMK IMK // IMK IMK
if let result = imkCandidatesEventPreHandler(event: eventToDeal) { if let result = imkCandidatesEventPreHandler(event: eventToDeal) {
if shouldUseShiftToggleHandle { rencentKeyHandledByKeyHandlerEtc = result } if shouldUseShiftToggleHandle { rencentKeyHandledByInputHandlerEtc = result }
return result return result
} }
@ -140,7 +140,7 @@ extension SessionCtl {
/// IMK 便 /// IMK 便
let result = commonEventHandler(eventToDeal) let result = commonEventHandler(eventToDeal)
if shouldUseShiftToggleHandle { if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result rencentKeyHandledByInputHandlerEtc = result
} }
return result return result
} }
@ -155,13 +155,13 @@ extension SessionCtl {
/// - Returns: `true` IMK`false` /// - Returns: `true` IMK`false`
private func commonEventHandler(_ event: NSEvent) -> Bool { private func commonEventHandler(_ event: NSEvent) -> Bool {
// //
// KeyHandler // InputHandler
if !event.charCode.isPrintable { return false } if !event.charCode.isPrintable { return false }
/// 調 /// 調
/// result bool IMK /// result bool IMK
/// keyHandler.handleCandidate() /// inputHandler.handleCandidate()
let result = keyHandler.handle(input: event, state: state) { newState in let result = inputHandler.handleInput(event: event, state: state) { newState in
self.handle(state: newState) self.handle(state: newState)
} errorCallback: { errorString in } errorCallback: { errorString in
vCLog(errorString) vCLog(errorString)
@ -178,11 +178,11 @@ extension SessionCtl {
// IMK IMK // IMK IMK
// interpretKeyEvents() // interpretKeyEvents()
// - imkCandidates.interpretKeyEvents() // - imkCandidates.interpretKeyEvents()
// - delegate SessionCtl KeyHandler // - delegate SessionCtl InputHandler
if let imkCandidates = ctlCandidateCurrent as? CtlCandidateIMK, imkCandidates.visible { if let imkCandidates = ctlCandidateCurrent as? CtlCandidateIMK, imkCandidates.visible {
let event: NSEvent = CtlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal let event: NSEvent = CtlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
// Shift+Enter delegate keyHandler // Shift+Enter delegate inputHandler
// Shift Flags // Shift Flags
if event.isShiftHold, event.isEnter { if event.isShiftHold, event.isEnter {
guard let newEvent = event.reinitiate(modifierFlags: []) else { guard let newEvent = event.reinitiate(modifierFlags: []) else {

View File

@ -34,7 +34,7 @@ extension SessionCtl {
} }
clearInlineDisplay() clearInlineDisplay()
// //
keyHandler.clear() inputHandler.clear()
// deactivateServer() activateServer() // deactivateServer() activateServer()
// //
// IMKCandidates // IMKCandidates
@ -62,14 +62,14 @@ extension SessionCtl {
tooltipInstance.hide() tooltipInstance.hide()
clearInlineDisplay() clearInlineDisplay()
// //
keyHandler.clear() inputHandler.clear()
case .ofCommitting: case .ofCommitting:
ctlCandidateCurrent.visible = false ctlCandidateCurrent.visible = false
tooltipInstance.hide() tooltipInstance.hide()
commit(text: newState.textToCommit) commit(text: newState.textToCommit)
clearInlineDisplay() clearInlineDisplay()
// //
keyHandler.clear() inputHandler.clear()
case .ofInputting: case .ofInputting:
ctlCandidateCurrent.visible = false ctlCandidateCurrent.visible = false
tooltipInstance.hide() tooltipInstance.hide()

View File

@ -57,7 +57,7 @@ extension SessionCtl {
public override func candidateSelectionChanged(_: NSAttributedString!) { public override func candidateSelectionChanged(_: NSAttributedString!) {
// //
// IMKServer.commitCompositionWithReply() commitComposition() // IMKServer.commitCompositionWithReply() commitComposition()
// keyHandler // inputHandler
// //

View File

@ -221,7 +221,7 @@ extension SessionCtl {
} }
@objc public func toggleSCPCTypingMode(_: Any? = nil) { @objc public func toggleSCPCTypingMode(_: Any? = nil) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n" message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
+ (PrefMgr.shared.useSCPCTypingMode.toggled() + (PrefMgr.shared.useSCPCTypingMode.toggled()
@ -231,7 +231,7 @@ extension SessionCtl {
} }
@objc public func toggleChineseConverter(_: Any?) { @objc public func toggleChineseConverter(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n" message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
+ (PrefMgr.shared.chineseConversionEnabled.toggled() + (PrefMgr.shared.chineseConversionEnabled.toggled()
@ -241,7 +241,7 @@ extension SessionCtl {
} }
@objc public func toggleShiftJISShinjitaiOutput(_: Any?) { @objc public func toggleShiftJISShinjitaiOutput(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n" message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
+ (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled() + (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled()
@ -251,7 +251,7 @@ extension SessionCtl {
} }
@objc public func toggleCurrencyNumerals(_: Any?) { @objc public func toggleCurrencyNumerals(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n" message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
+ (PrefMgr.shared.currencyNumeralsEnabled.toggled() + (PrefMgr.shared.currencyNumeralsEnabled.toggled()
@ -261,7 +261,7 @@ extension SessionCtl {
} }
@objc public func toggleHalfWidthPunctuation(_: Any?) { @objc public func toggleHalfWidthPunctuation(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n" message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
+ (PrefMgr.shared.halfWidthPunctuationEnabled.toggled() + (PrefMgr.shared.halfWidthPunctuationEnabled.toggled()
@ -271,7 +271,7 @@ extension SessionCtl {
} }
@objc public func toggleCNS11643Enabled(_: Any?) { @objc public func toggleCNS11643Enabled(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n" message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
+ (PrefMgr.shared.cns11643Enabled.toggled() + (PrefMgr.shared.cns11643Enabled.toggled()
@ -281,7 +281,7 @@ extension SessionCtl {
} }
@objc public func toggleSymbolEnabled(_: Any?) { @objc public func toggleSymbolEnabled(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n" message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
+ (PrefMgr.shared.symbolInputEnabled.toggled() + (PrefMgr.shared.symbolInputEnabled.toggled()
@ -291,7 +291,7 @@ extension SessionCtl {
} }
@objc public func toggleAssociatedPhrasesEnabled(_: Any?) { @objc public func toggleAssociatedPhrasesEnabled(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n" message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
+ (PrefMgr.shared.associatedPhrasesEnabled.toggled() + (PrefMgr.shared.associatedPhrasesEnabled.toggled()
@ -301,7 +301,7 @@ extension SessionCtl {
} }
@objc public func togglePhraseReplacement(_: Any?) { @objc public func togglePhraseReplacement(_: Any?) {
resetKeyHandler() resetInputHandler()
Notifier.notify( Notifier.notify(
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n" message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
+ (PrefMgr.shared.phraseReplacementEnabled.toggled() + (PrefMgr.shared.phraseReplacementEnabled.toggled()

View File

@ -79,7 +79,7 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
public required init(_ layout: NSUserInterfaceLayoutOrientation = .horizontal) { public required init(_ layout: NSUserInterfaceLayoutOrientation = .horizontal) {
super.init(server: theServer, panelType: kIMKScrollingGridCandidatePanel) super.init(server: theServer, panelType: kIMKScrollingGridCandidatePanel)
specifyLayout(layout) specifyLayout(layout)
// true ctlIME // true SessionCtl
setAttributes([IMKCandidatesSendServerKeyEventFirst: true]) setAttributes([IMKCandidatesSendServerKeyEventFirst: true])
visible = false visible = false
// guard let currentTISInputSource = currentTISInputSource else { return } // // guard let currentTISInputSource = currentTISInputSource else { return } //
@ -101,7 +101,7 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
} }
/// IMKCandidates /// IMKCandidates
/// IMK keyHandler `ctlIME_Core` /// IMK inputHandler `SessionCtl_HandleEvent`
// IMK // IMK
@discardableResult public func showNextPage() -> Bool { @discardableResult public func showNextPage() -> Bool {

View File

@ -15,18 +15,18 @@
5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176B287539BB000443A9 /* SessionCtl_HandleStates.swift */; }; 5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176B287539BB000443A9 /* SessionCtl_HandleStates.swift */; };
5B21176E28753B35000443A9 /* SessionCtl_HandleDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176D28753B35000443A9 /* SessionCtl_HandleDisplay.swift */; }; 5B21176E28753B35000443A9 /* SessionCtl_HandleDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176D28753B35000443A9 /* SessionCtl_HandleDisplay.swift */; };
5B21177028753B9D000443A9 /* SessionCtl_Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176F28753B9D000443A9 /* SessionCtl_Delegates.swift */; }; 5B21177028753B9D000443A9 /* SessionCtl_Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176F28753B9D000443A9 /* SessionCtl_Delegates.swift */; };
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3133BE280B229700A4A505 /* KeyHandler_States.swift */; }; 5B3133BF280B229700A4A505 /* InputHandler_States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3133BE280B229700A4A505 /* InputHandler_States.swift */; };
5B40113928D7050D00A9D4CB /* Shared in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113828D7050D00A9D4CB /* Shared */; }; 5B40113928D7050D00A9D4CB /* Shared in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113828D7050D00A9D4CB /* Shared */; };
5B40113C28D71C0100A9D4CB /* Uninstaller in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113B28D71C0100A9D4CB /* Uninstaller */; }; 5B40113C28D71C0100A9D4CB /* Uninstaller in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113B28D71C0100A9D4CB /* Uninstaller */; };
5B5A603028E81CC50001AE8D /* SwiftUIBackports in Frameworks */ = {isa = PBXBuildFile; productRef = 5B5A602F28E81CC50001AE8D /* SwiftUIBackports */; }; 5B5A603028E81CC50001AE8D /* SwiftUIBackports in Frameworks */ = {isa = PBXBuildFile; productRef = 5B5A602F28E81CC50001AE8D /* SwiftUIBackports */; };
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; }; 5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift */; }; 5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift */; };
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; }; 5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; }; 5B782EC4280C243C007276DE /* InputHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* InputHandler_HandleCandidate.swift */; };
5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */; }; 5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */; };
5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; }; 5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; };
5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */; }; 5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */; };
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */; }; 5B7F225D2808501000DDD3CB /* InputHandler_HandleInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F225C2808501000DDD3CB /* InputHandler_HandleInput.swift */; };
5B84579E2871AD2200C93B01 /* convdict.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B84579C2871AD2200C93B01 /* convdict.plist */; }; 5B84579E2871AD2200C93B01 /* convdict.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B84579C2871AD2200C93B01 /* convdict.plist */; };
5B8457A12871ADBE00C93B01 /* ChineseConverterBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */; }; 5B8457A12871ADBE00C93B01 /* ChineseConverterBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */; };
5B963C9D28D5BFB800DCEE88 /* CocoaExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963C9C28D5BFB800DCEE88 /* CocoaExtension */; }; 5B963C9D28D5BFB800DCEE88 /* CocoaExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963C9C28D5BFB800DCEE88 /* CocoaExtension */; };
@ -60,7 +60,7 @@
5BC5E02128DDEFE00094E427 /* TooltipUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5BC5E02028DDEFE00094E427 /* TooltipUI */; }; 5BC5E02128DDEFE00094E427 /* TooltipUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5BC5E02028DDEFE00094E427 /* TooltipUI */; };
5BC5E02428DE07860094E427 /* PopupCompositionBuffer in Frameworks */ = {isa = PBXBuildFile; productRef = 5BC5E02328DE07860094E427 /* PopupCompositionBuffer */; }; 5BC5E02428DE07860094E427 /* PopupCompositionBuffer in Frameworks */ = {isa = PBXBuildFile; productRef = 5BC5E02328DE07860094E427 /* PopupCompositionBuffer */; };
5BCCAFF828DB19A300AB1B27 /* PrefMgr_Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */; }; 5BCCAFF828DB19A300AB1B27 /* PrefMgr_Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */; };
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113C2818543900609769 /* KeyHandler_Core.swift */; }; 5BD0113D2818543900609769 /* InputHandler_Core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113C2818543900609769 /* InputHandler_Core.swift */; };
5BD05BCA27B2A43D004C4F1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; }; 5BD05BCA27B2A43D004C4F1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; };
5BD05C5D27B2BBA9004C4F1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05C5B27B2BBA9004C4F1D /* Main.storyboard */; }; 5BD05C5D27B2BBA9004C4F1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05C5B27B2BBA9004C4F1D /* Main.storyboard */; };
5BD05C6627B2BBEF004C4F1D /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6127B2BBEF004C4F1D /* Document.swift */; }; 5BD05C6627B2BBEF004C4F1D /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6127B2BBEF004C4F1D /* Document.swift */; };
@ -77,7 +77,7 @@
5BDB7A4528D4824A001AC277 /* ShiftKeyUpChecker in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4428D4824A001AC277 /* ShiftKeyUpChecker */; }; 5BDB7A4528D4824A001AC277 /* ShiftKeyUpChecker in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4428D4824A001AC277 /* ShiftKeyUpChecker */; };
5BDB7A4728D4824A001AC277 /* Tekkon in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4628D4824A001AC277 /* Tekkon */; }; 5BDB7A4728D4824A001AC277 /* Tekkon in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4628D4824A001AC277 /* Tekkon */; };
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; }; 5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */; }; 5BE377A0288FED8D0037365B /* InputHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */; };
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; }; 5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; }; 5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; };
5BEDB721283B4C250078EB25 /* data-cns.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71D283B4AEA0078EB25 /* data-cns.plist */; }; 5BEDB721283B4C250078EB25 /* data-cns.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71D283B4AEA0078EB25 /* data-cns.plist */; };
@ -202,7 +202,7 @@
5B2F2BB3286216A500B8557B /* vChewingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vChewingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5B2F2BB3286216A500B8557B /* vChewingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vChewingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; }; 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
5B312684287800DE001AA720 /* FAQ.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = FAQ.md; sourceTree = "<group>"; }; 5B312684287800DE001AA720 /* FAQ.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = FAQ.md; sourceTree = "<group>"; };
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_States.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; }; 5B3133BE280B229700A4A505 /* InputHandler_States.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = InputHandler_States.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B40113A28D71B8700A9D4CB /* vChewing_Uninstaller */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Uninstaller; path = Packages/vChewing_Uninstaller; sourceTree = "<group>"; }; 5B40113A28D71B8700A9D4CB /* vChewing_Uninstaller */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Uninstaller; path = Packages/vChewing_Uninstaller; sourceTree = "<group>"; };
5B5A602E28E81CB00001AE8D /* ShapsBenkau_SwiftUIBackports */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ShapsBenkau_SwiftUIBackports; path = Packages/ShapsBenkau_SwiftUIBackports; sourceTree = "<group>"; }; 5B5A602E28E81CB00001AE8D /* ShapsBenkau_SwiftUIBackports */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ShapsBenkau_SwiftUIBackports; path = Packages/ShapsBenkau_SwiftUIBackports; sourceTree = "<group>"; };
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; }; 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
@ -210,12 +210,12 @@
5B6C141128A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCtl_HandleEvent.swift; sourceTree = "<group>"; }; 5B6C141128A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCtl_HandleEvent.swift; sourceTree = "<group>"; };
5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; }; 5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; };
5B73FB5F27B2BE1300E9BF49 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 5B73FB5F27B2BE1300E9BF49 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; }; 5B782EC3280C243C007276DE /* InputHandler_HandleCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = InputHandler_HandleCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = suiPrefPaneDevZone.swift; sourceTree = "<group>"; }; 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = suiPrefPaneDevZone.swift; sourceTree = "<group>"; };
5B7BC4AF27AFFBE800F66C24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmPrefWindow.xib; sourceTree = "<group>"; }; 5B7BC4AF27AFFBE800F66C24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmPrefWindow.xib; sourceTree = "<group>"; };
5B7BC4B227AFFC0B00F66C24 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmPrefWindow.strings; sourceTree = "<group>"; }; 5B7BC4B227AFFC0B00F66C24 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmPrefWindow.strings; sourceTree = "<group>"; };
5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = fixinstall.sh; sourceTree = "<group>"; }; 5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = fixinstall.sh; sourceTree = "<group>"; };
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleInput.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; }; 5B7F225C2808501000DDD3CB /* InputHandler_HandleInput.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = InputHandler_HandleInput.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B84579C2871AD2200C93B01 /* convdict.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = convdict.plist; sourceTree = "<group>"; }; 5B84579C2871AD2200C93B01 /* convdict.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = convdict.plist; sourceTree = "<group>"; };
5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChineseConverterBridge.swift; sourceTree = "<group>"; }; 5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChineseConverterBridge.swift; sourceTree = "<group>"; };
5B963C9B28D5BE4100DCEE88 /* vChewing_CocoaExtension */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_CocoaExtension; path = Packages/vChewing_CocoaExtension; sourceTree = "<group>"; }; 5B963C9B28D5BE4100DCEE88 /* vChewing_CocoaExtension */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_CocoaExtension; path = Packages/vChewing_CocoaExtension; sourceTree = "<group>"; };
@ -249,7 +249,7 @@
5BC5E01F28DDEFD80094E427 /* vChewing_TooltipUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_TooltipUI; path = Packages/vChewing_TooltipUI; sourceTree = "<group>"; }; 5BC5E01F28DDEFD80094E427 /* vChewing_TooltipUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_TooltipUI; path = Packages/vChewing_TooltipUI; sourceTree = "<group>"; };
5BC5E02228DE07250094E427 /* vChewing_PopupCompositionBuffer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_PopupCompositionBuffer; path = Packages/vChewing_PopupCompositionBuffer; sourceTree = "<group>"; }; 5BC5E02228DE07250094E427 /* vChewing_PopupCompositionBuffer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_PopupCompositionBuffer; path = Packages/vChewing_PopupCompositionBuffer; sourceTree = "<group>"; };
5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefMgr_Extension.swift; sourceTree = "<group>"; }; 5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefMgr_Extension.swift; sourceTree = "<group>"; };
5BD0113C2818543900609769 /* KeyHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Core.swift; sourceTree = "<group>"; usesTabs = 0; }; 5BD0113C2818543900609769 /* InputHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = InputHandler_Core.swift; sourceTree = "<group>"; usesTabs = 0; };
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewingPhraseEditor.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewingPhraseEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
5BD05BC627B2A42A004C4F1D /* vChewingPhraseEditor.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = vChewingPhraseEditor.entitlements; sourceTree = "<group>"; }; 5BD05BC627B2A42A004C4F1D /* vChewingPhraseEditor.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = vChewingPhraseEditor.entitlements; sourceTree = "<group>"; };
5BD05C5C27B2BBA9004C4F1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 5BD05C5C27B2BBA9004C4F1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@ -275,7 +275,7 @@
5BDCBB4A27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; }; 5BDCBB4A27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
5BDCBB4B27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; }; 5BDCBB4B27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
5BDCBB4D27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; }; 5BDCBB4D27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyHandler_HandleComposition.swift; sourceTree = "<group>"; }; 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputHandler_HandleComposition.swift; sourceTree = "<group>"; };
5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; }; 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5BE78BDB27B37764005EA1BE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmAboutWindow.xib; sourceTree = "<group>"; }; 5BE78BDB27B37764005EA1BE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmAboutWindow.xib; sourceTree = "<group>"; };
5BE78BDF27B37968005EA1BE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmAboutWindow.strings; sourceTree = "<group>"; }; 5BE78BDF27B37968005EA1BE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmAboutWindow.strings; sourceTree = "<group>"; };
@ -666,11 +666,11 @@
5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */, 5B8457A02871ADBE00C93B01 /* ChineseConverterBridge.swift */,
5BF56F9728C39A2700DD6839 /* IMEState.swift */, 5BF56F9728C39A2700DD6839 /* IMEState.swift */,
5BF56F9928C39D1800DD6839 /* IMEStateData.swift */, 5BF56F9928C39D1800DD6839 /* IMEStateData.swift */,
5BD0113C2818543900609769 /* KeyHandler_Core.swift */, 5BD0113C2818543900609769 /* InputHandler_Core.swift */,
5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */, 5B782EC3280C243C007276DE /* InputHandler_HandleCandidate.swift */,
5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */, 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */,
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */, 5B7F225C2808501000DDD3CB /* InputHandler_HandleInput.swift */,
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */, 5B3133BE280B229700A4A505 /* InputHandler_States.swift */,
5BAEFACF28012565001F42C9 /* LMMgr.swift */, 5BAEFACF28012565001F42C9 /* LMMgr.swift */,
D47B92BF27972AC800458394 /* main.swift */, D47B92BF27972AC800458394 /* main.swift */,
5B963CA728D5DB1400DCEE88 /* PrefMgr_Core.swift */, 5B963CA728D5DB1400DCEE88 /* PrefMgr_Core.swift */,
@ -1053,7 +1053,7 @@
files = ( files = (
5B963CA828D5DB1400DCEE88 /* PrefMgr_Core.swift in Sources */, 5B963CA828D5DB1400DCEE88 /* PrefMgr_Core.swift in Sources */,
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */, D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */, 5B7F225D2808501000DDD3CB /* InputHandler_HandleInput.swift in Sources */,
5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */, 5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */,
5BF56F9828C39A2700DD6839 /* IMEState.swift in Sources */, 5BF56F9828C39A2700DD6839 /* IMEState.swift in Sources */,
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */, 5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */,
@ -1063,15 +1063,15 @@
5B21177028753B9D000443A9 /* SessionCtl_Delegates.swift in Sources */, 5B21177028753B9D000443A9 /* SessionCtl_Delegates.swift in Sources */,
5B21176E28753B35000443A9 /* SessionCtl_HandleDisplay.swift in Sources */, 5B21176E28753B35000443A9 /* SessionCtl_HandleDisplay.swift in Sources */,
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */, 5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */,
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */, 5B3133BF280B229700A4A505 /* InputHandler_States.swift in Sources */,
5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */, 5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */,
5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */, 5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */,
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */, D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */, 5BD0113D2818543900609769 /* InputHandler_Core.swift in Sources */,
5BF56F9A28C39D1800DD6839 /* IMEStateData.swift in Sources */, 5BF56F9A28C39D1800DD6839 /* IMEStateData.swift in Sources */,
5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */, 5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */,
5BAEFAD028012565001F42C9 /* LMMgr.swift in Sources */, 5BAEFAD028012565001F42C9 /* LMMgr.swift in Sources */,
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */, 5B782EC4280C243C007276DE /* InputHandler_HandleCandidate.swift in Sources */,
5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */, 5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */,
5BCCAFF828DB19A300AB1B27 /* PrefMgr_Extension.swift in Sources */, 5BCCAFF828DB19A300AB1B27 /* PrefMgr_Extension.swift in Sources */,
5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */, 5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */,
@ -1079,7 +1079,7 @@
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */, 5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
5BFDF011289635C100417BBC /* IMKCandidatesImpl.swift in Sources */, 5BFDF011289635C100417BBC /* IMKCandidatesImpl.swift in Sources */,
5BB802DA27FABA8300CF1C19 /* SessionCtl_Menu.swift in Sources */, 5BB802DA27FABA8300CF1C19 /* SessionCtl_Menu.swift in Sources */,
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */, 5BE377A0288FED8D0037365B /* InputHandler_HandleComposition.swift in Sources */,
5B00FA0C28DEC17200F6D436 /* SessionCtl_IMKCandidatesData.swift in Sources */, 5B00FA0C28DEC17200F6D436 /* SessionCtl_IMKCandidatesData.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;