SPM // Consolidate dependencies.

This commit is contained in:
ShikiSuen 2024-03-05 20:24:49 +08:00
parent 93256f0095
commit 005116c429
65 changed files with 521 additions and 475 deletions

View File

@ -13,13 +13,13 @@ let package = Package(
), ),
], ],
dependencies: [ dependencies: [
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
], ],
targets: [ targets: [
.target( .target(
name: "NSAttributedTextView", name: "NSAttributedTextView",
dependencies: [ dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
] ]
), ),
.testTarget( .testTarget(

View File

@ -6,7 +6,7 @@
// Modified by The vChewing Project in order to use it with AppKit. // Modified by The vChewing Project in order to use it with AppKit.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
import SwiftUI import SwiftUI
@available(macOS 10.15, *) @available(macOS 10.15, *)

View File

@ -7,9 +7,9 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension
import Foundation import Foundation
@testable import NSAttributedTextView @testable import NSAttributedTextView
import OSFrameworkImpl
import Shared import Shared
import XCTest import XCTest

View File

@ -1,7 +1,6 @@
// (c) 2019 and onwards Robert Muckle-Jones (Apache 2.0 License). // (c) 2019 and onwards Robert Muckle-Jones (Apache 2.0 License).
import Foundation import Foundation
import SwiftExtension
public class LineReader { public class LineReader {
let encoding: String.Encoding let encoding: String.Encoding

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
import Shared import Shared
private extension NSUserInterfaceLayoutOrientation { private extension NSUserInterfaceLayoutOrientation {

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
import Shared import Shared
/// AppKit SwiftUI /// AppKit SwiftUI

View File

@ -15,8 +15,7 @@ let package = Package(
dependencies: [ dependencies: [
.package(path: "../RMJay_LineReader"), .package(path: "../RMJay_LineReader"),
.package(path: "../vChewing_Megrez"), .package(path: "../vChewing_Megrez"),
.package(path: "../vChewing_PinyinPhonaConverter"), .package(path: "../vChewing_SwiftExtension"),
.package(path: "../vChewing_Shared"),
], ],
targets: [ targets: [
.target( .target(
@ -24,8 +23,7 @@ let package = Package(
dependencies: [ dependencies: [
.product(name: "LineReader", package: "RMJay_LineReader"), .product(name: "LineReader", package: "RMJay_LineReader"),
.product(name: "Megrez", package: "vChewing_Megrez"), .product(name: "Megrez", package: "vChewing_Megrez"),
.product(name: "Shared", package: "vChewing_Shared"), .product(name: "SwiftExtension", package: "vChewing_SwiftExtension"),
.product(name: "PinyinPhonaConverter", package: "vChewing_PinyinPhonaConverter"),
] ]
), ),
.testTarget( .testTarget(

View File

@ -8,7 +8,6 @@
import Foundation import Foundation
import LineReader import LineReader
import Shared
public extension LMAssembly { public extension LMAssembly {
enum LMConsolidator { enum LMConsolidator {
@ -26,19 +25,19 @@ public extension LMAssembly {
let lineReader = try LineReader(file: fileHandle) let lineReader = try LineReader(file: fileHandle)
for strLine in lineReader { // i=0 for strLine in lineReader { // i=0
if strLine != kPragmaHeader { if strLine != kPragmaHeader {
vCLog("Header Mismatch, Starting In-Place Consolidation.") vCLMLog("Header Mismatch, Starting In-Place Consolidation.")
return false return false
} else { } else {
vCLog("Header Verification Succeeded: \(strLine).") vCLMLog("Header Verification Succeeded: \(strLine).")
return true return true
} }
} }
} catch { } catch {
vCLog("Header Verification Failed: File Access Error.") vCLMLog("Header Verification Failed: File Access Error.")
return false return false
} }
} }
vCLog("Header Verification Failed: File Missing.") vCLMLog("Header Verification Failed: File Missing.")
return false return false
} }
@ -51,12 +50,12 @@ public extension LMAssembly {
let dict = try FileManager.default.attributesOfItem(atPath: path) let dict = try FileManager.default.attributesOfItem(atPath: path)
if let value = dict[FileAttributeKey.size] as? UInt64 { fileSize = value } if let value = dict[FileAttributeKey.size] as? UInt64 { fileSize = value }
} catch { } catch {
vCLog("EOF Fix Failed: File Missing at \(path).") vCLMLog("EOF Fix Failed: File Missing at \(path).")
return false return false
} }
guard let fileSize = fileSize else { return false } guard let fileSize = fileSize else { return false }
guard let writeFile = FileHandle(forUpdatingAtPath: path) else { guard let writeFile = FileHandle(forUpdatingAtPath: path) else {
vCLog("EOF Fix Failed: File Not Writable at \(path).") vCLMLog("EOF Fix Failed: File Not Writable at \(path).")
return false return false
} }
defer { writeFile.closeFile() } defer { writeFile.closeFile() }
@ -64,11 +63,11 @@ public extension LMAssembly {
/// consolidate() /// consolidate()
writeFile.seek(toFileOffset: fileSize - 1) writeFile.seek(toFileOffset: fileSize - 1)
if writeFile.readDataToEndOfFile().first != 0x0A { if writeFile.readDataToEndOfFile().first != 0x0A {
vCLog("EOF Missing Confirmed, Start Fixing.") vCLMLog("EOF Missing Confirmed, Start Fixing.")
var newData = Data() var newData = Data()
newData.append(0x0A) newData.append(0x0A)
writeFile.write(newData) writeFile.write(newData)
vCLog("EOF Successfully Assured.") vCLMLog("EOF Successfully Assured.")
} }
return false return false
} }
@ -142,14 +141,29 @@ public extension LMAssembly {
// Write consolidated file contents. // Write consolidated file contents.
try strProcessed.write(to: urlPath, atomically: false, encoding: .utf8) try strProcessed.write(to: urlPath, atomically: false, encoding: .utf8)
} catch { } catch {
vCLog("Consolidation Failed w/ File: \(path), error: \(error)") vCLMLog("Consolidation Failed w/ File: \(path), error: \(error)")
return false return false
} }
vCLog("Either Consolidation Successful Or No-Need-To-Consolidate.") vCLMLog("Either Consolidation Successful Or No-Need-To-Consolidate.")
return true return true
} }
vCLog("Consolidation Failed: File Missing at \(path).") vCLMLog("Consolidation Failed: File Missing at \(path).")
return false return false
} }
} }
} }
private extension String {
mutating func regReplace(pattern: String, replaceWith: String = "") {
// Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914
do {
let regex = try NSRegularExpression(
pattern: pattern, options: [.caseInsensitive, .anchorsMatchLines]
)
let range = NSRange(startIndex..., in: self)
self = regex.stringByReplacingMatches(
in: self, options: [], range: range, withTemplate: replaceWith
)
} catch { return }
}
}

View File

@ -8,8 +8,6 @@
import Foundation import Foundation
import Megrez import Megrez
import Shared
import SQLite3
public extension LMAssembly { public extension LMAssembly {
/// LMInstantiatorLMI /// LMInstantiatorLMI
@ -47,13 +45,13 @@ public extension LMAssembly {
static var ptrSQL: OpaquePointer? static var ptrSQL: OpaquePointer?
// SQLite // SQLite
public private(set) static var isSQLDBConnected: Bool = false public internal(set) static var isSQLDBConnected: Bool = false
// //
public let isCHS: Bool public let isCHS: Bool
// //
public var config = Config() public private(set) var config = Config()
// package // package
public init( public init(
@ -69,21 +67,8 @@ public extension LMAssembly {
return self return self
} }
@discardableResult public static func connectSQLDB(dbPath: String, dropPreviousConnection: Bool = true) -> Bool { public static func setCassetCandidateKeyValidator(_ validator: @escaping (String) -> Bool) {
if dropPreviousConnection { disconnectSQLDB() } Self.lmCassette.candidateKeysValidator = validator
vCLog("Establishing SQLite connection to: \(dbPath)")
guard sqlite3_open(dbPath, &Self.ptrSQL) == SQLITE_OK else { return false }
guard "PRAGMA journal_mode = OFF;".runAsSQLExec(dbPointer: &ptrSQL) else { return false }
isSQLDBConnected = true
return true
}
public static func disconnectSQLDB() {
if Self.ptrSQL != nil {
sqlite3_close_v2(Self.ptrSQL)
Self.ptrSQL = nil
}
isSQLDBConnected = false
} }
/// ///
@ -126,9 +111,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
self.lmUserPhrases.clear() self.lmUserPhrases.clear()
self.lmUserPhrases.open(path) self.lmUserPhrases.open(path)
vCLog("lmUserPhrases: \(self.lmUserPhrases.count) entries of data loaded from: \(path)") vCLMLog("lmUserPhrases: \(self.lmUserPhrases.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmUserPhrases: File access failure: \(path)") vCLMLog("lmUserPhrases: File access failure: \(path)")
} }
} }
guard let filterPath = filterPath else { return } guard let filterPath = filterPath else { return }
@ -136,9 +121,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: filterPath) { if FileManager.default.isReadableFile(atPath: filterPath) {
self.lmFiltered.clear() self.lmFiltered.clear()
self.lmFiltered.open(filterPath) self.lmFiltered.open(filterPath)
vCLog("lmFiltered: \(self.lmFiltered.count) entries of data loaded from: \(path)") vCLMLog("lmFiltered: \(self.lmFiltered.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmFiltered: File access failure: \(path)") vCLMLog("lmFiltered: File access failure: \(path)")
} }
} }
} }
@ -148,9 +133,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
lmFiltered.clear() lmFiltered.clear()
lmFiltered.open(path) lmFiltered.open(path)
vCLog("lmFiltered: \(lmFiltered.count) entries of data loaded from: \(path)") vCLMLog("lmFiltered: \(lmFiltered.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmFiltered: File access failure: \(path)") vCLMLog("lmFiltered: File access failure: \(path)")
} }
} }
@ -159,9 +144,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
self.lmUserSymbols.clear() self.lmUserSymbols.clear()
self.lmUserSymbols.open(path) self.lmUserSymbols.open(path)
vCLog("lmUserSymbol: \(self.lmUserSymbols.count) entries of data loaded from: \(path)") vCLMLog("lmUserSymbol: \(self.lmUserSymbols.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmUserSymbol: File access failure: \(path)") vCLMLog("lmUserSymbol: File access failure: \(path)")
} }
} }
} }
@ -171,9 +156,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
self.lmAssociates.clear() self.lmAssociates.clear()
self.lmAssociates.open(path) self.lmAssociates.open(path)
vCLog("lmAssociates: \(self.lmAssociates.count) entries of data loaded from: \(path)") vCLMLog("lmAssociates: \(self.lmAssociates.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmAssociates: File access failure: \(path)") vCLMLog("lmAssociates: File access failure: \(path)")
} }
} }
} }
@ -183,9 +168,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
self.lmReplacements.clear() self.lmReplacements.clear()
self.lmReplacements.open(path) self.lmReplacements.open(path)
vCLog("lmReplacements: \(self.lmReplacements.count) entries of data loaded from: \(path)") vCLMLog("lmReplacements: \(self.lmReplacements.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmReplacements: File access failure: \(path)") vCLMLog("lmReplacements: File access failure: \(path)")
} }
} }
} }
@ -196,9 +181,9 @@ public extension LMAssembly {
if FileManager.default.isReadableFile(atPath: path) { if FileManager.default.isReadableFile(atPath: path) {
Self.lmCassette.clear() Self.lmCassette.clear()
Self.lmCassette.open(path) Self.lmCassette.open(path)
vCLog("lmCassette: \(Self.lmCassette.count) entries of data loaded from: \(path)") vCLMLog("lmCassette: \(Self.lmCassette.count) entries of data loaded from: \(path)")
} else { } else {
vCLog("lmCassette: File access failure: \(path)") vCLMLog("lmCassette: File access failure: \(path)")
} }
} }
} }

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
import Megrez import Megrez
import Shared import SwiftExtension
public extension LMAssembly.LMInstantiator { public extension LMAssembly.LMInstantiator {
/// ///

View File

@ -8,7 +8,6 @@
import Foundation import Foundation
import Megrez import Megrez
import Shared
import SQLite3 import SQLite3
/* ============== /* ==============
@ -57,6 +56,23 @@ extension LMAssembly.LMInstantiator {
} }
extension LMAssembly.LMInstantiator { extension LMAssembly.LMInstantiator {
@discardableResult public static func connectSQLDB(dbPath: String, dropPreviousConnection: Bool = true) -> Bool {
if dropPreviousConnection { disconnectSQLDB() }
vCLMLog("Establishing SQLite connection to: \(dbPath)")
guard sqlite3_open(dbPath, &Self.ptrSQL) == SQLITE_OK else { return false }
guard "PRAGMA journal_mode = OFF;".runAsSQLExec(dbPointer: &ptrSQL) else { return false }
isSQLDBConnected = true
return true
}
public static func disconnectSQLDB() {
if Self.ptrSQL != nil {
sqlite3_close_v2(Self.ptrSQL)
Self.ptrSQL = nil
}
isSQLDBConnected = false
}
fileprivate static func querySQL(strStmt sqlQuery: String, coreColumn column: CoreColumn, handler: (String) -> Void) { fileprivate static func querySQL(strStmt sqlQuery: String, coreColumn column: CoreColumn, handler: (String) -> Void) {
guard Self.ptrSQL != nil else { return } guard Self.ptrSQL != nil else { return }
performStatementSansResult { ptrStatement in performStatementSansResult { ptrStatement in

View File

@ -0,0 +1,123 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Foundation
// 使 LMAssembly Tekkon
private typealias LengthSortedDictionary = [Int: [String: String]]
private let mapHanyuPinyinToPhonabets: LengthSortedDictionary = {
let parsed = try? JSONDecoder().decode(LengthSortedDictionary.self, from: jsnHanyuPinyinToMPS.data(using: .utf8) ?? Data([]))
return parsed ?? [:]
}()
extension String {
mutating func convertToPhonabets(newToneOne: String = "") {
if isEmpty || contains("_") || !isNotPureAlphanumerical { return }
let lengths = mapHanyuPinyinToPhonabets.keys.sorted().reversed()
lengths.forEach { length in
mapHanyuPinyinToPhonabets[length]?.forEach { key, value in
self = replacingOccurrences(of: key, with: value)
}
}
self = replacingOccurrences(of: " ", with: newToneOne)
}
}
///
private extension String {
var isNotPureAlphanumerical: Bool {
let regex = ".*[^A-Za-z0-9].*"
let testString = NSPredicate(format: "SELF MATCHES %@", regex)
return testString.evaluate(with: self)
}
}
private let jsnHanyuPinyinToMPS = #"""
{
"1":{"1":" ","2":"ˊ","3":"ˇ","4":"ˋ","5":"˙","a":"","e":"","o":"","q":""},
"2":{"ai":"","an":"","ao":"","ba":"ㄅㄚ","bi":"ㄅㄧ","bo":"ㄅㄛ","bu":"ㄅㄨ",
"ca":"ㄘㄚ","ce":"ㄘㄜ","ci":"","cu":"ㄘㄨ","da":"ㄉㄚ","de":"ㄉㄜ","di":"ㄉㄧ",
"du":"ㄉㄨ","eh":"","ei":"","en":"","er":"","fa":"ㄈㄚ","fo":"ㄈㄛ",
"fu":"ㄈㄨ","ga":"ㄍㄚ","ge":"ㄍㄜ","gi":"ㄍㄧ","gu":"ㄍㄨ","ha":"ㄏㄚ","he":"ㄏㄜ",
"hu":"ㄏㄨ","ji":"ㄐㄧ","ju":"ㄐㄩ","ka":"ㄎㄚ","ke":"ㄎㄜ","ku":"ㄎㄨ","la":"ㄌㄚ",
"le":"ㄌㄜ","li":"ㄌㄧ","lo":"ㄌㄛ","lu":"ㄌㄨ","lv":"ㄌㄩ","ma":"ㄇㄚ","me":"ㄇㄜ",
"mi":"ㄇㄧ","mo":"ㄇㄛ","mu":"ㄇㄨ","na":"ㄋㄚ","ne":"ㄋㄜ","ni":"ㄋㄧ","nu":"ㄋㄨ",
"nv":"ㄋㄩ","ou":"","pa":"ㄆㄚ","pi":"ㄆㄧ","po":"ㄆㄛ","pu":"ㄆㄨ","qi":"ㄑㄧ",
"qu":"ㄑㄩ","re":"ㄖㄜ","ri":"","ru":"ㄖㄨ","sa":"ㄙㄚ","se":"ㄙㄜ","si":"",
"su":"ㄙㄨ","ta":"ㄊㄚ","te":"ㄊㄜ","ti":"ㄊㄧ","tu":"ㄊㄨ","wa":"ㄨㄚ","wo":"ㄨㄛ",
"wu":"","xi":"ㄒㄧ","xu":"ㄒㄩ","ya":"ㄧㄚ","ye":"ㄧㄝ","yi":"","yo":"ㄧㄛ",
"yu":"","za":"ㄗㄚ","ze":"ㄗㄜ","zi":"","zu":"ㄗㄨ"},
"3":{"ang":"","bai":"ㄅㄞ","ban":"ㄅㄢ","bao":"ㄅㄠ","bei":"ㄅㄟ","ben":"ㄅㄣ",
"bie":"ㄅㄧㄝ","bin":"ㄅㄧㄣ","cai":"ㄘㄞ","can":"ㄘㄢ","cao":"ㄘㄠ","cei":"ㄘㄟ",
"cen":"ㄘㄣ","cha":"ㄔㄚ","che":"ㄔㄜ","chi":"","chu":"ㄔㄨ","cou":"ㄘㄡ",
"cui":"ㄘㄨㄟ","cun":"ㄘㄨㄣ","cuo":"ㄘㄨㄛ","dai":"ㄉㄞ","dan":"ㄉㄢ","dao":"ㄉㄠ",
"dei":"ㄉㄟ","den":"ㄉㄣ","dia":"ㄉㄧㄚ","die":"ㄉㄧㄝ","diu":"ㄉㄧㄡ","dou":"ㄉㄡ",
"dui":"ㄉㄨㄟ","dun":"ㄉㄨㄣ","duo":"ㄉㄨㄛ","eng":"","fan":"ㄈㄢ","fei":"ㄈㄟ",
"fen":"ㄈㄣ","fou":"ㄈㄡ","gai":"ㄍㄞ","gan":"ㄍㄢ","gao":"ㄍㄠ","gei":"ㄍㄟ",
"gen":"ㄍㄣ","gin":"ㄍㄧㄣ","gou":"ㄍㄡ","gua":"ㄍㄨㄚ","gue":"ㄍㄨㄜ","gui":"ㄍㄨㄟ",
"gun":"ㄍㄨㄣ","guo":"ㄍㄨㄛ","hai":"ㄏㄞ","han":"ㄏㄢ","hao":"ㄏㄠ","hei":"ㄏㄟ",
"hen":"ㄏㄣ","hou":"ㄏㄡ","hua":"ㄏㄨㄚ","hui":"ㄏㄨㄟ","hun":"ㄏㄨㄣ","huo":"ㄏㄨㄛ",
"jia":"ㄐㄧㄚ","jie":"ㄐㄧㄝ","jin":"ㄐㄧㄣ","jiu":"ㄐㄧㄡ","jue":"ㄐㄩㄝ",
"jun":"ㄐㄩㄣ","kai":"ㄎㄞ","kan":"ㄎㄢ","kao":"ㄎㄠ","ken":"ㄎㄣ","kiu":"ㄎㄧㄡ",
"kou":"ㄎㄡ","kua":"ㄎㄨㄚ","kui":"ㄎㄨㄟ","kun":"ㄎㄨㄣ","kuo":"ㄎㄨㄛ","lai":"ㄌㄞ",
"lan":"ㄌㄢ","lao":"ㄌㄠ","lei":"ㄌㄟ","lia":"ㄌㄧㄚ","lie":"ㄌㄧㄝ","lin":"ㄌㄧㄣ",
"liu":"ㄌㄧㄡ","lou":"ㄌㄡ","lun":"ㄌㄨㄣ","luo":"ㄌㄨㄛ","lve":"ㄌㄩㄝ","mai":"ㄇㄞ",
"man":"ㄇㄢ","mao":"ㄇㄠ","mei":"ㄇㄟ","men":"ㄇㄣ","mie":"ㄇㄧㄝ","min":"ㄇㄧㄣ",
"miu":"ㄇㄧㄡ","mou":"ㄇㄡ","nai":"ㄋㄞ","nan":"ㄋㄢ","nao":"ㄋㄠ","nei":"ㄋㄟ",
"nen":"ㄋㄣ","nie":"ㄋㄧㄝ","nin":"ㄋㄧㄣ","niu":"ㄋㄧㄡ","nou":"ㄋㄡ","nui":"ㄋㄨㄟ",
"nun":"ㄋㄨㄣ","nuo":"ㄋㄨㄛ","nve":"ㄋㄩㄝ","pai":"ㄆㄞ","pan":"ㄆㄢ","pao":"ㄆㄠ",
"pei":"ㄆㄟ","pen":"ㄆㄣ","pia":"ㄆㄧㄚ","pie":"ㄆㄧㄝ","pin":"ㄆㄧㄣ","pou":"ㄆㄡ",
"qia":"ㄑㄧㄚ","qie":"ㄑㄧㄝ","qin":"ㄑㄧㄣ","qiu":"ㄑㄧㄡ","que":"ㄑㄩㄝ",
"qun":"ㄑㄩㄣ","ran":"ㄖㄢ","rao":"ㄖㄠ","ren":"ㄖㄣ","rou":"ㄖㄡ","rui":"ㄖㄨㄟ",
"run":"ㄖㄨㄣ","ruo":"ㄖㄨㄛ","sai":"ㄙㄞ","san":"ㄙㄢ","sao":"ㄙㄠ","sei":"ㄙㄟ",
"sen":"ㄙㄣ","sha":"ㄕㄚ","she":"ㄕㄜ","shi":"","shu":"ㄕㄨ","sou":"ㄙㄡ",
"sui":"ㄙㄨㄟ","sun":"ㄙㄨㄣ","suo":"ㄙㄨㄛ","tai":"ㄊㄞ","tan":"ㄊㄢ","tao":"ㄊㄠ",
"tie":"ㄊㄧㄝ","tou":"ㄊㄡ","tui":"ㄊㄨㄟ","tun":"ㄊㄨㄣ","tuo":"ㄊㄨㄛ",
"wai":"ㄨㄞ","wan":"ㄨㄢ","wei":"ㄨㄟ","wen":"ㄨㄣ","xia":"ㄒㄧㄚ","xie":"ㄒㄧㄝ",
"xin":"ㄒㄧㄣ","xiu":"ㄒㄧㄡ","xue":"ㄒㄩㄝ","xun":"ㄒㄩㄣ","yai":"ㄧㄞ",
"yan":"ㄧㄢ","yao":"ㄧㄠ","yin":"ㄧㄣ","you":"ㄧㄡ","yue":"ㄩㄝ","yun":"ㄩㄣ",
"zai":"ㄗㄞ","zan":"ㄗㄢ","zao":"ㄗㄠ","zei":"ㄗㄟ","zen":"ㄗㄣ","zha":"ㄓㄚ",
"zhe":"ㄓㄜ","zhi":"","zhu":"ㄓㄨ","zou":"ㄗㄡ","zui":"ㄗㄨㄟ","zun":"ㄗㄨㄣ",
"zuo":"ㄗㄨㄛ"},
"4":{"bang":"ㄅㄤ","beng":"ㄅㄥ","bian":"ㄅㄧㄢ","biao":"ㄅㄧㄠ","bing":"ㄅㄧㄥ",
"cang":"ㄘㄤ","ceng":"ㄘㄥ","chai":"ㄔㄞ","chan":"ㄔㄢ","chao":"ㄔㄠ","chen":"ㄔㄣ",
"chou":"ㄔㄡ","chua":"ㄔㄨㄚ","chui":"ㄔㄨㄟ","chun":"ㄔㄨㄣ","chuo":"ㄔㄨㄛ",
"cong":"ㄘㄨㄥ","cuan":"ㄘㄨㄢ","dang":"ㄉㄤ","deng":"ㄉㄥ","dian":"ㄉㄧㄢ",
"diao":"ㄉㄧㄠ","ding":"ㄉㄧㄥ","dong":"ㄉㄨㄥ","duan":"ㄉㄨㄢ","fang":"ㄈㄤ",
"feng":"ㄈㄥ","fiao":"ㄈㄧㄠ","fong":"ㄈㄨㄥ","gang":"ㄍㄤ","geng":"ㄍㄥ",
"giao":"ㄍㄧㄠ","gong":"ㄍㄨㄥ","guai":"ㄍㄨㄞ","guan":"ㄍㄨㄢ","hang":"ㄏㄤ",
"heng":"ㄏㄥ","hong":"ㄏㄨㄥ","huai":"ㄏㄨㄞ","huan":"ㄏㄨㄢ","jian":"ㄐㄧㄢ",
"jiao":"ㄐㄧㄠ","jing":"ㄐㄧㄥ","juan":"ㄐㄩㄢ","kang":"ㄎㄤ","keng":"ㄎㄥ",
"kong":"ㄎㄨㄥ","kuai":"ㄎㄨㄞ","kuan":"ㄎㄨㄢ","lang":"ㄌㄤ","leng":"ㄌㄥ",
"lian":"ㄌㄧㄢ","liao":"ㄌㄧㄠ","ling":"ㄌㄧㄥ","long":"ㄌㄨㄥ","luan":"ㄌㄨㄢ",
"lvan":"ㄌㄩㄢ","mang":"ㄇㄤ","meng":"ㄇㄥ","mian":"ㄇㄧㄢ","miao":"ㄇㄧㄠ",
"ming":"ㄇㄧㄥ","nang":"ㄋㄤ","neng":"ㄋㄥ","nian":"ㄋㄧㄢ","niao":"ㄋㄧㄠ",
"ning":"ㄋㄧㄥ","nong":"ㄋㄨㄥ","nuan":"ㄋㄨㄢ","pang":"ㄆㄤ","peng":"ㄆㄥ",
"pian":"ㄆㄧㄢ","piao":"ㄆㄧㄠ","ping":"ㄆㄧㄥ","qian":"ㄑㄧㄢ","qiao":"ㄑㄧㄠ",
"qing":"ㄑㄧㄥ","quan":"ㄑㄩㄢ","rang":"ㄖㄤ","reng":"ㄖㄥ","rong":"ㄖㄨㄥ",
"ruan":"ㄖㄨㄢ","sang":"ㄙㄤ","seng":"ㄙㄥ","shai":"ㄕㄞ","shan":"ㄕㄢ",
"shao":"ㄕㄠ","shei":"ㄕㄟ","shen":"ㄕㄣ","shou":"ㄕㄡ","shua":"ㄕㄨㄚ",
"shui":"ㄕㄨㄟ","shun":"ㄕㄨㄣ","shuo":"ㄕㄨㄛ","song":"ㄙㄨㄥ","suan":"ㄙㄨㄢ",
"tang":"ㄊㄤ","teng":"ㄊㄥ","tian":"ㄊㄧㄢ","tiao":"ㄊㄧㄠ","ting":"ㄊㄧㄥ",
"tong":"ㄊㄨㄥ","tuan":"ㄊㄨㄢ","wang":"ㄨㄤ","weng":"ㄨㄥ","xian":"ㄒㄧㄢ",
"xiao":"ㄒㄧㄠ","xing":"ㄒㄧㄥ","xuan":"ㄒㄩㄢ","yang":"ㄧㄤ","ying":"ㄧㄥ",
"yong":"ㄩㄥ","yuan":"ㄩㄢ","zang":"ㄗㄤ","zeng":"ㄗㄥ","zhai":"ㄓㄞ",
"zhan":"ㄓㄢ","zhao":"ㄓㄠ","zhei":"ㄓㄟ","zhen":"ㄓㄣ","zhou":"ㄓㄡ",
"zhua":"ㄓㄨㄚ","zhui":"ㄓㄨㄟ","zhun":"ㄓㄨㄣ","zhuo":"ㄓㄨㄛ",
"zong":"ㄗㄨㄥ","zuan":"ㄗㄨㄢ"},
"5":{"biang":"ㄅㄧㄤ","chang":"ㄔㄤ","cheng":"ㄔㄥ","chong":"ㄔㄨㄥ","chuai":"ㄔㄨㄞ",
"chuan":"ㄔㄨㄢ","duang":"ㄉㄨㄤ","guang":"ㄍㄨㄤ","huang":"ㄏㄨㄤ","jiang":"ㄐㄧㄤ",
"jiong":"ㄐㄩㄥ","kiang":"ㄎㄧㄤ","kuang":"ㄎㄨㄤ","liang":"ㄌㄧㄤ","niang":"ㄋㄧㄤ",
"qiang":"ㄑㄧㄤ","qiong":"ㄑㄩㄥ","shang":"ㄕㄤ","sheng":"ㄕㄥ","shuai":"ㄕㄨㄞ",
"shuan":"ㄕㄨㄢ","xiang":"ㄒㄧㄤ","xiong":"ㄒㄩㄥ","zhang":"ㄓㄤ","zheng":"ㄓㄥ",
"zhong":"ㄓㄨㄥ","zhuai":"ㄓㄨㄞ","zhuan":"ㄓㄨㄢ"},
"6":{"chuang":"ㄔㄨㄤ","shuang":"ㄕㄨㄤ","zhuang":"ㄓㄨㄤ"}
}
"""#

View File

@ -7,8 +7,6 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import Megrez import Megrez
import PinyinPhonaConverter
import Shared
extension LMAssembly { extension LMAssembly {
struct LMAssociates { struct LMAssociates {
@ -48,8 +46,8 @@ extension LMAssembly {
replaceData(textData: rawStrData) replaceData(textData: rawStrData)
} catch { } catch {
filePath = oldPath filePath = oldPath
vCLog("\(error)") vCLMLog("\(error)")
vCLog("↑ Exception happened when reading data at: \(path).") vCLMLog("↑ Exception happened when reading data at: \(path).")
return false return false
} }
@ -93,7 +91,7 @@ extension LMAssembly {
do { do {
try strData.write(toFile: filePath, atomically: true, encoding: .utf8) try strData.write(toFile: filePath, atomically: true, encoding: .utf8)
} catch { } catch {
vCLog("Failed to save current database to: \(filePath)") vCLMLog("Failed to save current database to: \(filePath)")
} }
} }
@ -113,8 +111,7 @@ extension LMAssembly {
pairs.append(theValue) pairs.append(theValue)
} }
} }
var set = Set<String>() return pairs.deduplicated
return pairs.filter { set.insert($0).inserted }
} }
public func hasValuesFor(pair: Megrez.KeyValuePaired) -> Bool { public func hasValuesFor(pair: Megrez.KeyValuePaired) -> Bool {

View File

@ -10,7 +10,6 @@
import Foundation import Foundation
import LineReader import LineReader
import Megrez import Megrez
import Shared
extension LMAssembly { extension LMAssembly {
/// 便使 /// 便使
@ -40,6 +39,7 @@ extension LMAssembly {
public private(set) var areCandidateKeysShiftHeld: Bool = false public private(set) var areCandidateKeysShiftHeld: Bool = false
public private(set) var supplyQuickResults: Bool = false public private(set) var supplyQuickResults: Bool = false
public private(set) var supplyPartiallyMatchedResults: Bool = false public private(set) var supplyPartiallyMatchedResults: Bool = false
public var candidateKeysValidator: (String) -> Bool = { _ in false }
/// 西 - NORM /// 西 - NORM
private var norm = 0.0 private var norm = 0.0
} }
@ -195,7 +195,7 @@ extension LMAssembly.LMCassette {
// Post process. // Post process.
// Package 便 J / K // Package 便 J / K
// //
if CandidateKey.validate(keys: selectionKeys) != nil { selectionKeys = "1234567890" } if !candidateKeysValidator(selectionKeys) { selectionKeys = "1234567890" }
if !keysUsedInCharDef.intersection(selectionKeys.map(\.description)).isEmpty { if !keysUsedInCharDef.intersection(selectionKeys.map(\.description)).isEmpty {
areCandidateKeysShiftHeld = true areCandidateKeysShiftHeld = true
} }
@ -204,10 +204,10 @@ extension LMAssembly.LMCassette {
filePath = path filePath = path
return true return true
} catch { } catch {
vCLog("CIN Loading Failed: File Access Error.") vCLMLog("CIN Loading Failed: File Access Error.")
} }
} else { } else {
vCLog("CIN Loading Failed: File Missing.") vCLMLog("CIN Loading Failed: File Missing.")
} }
filePath = oldPath filePath = oldPath
return false return false

View File

@ -7,8 +7,6 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import Megrez import Megrez
import PinyinPhonaConverter
import Shared
extension LMAssembly { extension LMAssembly {
/// LMCore LMCoreEX range /// LMCore LMCoreEX range
@ -81,8 +79,8 @@ extension LMAssembly {
replaceData(textData: rawStrData) replaceData(textData: rawStrData)
} catch { } catch {
filePath = oldPath filePath = oldPath
vCLog("\(error)") vCLMLog("\(error)")
vCLog("↑ Exception happened when reading data at: \(path).") vCLMLog("↑ Exception happened when reading data at: \(path).")
return false return false
} }
@ -133,7 +131,7 @@ extension LMAssembly {
} }
try dataToWrite.write(toFile: filePath, atomically: true, encoding: .utf8) try dataToWrite.write(toFile: filePath, atomically: true, encoding: .utf8)
} catch { } catch {
vCLog("Failed to save current database to: \(filePath)") vCLMLog("Failed to save current database to: \(filePath)")
} }
} }
@ -150,7 +148,7 @@ extension LMAssembly {
strDump += addline strDump += addline
} }
} }
vCLog(strDump) vCLMLog(strDump)
} }
/// strData /// strData

View File

@ -7,7 +7,6 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import Foundation import Foundation
import Shared
extension LMAssembly { extension LMAssembly {
struct LMPlainBopomofo { struct LMPlainBopomofo {
@ -22,8 +21,8 @@ extension LMAssembly {
let rawJSON = try JSONDecoder().decode([String: [String: String]].self, from: rawData) let rawJSON = try JSONDecoder().decode([String: [String: String]].self, from: rawData)
dataMap = rawJSON dataMap = rawJSON
} catch { } catch {
vCLog("\(error)") vCLMLog("\(error)")
vCLog("↑ Exception happened when parsing raw JSON sequence data from vChewing LMAssembly.") vCLMLog("↑ Exception happened when parsing raw JSON sequence data from vChewing LMAssembly.")
dataMap = [:] dataMap = [:]
} }
} }

View File

@ -6,8 +6,6 @@
// 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.
import Shared
extension LMAssembly { extension LMAssembly {
struct LMReplacements { struct LMReplacements {
public private(set) var filePath: String? public private(set) var filePath: String?
@ -35,8 +33,8 @@ extension LMAssembly {
replaceData(textData: rawStrData) replaceData(textData: rawStrData)
} catch { } catch {
filePath = oldPath filePath = oldPath
vCLog("\(error)") vCLMLog("\(error)")
vCLog("↑ Exception happened when reading data at: \(path).") vCLMLog("↑ Exception happened when reading data at: \(path).")
return false return false
} }
@ -72,7 +70,7 @@ extension LMAssembly {
do { do {
try strData.write(toFile: filePath, atomically: true, encoding: .utf8) try strData.write(toFile: filePath, atomically: true, encoding: .utf8)
} catch { } catch {
vCLog("Failed to save current database to: \(filePath)") vCLMLog("Failed to save current database to: \(filePath)")
} }
} }
@ -81,7 +79,7 @@ extension LMAssembly {
for entry in rangeMap { for entry in rangeMap {
strDump += strData[entry.value] + "\n" strDump += strData[entry.value] + "\n"
} }
vCLog(strDump) vCLMLog(strDump)
} }
public func valuesFor(key: String) -> String { public func valuesFor(key: String) -> String {

View File

@ -9,7 +9,6 @@
import Foundation import Foundation
import Megrez import Megrez
import Shared
// MARK: - Public Types. // MARK: - Public Types.
@ -202,18 +201,18 @@ extension LMAssembly.LMUserOverride {
do { do {
let nullData = "{}" let nullData = "{}"
guard let fileURL = fileURL ?? fileSaveLocationURL else { guard let fileURL = fileURL ?? fileSaveLocationURL else {
throw "given fileURL is invalid or nil." throw UOMError(rawValue: "given fileURL is invalid or nil.")
} }
try nullData.write(to: fileURL, atomically: false, encoding: .utf8) try nullData.write(to: fileURL, atomically: false, encoding: .utf8)
} catch { } catch {
vCLog("UOM Error: Unable to clear the data in the UOM file. Details: \(error)") vCLMLog("UOM Error: Unable to clear the data in the UOM file. Details: \(error)")
return return
} }
} }
func saveData(toURL fileURL: URL? = nil) { func saveData(toURL fileURL: URL? = nil) {
guard let fileURL: URL = fileURL ?? fileSaveLocationURL else { guard let fileURL: URL = fileURL ?? fileSaveLocationURL else {
vCLog("UOM saveData() failed. At least the file Save URL is not set for the current UOM.") vCLMLog("UOM saveData() failed. At least the file Save URL is not set for the current UOM.")
return return
} }
// 使 JSONSerialization // 使 JSONSerialization
@ -222,14 +221,14 @@ extension LMAssembly.LMUserOverride {
guard let jsonData = try? encoder.encode(mutLRUMap) else { return } guard let jsonData = try? encoder.encode(mutLRUMap) else { return }
try jsonData.write(to: fileURL, options: .atomic) try jsonData.write(to: fileURL, options: .atomic)
} catch { } catch {
vCLog("UOM Error: Unable to save data, abort saving. Details: \(error)") vCLMLog("UOM Error: Unable to save data, abort saving. Details: \(error)")
return return
} }
} }
func loadData(fromURL fileURL: URL? = nil) { func loadData(fromURL fileURL: URL? = nil) {
guard let fileURL: URL = fileURL ?? fileSaveLocationURL else { guard let fileURL: URL = fileURL ?? fileSaveLocationURL else {
vCLog("UOM loadData() failed. At least the file Load URL is not set for the current UOM.") vCLMLog("UOM loadData() failed. At least the file Load URL is not set for the current UOM.")
return return
} }
// 使 JSONSerialization // 使 JSONSerialization
@ -238,13 +237,13 @@ extension LMAssembly.LMUserOverride {
let data = try Data(contentsOf: fileURL, options: .mappedIfSafe) let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
if ["", "{}"].contains(String(data: data, encoding: .utf8)) { return } if ["", "{}"].contains(String(data: data, encoding: .utf8)) { return }
guard let jsonResult = try? decoder.decode([String: KeyObservationPair].self, from: data) else { guard let jsonResult = try? decoder.decode([String: KeyObservationPair].self, from: data) else {
vCLog("UOM Error: Read file content type invalid, abort loading.") vCLMLog("UOM Error: Read file content type invalid, abort loading.")
return return
} }
mutLRUMap = jsonResult mutLRUMap = jsonResult
resetMRUList() resetMRUList()
} catch { } catch {
vCLog("UOM Error: Unable to read file or parse the data, abort loading. Details: \(error)") vCLMLog("UOM Error: Unable to read file or parse the data, abort loading. Details: \(error)")
return return
} }
} }
@ -271,7 +270,7 @@ extension LMAssembly.LMUserOverride {
mutLRUMap.removeValue(forKey: mutLRUList[mutLRUList.endIndex - 1].key) mutLRUMap.removeValue(forKey: mutLRUList[mutLRUList.endIndex - 1].key)
mutLRUList.removeLast() mutLRUList.removeLast()
} }
vCLog("UOM: Observation finished with new observation: \(key)") vCLMLog("UOM: Observation finished with new observation: \(key)")
saveCallback?() ?? saveData() saveCallback?() ?? saveData()
return return
} }
@ -282,7 +281,7 @@ extension LMAssembly.LMUserOverride {
) )
mutLRUList.insert(theNeta, at: 0) mutLRUList.insert(theNeta, at: 0)
mutLRUMap[key] = theNeta mutLRUMap[key] = theNeta
vCLog("UOM: Observation finished with existing observation: \(key)") vCLMLog("UOM: Observation finished with existing observation: \(key)")
saveCallback?() ?? saveData() saveCallback?() ?? saveData()
} }
} }
@ -400,3 +399,10 @@ extension LMAssembly.LMUserOverride {
return result return result
} }
} }
struct UOMError: LocalizedError {
var rawValue: String
var errorDescription: String? {
NSLocalizedString("rawValue", comment: "")
}
}

View File

@ -7,7 +7,6 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import Foundation import Foundation
import Shared
import SQLite3 import SQLite3
public enum LMAssembly { public enum LMAssembly {
@ -56,7 +55,7 @@ extension Array where Element == String {
sqlite3_prepare_v2(ptrDB, strStmt, -1, &ptrStmt, nil) == SQLITE_OK && sqlite3_step(ptrStmt) == SQLITE_DONE sqlite3_prepare_v2(ptrDB, strStmt, -1, &ptrStmt, nil) == SQLITE_OK && sqlite3_step(ptrStmt) == SQLITE_DONE
} }
guard thisResult else { guard thisResult else {
vCLog("SQL Query Error. Statement: \(strStmt)") vCLMLog("SQL Query Error. Statement: \(strStmt)")
return false return false
} }
} }
@ -83,3 +82,13 @@ func performStatementSansResult(_ handler: (inout OpaquePointer?) -> Void) {
} }
handler(&ptrStmt) handler(&ptrStmt)
} }
func vCLMLog(_ strPrint: StringLiteralType) {
guard let toLog = UserDefaults.standard.object(forKey: "_DebugMode") as? Bool else {
NSLog("vChewingDebug: %@", strPrint)
return
}
if toLog {
NSLog("vChewingDebug: %@", strPrint)
}
}

View File

@ -19,7 +19,7 @@ let package = Package(
.package(path: "../Qwertyyb_ShiftKeyUpChecker"), .package(path: "../Qwertyyb_ShiftKeyUpChecker"),
.package(path: "../vChewing_BrailleSputnik"), .package(path: "../vChewing_BrailleSputnik"),
.package(path: "../vChewing_CandidateWindow"), .package(path: "../vChewing_CandidateWindow"),
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
.package(path: "../vChewing_Hotenka"), .package(path: "../vChewing_Hotenka"),
.package(path: "../vChewing_IMKUtils"), .package(path: "../vChewing_IMKUtils"),
.package(path: "../vChewing_KimoDataReader"), .package(path: "../vChewing_KimoDataReader"),
@ -42,7 +42,7 @@ let package = Package(
.product(name: "BrailleSputnik", package: "vChewing_BrailleSputnik"), .product(name: "BrailleSputnik", package: "vChewing_BrailleSputnik"),
.product(name: "BookmarkManager", package: "Jad_BookmarkManager"), .product(name: "BookmarkManager", package: "Jad_BookmarkManager"),
.product(name: "CandidateWindow", package: "vChewing_CandidateWindow"), .product(name: "CandidateWindow", package: "vChewing_CandidateWindow"),
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
.product(name: "FolderMonitor", package: "DanielGalasko_FolderMonitor"), .product(name: "FolderMonitor", package: "DanielGalasko_FolderMonitor"),
.product(name: "Hotenka", package: "vChewing_Hotenka"), .product(name: "Hotenka", package: "vChewing_Hotenka"),
.product(name: "IMKUtils", package: "vChewing_IMKUtils"), .product(name: "IMKUtils", package: "vChewing_IMKUtils"),

View File

@ -9,9 +9,9 @@
/// 調 /// 調
import CandidateWindow import CandidateWindow
import CocoaExtension
import InputMethodKit import InputMethodKit
import Megrez import Megrez
import OSFrameworkImpl
import Shared import Shared
// MARK: - § 調 (Handle Candidate State). // MARK: - § 調 (Handle Candidate State).

View File

@ -1041,11 +1041,15 @@ extension InputHandler {
let fullWidthResult = behaviorValue % 2 != 0 // let fullWidthResult = behaviorValue % 2 != 0 //
triagePrefs: switch (behaviorValue, isConsideredEmptyForNow) { triagePrefs: switch (behaviorValue, isConsideredEmptyForNow) {
case (2, _), (3, _), (4, false), (5, false): case (2, _), (3, _), (4, false), (5, false):
currentLM.config.numPadFWHWStatus = fullWidthResult currentLM.setOptions { config in
config.numPadFWHWStatus = fullWidthResult
}
if handlePunctuation("_NumPad_\(inputText)") { return true } if handlePunctuation("_NumPad_\(inputText)") { return true }
default: break triagePrefs // case 0 & 1 default: break triagePrefs // case 0 & 1
} }
currentLM.config.numPadFWHWStatus = nil currentLM.setOptions { config in
config.numPadFWHWStatus = nil
}
delegate.switchState(IMEState.ofEmpty()) delegate.switchState(IMEState.ofEmpty())
let charToCommit = inputText.applyingTransformFW2HW(reverse: fullWidthResult) let charToCommit = inputText.applyingTransformFW2HW(reverse: fullWidthResult)
delegate.switchState(IMEState.ofCommitting(textToCommit: charToCommit)) delegate.switchState(IMEState.ofCommitting(textToCommit: charToCommit))

View File

@ -9,11 +9,11 @@
/// 調 IMK 調 /// 調 IMK 調
/// 調 /// 調
import CocoaExtension
import IMKUtils import IMKUtils
import InputMethodKit import InputMethodKit
import LangModelAssembly import LangModelAssembly
import Megrez import Megrez
import OSFrameworkImpl
import Shared import Shared
// MARK: - § 調 (Handle Input with States) * Triage // MARK: - § 調 (Handle Input with States) * Triage

View File

@ -65,6 +65,11 @@ public class LMMgr {
/// ///
/// - Remark: cassettePath() /// - Remark: cassettePath()
public static func loadCassetteData() { public static func loadCassetteData() {
func validateCassetteCandidateKey(_ target: String) -> Bool {
CandidateKey.validate(keys: target) == nil
}
LMAssembly.LMInstantiator.setCassetCandidateKeyValidator(validateCassetteCandidateKey)
LMAssembly.LMInstantiator.loadCassetteData(path: cassettePath()) LMAssembly.LMInstantiator.loadCassetteData(path: cassettePath())
} }

View File

@ -8,7 +8,7 @@
import AppKit import AppKit
import Carbon import Carbon
import CocoaExtension import OSFrameworkImpl
import Shared import Shared
public class SecurityAgentHelper { public class SecurityAgentHelper {

View File

@ -7,8 +7,8 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension
import Foundation import Foundation
import OSFrameworkImpl
import Shared import Shared
public class VwrServiceMenuEditor: NSViewController { public class VwrServiceMenuEditor: NSViewController {

View File

@ -7,10 +7,10 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import CandidateWindow import CandidateWindow
import CocoaExtension
import IMKUtils import IMKUtils
import InputMethodKit import InputMethodKit
import NotifierUI import NotifierUI
import OSFrameworkImpl
import PopupCompositionBuffer import PopupCompositionBuffer
import Shared import Shared
import ShiftKeyUpChecker import ShiftKeyUpChecker

View File

@ -6,10 +6,10 @@
// 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.
import CocoaExtension
import IMKUtils import IMKUtils
import InputMethodKit import InputMethodKit
import NotifierUI import NotifierUI
import OSFrameworkImpl
import Shared import Shared
import SwiftyCapsLockToggler import SwiftyCapsLockToggler

View File

@ -7,8 +7,8 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension
import NotifierUI import NotifierUI
import OSFrameworkImpl
import Shared import Shared
import SwiftExtension import SwiftExtension

View File

@ -8,8 +8,8 @@
import AppKit import AppKit
import BookmarkManager import BookmarkManager
import CocoaExtension
import Foundation import Foundation
import OSFrameworkImpl
import Shared import Shared
public extension SettingsPanesCocoa { public extension SettingsPanesCocoa {

View File

@ -7,8 +7,8 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import BookmarkManager import BookmarkManager
import OSFrameworkImpl
import Shared import Shared
import SwiftExtension
import SwiftUI import SwiftUI
@available(macOS 13, *) @available(macOS 13, *)

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import BookmarkManager import BookmarkManager
import CocoaExtension import OSFrameworkImpl
import Shared import Shared
import SwiftExtension import SwiftExtension
import SwiftUI import SwiftUI

View File

@ -6,10 +6,10 @@
// 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.
import CocoaExtension
import InputMethodKit import InputMethodKit
import LangModelAssembly import LangModelAssembly
@testable import MainAssembly @testable import MainAssembly
import OSFrameworkImpl
import Shared import Shared
import XCTest import XCTest

View File

@ -6,10 +6,10 @@
// 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.
import CocoaExtension
import InputMethodKit import InputMethodKit
import LangModelAssembly import LangModelAssembly
@testable import MainAssembly @testable import MainAssembly
import OSFrameworkImpl
import Shared import Shared
import XCTest import XCTest

View File

@ -6,10 +6,10 @@
// 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.
import CocoaExtension
import InputMethodKit import InputMethodKit
import LangModelAssembly import LangModelAssembly
@testable import MainAssembly @testable import MainAssembly
import OSFrameworkImpl
import Shared import Shared
import XCTest import XCTest

View File

@ -13,13 +13,13 @@ let package = Package(
), ),
], ],
dependencies: [ dependencies: [
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
], ],
targets: [ targets: [
.target( .target(
name: "NotifierUI", name: "NotifierUI",
dependencies: [ dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
] ]
), ),
] ]

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
public class Notifier: NSWindowController { public class Notifier: NSWindowController {
public static func notify(message: String) { public static func notify(message: String) {

View File

@ -2,14 +2,14 @@
import PackageDescription import PackageDescription
let package = Package( let package = Package(
name: "CocoaExtension", name: "OSFrameworkImpl",
platforms: [ platforms: [
.macOS(.v11), .macOS(.v11),
], ],
products: [ products: [
.library( .library(
name: "CocoaExtension", name: "OSFrameworkImpl",
targets: ["CocoaExtension"] targets: ["OSFrameworkImpl"]
), ),
], ],
dependencies: [ dependencies: [
@ -17,7 +17,7 @@ let package = Package(
], ],
targets: [ targets: [
.target( .target(
name: "CocoaExtension", name: "OSFrameworkImpl",
dependencies: [ dependencies: [
.product(name: "SwiftExtension", package: "vChewing_SwiftExtension"), .product(name: "SwiftExtension", package: "vChewing_SwiftExtension"),
] ]

View File

@ -1,4 +1,4 @@
# CocoaExtension # OSFrameworkImpl
威注音輸入法針對 Cocoa 的一些功能擴充,使程式維護體驗更佳。 威注音輸入法針對 Cocoa 的一些功能擴充,使程式維護體驗更佳。

View File

@ -210,19 +210,6 @@ public extension NSApplication {
} }
} }
// MARK: - String.applyingTransform
public extension String {
func applyingTransformFW2HW(reverse: Bool) -> String {
if #available(macOS 10.11, *) {
return applyingTransform(.fullwidthToHalfwidth, reverse: reverse) ?? self
}
let theString = NSMutableString(string: self)
CFStringTransform(theString, nil, kCFStringTransformFullwidthHalfwidth, reverse)
return theString as String
}
}
// MARK: - Check whether current date is the given date. // MARK: - Check whether current date is the given date.
public extension Date { public extension Date {

View File

@ -6,6 +6,7 @@
// 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.
import SwiftExtension
import SwiftUI import SwiftUI
// MARK: - Add "didChange" support to bindings. // MARK: - Add "didChange" support to bindings.

View File

@ -10,6 +10,7 @@ import AppKit
import Combine import Combine
import Foundation import Foundation
import LangModelAssembly import LangModelAssembly
import OSFrameworkImpl
import Shared import Shared
import SwiftExtension import SwiftExtension
import SwiftUI import SwiftUI

View File

@ -1,9 +0,0 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

View File

@ -1,22 +0,0 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "PinyinPhonaConverter",
platforms: [
.macOS(.v11),
],
products: [
.library(
name: "PinyinPhonaConverter",
targets: ["PinyinPhonaConverter"]
),
],
dependencies: [],
targets: [
.target(
name: "PinyinPhonaConverter",
dependencies: []
),
]
)

View File

@ -1,13 +0,0 @@
# PinyinPhonaConverter
拼音轉注音模組。因為太耽誤編譯時間,所以單獨拿出來寫了一個給 LangModelAssembly 專用的版本。
```
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
```

View File

@ -1,92 +0,0 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import AppKit
public extension String {
mutating func convertToPhonabets(newToneOne: String = "") {
if isEmpty || contains("_") || !isNotPureAlphanumerical { return }
for key in arrHanyuPinyinToPhonabets {
self = replacingOccurrences(of: key.0, with: key.1)
}
self = replacingOccurrences(of: " ", with: newToneOne)
}
}
///
private extension String {
var isNotPureAlphanumerical: Bool {
let regex = ".*[^A-Za-z0-9].*"
let testString = NSPredicate(format: "SELF MATCHES %@", regex)
return testString.evaluate(with: self)
}
}
private let arrHanyuPinyinToPhonabets: [(String, String)] = [
("chuang", "ㄔㄨㄤ"), ("shuang", "ㄕㄨㄤ"), ("zhuang", "ㄓㄨㄤ"), ("chang", "ㄔㄤ"), ("cheng", "ㄔㄥ"), ("chong", "ㄔㄨㄥ"),
("chuai", "ㄔㄨㄞ"), ("chuan", "ㄔㄨㄢ"), ("guang", "ㄍㄨㄤ"), ("huang", "ㄏㄨㄤ"), ("jiang", "ㄐㄧㄤ"), ("jiong", "ㄐㄩㄥ"),
("kiang", "ㄎㄧㄤ"), ("kuang", "ㄎㄨㄤ"), ("biang", "ㄅㄧㄤ"), ("duang", "ㄉㄨㄤ"), ("liang", "ㄌㄧㄤ"), ("niang", "ㄋㄧㄤ"),
("qiang", "ㄑㄧㄤ"), ("qiong", "ㄑㄩㄥ"), ("shang", "ㄕㄤ"), ("sheng", "ㄕㄥ"), ("shuai", "ㄕㄨㄞ"), ("shuan", "ㄕㄨㄢ"),
("xiang", "ㄒㄧㄤ"), ("xiong", "ㄒㄩㄥ"), ("zhang", "ㄓㄤ"), ("zheng", "ㄓㄥ"), ("zhong", "ㄓㄨㄥ"), ("zhuai", "ㄓㄨㄞ"),
("zhuan", "ㄓㄨㄢ"), ("bang", "ㄅㄤ"), ("beng", "ㄅㄥ"), ("bian", "ㄅㄧㄢ"), ("biao", "ㄅㄧㄠ"), ("bing", "ㄅㄧㄥ"), ("cang", "ㄘㄤ"),
("ceng", "ㄘㄥ"), ("chai", "ㄔㄞ"), ("chan", "ㄔㄢ"), ("chao", "ㄔㄠ"), ("chen", "ㄔㄣ"), ("chou", "ㄔㄡ"), ("chua", "ㄔㄨㄚ"),
("chui", "ㄔㄨㄟ"), ("chun", "ㄔㄨㄣ"), ("chuo", "ㄔㄨㄛ"), ("cong", "ㄘㄨㄥ"), ("cuan", "ㄘㄨㄢ"), ("dang", "ㄉㄤ"), ("deng", "ㄉㄥ"),
("dian", "ㄉㄧㄢ"), ("diao", "ㄉㄧㄠ"), ("ding", "ㄉㄧㄥ"), ("dong", "ㄉㄨㄥ"), ("duan", "ㄉㄨㄢ"), ("fang", "ㄈㄤ"), ("feng", "ㄈㄥ"),
("fiao", "ㄈㄧㄠ"), ("fong", "ㄈㄨㄥ"), ("gang", "ㄍㄤ"), ("geng", "ㄍㄥ"), ("giao", "ㄍㄧㄠ"), ("gong", "ㄍㄨㄥ"), ("guai", "ㄍㄨㄞ"),
("guan", "ㄍㄨㄢ"), ("hang", "ㄏㄤ"), ("heng", "ㄏㄥ"), ("hong", "ㄏㄨㄥ"), ("huai", "ㄏㄨㄞ"), ("huan", "ㄏㄨㄢ"), ("jian", "ㄐㄧㄢ"),
("jiao", "ㄐㄧㄠ"), ("jing", "ㄐㄧㄥ"), ("juan", "ㄐㄩㄢ"), ("kang", "ㄎㄤ"), ("keng", "ㄎㄥ"), ("kong", "ㄎㄨㄥ"), ("kuai", "ㄎㄨㄞ"),
("kuan", "ㄎㄨㄢ"), ("lang", "ㄌㄤ"), ("leng", "ㄌㄥ"), ("lian", "ㄌㄧㄢ"), ("liao", "ㄌㄧㄠ"), ("ling", "ㄌㄧㄥ"), ("long", "ㄌㄨㄥ"),
("luan", "ㄌㄨㄢ"), ("lvan", "ㄌㄩㄢ"), ("mang", "ㄇㄤ"), ("meng", "ㄇㄥ"), ("mian", "ㄇㄧㄢ"), ("miao", "ㄇㄧㄠ"), ("ming", "ㄇㄧㄥ"),
("nang", "ㄋㄤ"), ("neng", "ㄋㄥ"), ("nian", "ㄋㄧㄢ"), ("niao", "ㄋㄧㄠ"), ("ning", "ㄋㄧㄥ"), ("nong", "ㄋㄨㄥ"), ("nuan", "ㄋㄨㄢ"),
("pang", "ㄆㄤ"), ("peng", "ㄆㄥ"), ("pian", "ㄆㄧㄢ"), ("piao", "ㄆㄧㄠ"), ("ping", "ㄆㄧㄥ"), ("qian", "ㄑㄧㄢ"), ("qiao", "ㄑㄧㄠ"),
("qing", "ㄑㄧㄥ"), ("quan", "ㄑㄩㄢ"), ("rang", "ㄖㄤ"), ("reng", "ㄖㄥ"), ("rong", "ㄖㄨㄥ"), ("ruan", "ㄖㄨㄢ"), ("sang", "ㄙㄤ"),
("seng", "ㄙㄥ"), ("shai", "ㄕㄞ"), ("shan", "ㄕㄢ"), ("shao", "ㄕㄠ"), ("shei", "ㄕㄟ"), ("shen", "ㄕㄣ"), ("shou", "ㄕㄡ"),
("shua", "ㄕㄨㄚ"), ("shui", "ㄕㄨㄟ"), ("shun", "ㄕㄨㄣ"), ("shuo", "ㄕㄨㄛ"), ("song", "ㄙㄨㄥ"), ("suan", "ㄙㄨㄢ"), ("tang", "ㄊㄤ"),
("teng", "ㄊㄥ"), ("tian", "ㄊㄧㄢ"), ("tiao", "ㄊㄧㄠ"), ("ting", "ㄊㄧㄥ"), ("tong", "ㄊㄨㄥ"), ("tuan", "ㄊㄨㄢ"), ("wang", "ㄨㄤ"),
("weng", "ㄨㄥ"), ("xian", "ㄒㄧㄢ"), ("xiao", "ㄒㄧㄠ"), ("xing", "ㄒㄧㄥ"), ("xuan", "ㄒㄩㄢ"), ("yang", "ㄧㄤ"), ("ying", "ㄧㄥ"),
("yong", "ㄩㄥ"), ("yuan", "ㄩㄢ"), ("zang", "ㄗㄤ"), ("zeng", "ㄗㄥ"), ("zhai", "ㄓㄞ"), ("zhan", "ㄓㄢ"), ("zhao", "ㄓㄠ"),
("zhei", "ㄓㄟ"), ("zhen", "ㄓㄣ"), ("zhou", "ㄓㄡ"), ("zhua", "ㄓㄨㄚ"), ("zhui", "ㄓㄨㄟ"), ("zhun", "ㄓㄨㄣ"), ("zhuo", "ㄓㄨㄛ"),
("zong", "ㄗㄨㄥ"), ("zuan", "ㄗㄨㄢ"), ("jun", "ㄐㄩㄣ"), ("ang", ""), ("bai", "ㄅㄞ"), ("ban", "ㄅㄢ"), ("bao", "ㄅㄠ"),
("bei", "ㄅㄟ"), ("ben", "ㄅㄣ"), ("bie", "ㄅㄧㄝ"), ("bin", "ㄅㄧㄣ"), ("cai", "ㄘㄞ"), ("can", "ㄘㄢ"), ("cao", "ㄘㄠ"),
("cei", "ㄘㄟ"), ("cen", "ㄘㄣ"), ("cha", "ㄔㄚ"), ("che", "ㄔㄜ"), ("chi", ""), ("chu", "ㄔㄨ"), ("cou", "ㄘㄡ"),
("cui", "ㄘㄨㄟ"), ("cun", "ㄘㄨㄣ"), ("cuo", "ㄘㄨㄛ"), ("dai", "ㄉㄞ"), ("dan", "ㄉㄢ"), ("dao", "ㄉㄠ"), ("dei", "ㄉㄟ"),
("den", "ㄉㄣ"), ("dia", "ㄉㄧㄚ"), ("die", "ㄉㄧㄝ"), ("diu", "ㄉㄧㄡ"), ("dou", "ㄉㄡ"), ("dui", "ㄉㄨㄟ"), ("dun", "ㄉㄨㄣ"),
("duo", "ㄉㄨㄛ"), ("eng", ""), ("fan", "ㄈㄢ"), ("fei", "ㄈㄟ"), ("fen", "ㄈㄣ"), ("fou", "ㄈㄡ"), ("gai", "ㄍㄞ"),
("gan", "ㄍㄢ"), ("gao", "ㄍㄠ"), ("gei", "ㄍㄟ"), ("gin", "ㄍㄧㄣ"), ("gen", "ㄍㄣ"), ("gou", "ㄍㄡ"), ("gua", "ㄍㄨㄚ"),
("gue", "ㄍㄨㄜ"), ("gui", "ㄍㄨㄟ"), ("gun", "ㄍㄨㄣ"), ("guo", "ㄍㄨㄛ"), ("hai", "ㄏㄞ"), ("han", "ㄏㄢ"), ("hao", "ㄏㄠ"),
("hei", "ㄏㄟ"), ("hen", "ㄏㄣ"), ("hou", "ㄏㄡ"), ("hua", "ㄏㄨㄚ"), ("hui", "ㄏㄨㄟ"), ("hun", "ㄏㄨㄣ"), ("huo", "ㄏㄨㄛ"),
("jia", "ㄐㄧㄚ"), ("jie", "ㄐㄧㄝ"), ("jin", "ㄐㄧㄣ"), ("jiu", "ㄐㄧㄡ"), ("jue", "ㄐㄩㄝ"), ("kai", "ㄎㄞ"), ("kan", "ㄎㄢ"),
("kao", "ㄎㄠ"), ("ken", "ㄎㄣ"), ("kiu", "ㄎㄧㄡ"), ("kou", "ㄎㄡ"), ("kua", "ㄎㄨㄚ"), ("kui", "ㄎㄨㄟ"), ("kun", "ㄎㄨㄣ"),
("kuo", "ㄎㄨㄛ"), ("lai", "ㄌㄞ"), ("lan", "ㄌㄢ"), ("lao", "ㄌㄠ"), ("lei", "ㄌㄟ"), ("lia", "ㄌㄧㄚ"), ("lie", "ㄌㄧㄝ"),
("lin", "ㄌㄧㄣ"), ("liu", "ㄌㄧㄡ"), ("lou", "ㄌㄡ"), ("lun", "ㄌㄨㄣ"), ("luo", "ㄌㄨㄛ"), ("lve", "ㄌㄩㄝ"), ("mai", "ㄇㄞ"),
("man", "ㄇㄢ"), ("mao", "ㄇㄠ"), ("mei", "ㄇㄟ"), ("men", "ㄇㄣ"), ("mie", "ㄇㄧㄝ"), ("min", "ㄇㄧㄣ"), ("miu", "ㄇㄧㄡ"),
("mou", "ㄇㄡ"), ("nai", "ㄋㄞ"), ("nan", "ㄋㄢ"), ("nao", "ㄋㄠ"), ("nei", "ㄋㄟ"), ("nen", "ㄋㄣ"), ("nie", "ㄋㄧㄝ"),
("nin", "ㄋㄧㄣ"), ("niu", "ㄋㄧㄡ"), ("nou", "ㄋㄡ"), ("nui", "ㄋㄨㄟ"), ("nun", "ㄋㄨㄣ"), ("nuo", "ㄋㄨㄛ"), ("nve", "ㄋㄩㄝ"),
("pai", "ㄆㄞ"), ("pan", "ㄆㄢ"), ("pao", "ㄆㄠ"), ("pei", "ㄆㄟ"), ("pen", "ㄆㄣ"), ("pia", "ㄆㄧㄚ"), ("pie", "ㄆㄧㄝ"),
("pin", "ㄆㄧㄣ"), ("pou", "ㄆㄡ"), ("qia", "ㄑㄧㄚ"), ("qie", "ㄑㄧㄝ"), ("qin", "ㄑㄧㄣ"), ("qiu", "ㄑㄧㄡ"), ("que", "ㄑㄩㄝ"),
("qun", "ㄑㄩㄣ"), ("ran", "ㄖㄢ"), ("rao", "ㄖㄠ"), ("ren", "ㄖㄣ"), ("rou", "ㄖㄡ"), ("rui", "ㄖㄨㄟ"), ("run", "ㄖㄨㄣ"),
("ruo", "ㄖㄨㄛ"), ("sai", "ㄙㄞ"), ("san", "ㄙㄢ"), ("sao", "ㄙㄠ"), ("sei", "ㄙㄟ"), ("sen", "ㄙㄣ"), ("sha", "ㄕㄚ"),
("she", "ㄕㄜ"), ("shi", ""), ("shu", "ㄕㄨ"), ("sou", "ㄙㄡ"), ("sui", "ㄙㄨㄟ"), ("sun", "ㄙㄨㄣ"), ("suo", "ㄙㄨㄛ"),
("tai", "ㄊㄞ"), ("tan", "ㄊㄢ"), ("tao", "ㄊㄠ"), ("tie", "ㄊㄧㄝ"), ("tou", "ㄊㄡ"), ("tui", "ㄊㄨㄟ"), ("tun", "ㄊㄨㄣ"),
("tuo", "ㄊㄨㄛ"), ("wai", "ㄨㄞ"), ("wan", "ㄨㄢ"), ("wei", "ㄨㄟ"), ("wen", "ㄨㄣ"), ("xia", "ㄒㄧㄚ"), ("xie", "ㄒㄧㄝ"),
("xin", "ㄒㄧㄣ"), ("xiu", "ㄒㄧㄡ"), ("xue", "ㄒㄩㄝ"), ("xun", "ㄒㄩㄣ"), ("yai", "ㄧㄞ"), ("yan", "ㄧㄢ"), ("yao", "ㄧㄠ"),
("yin", "ㄧㄣ"), ("you", "ㄧㄡ"), ("yue", "ㄩㄝ"), ("yun", "ㄩㄣ"), ("zai", "ㄗㄞ"), ("zan", "ㄗㄢ"), ("zao", "ㄗㄠ"),
("zei", "ㄗㄟ"), ("zen", "ㄗㄣ"), ("zha", "ㄓㄚ"), ("zhe", "ㄓㄜ"), ("zhi", ""), ("zhu", "ㄓㄨ"), ("zou", "ㄗㄡ"),
("zui", "ㄗㄨㄟ"), ("zun", "ㄗㄨㄣ"), ("zuo", "ㄗㄨㄛ"), ("ai", ""), ("an", ""), ("ao", ""), ("ba", "ㄅㄚ"), ("bi", "ㄅㄧ"),
("bo", "ㄅㄛ"), ("bu", "ㄅㄨ"), ("ca", "ㄘㄚ"), ("ce", "ㄘㄜ"), ("ci", ""), ("cu", "ㄘㄨ"), ("da", "ㄉㄚ"), ("de", "ㄉㄜ"),
("di", "ㄉㄧ"), ("du", "ㄉㄨ"), ("eh", ""), ("ei", ""), ("en", ""), ("er", ""), ("fa", "ㄈㄚ"), ("fo", "ㄈㄛ"),
("fu", "ㄈㄨ"), ("ga", "ㄍㄚ"), ("ge", "ㄍㄜ"), ("gi", "ㄍㄧ"), ("gu", "ㄍㄨ"), ("ha", "ㄏㄚ"), ("he", "ㄏㄜ"), ("hu", "ㄏㄨ"),
("ji", "ㄐㄧ"), ("ju", "ㄐㄩ"), ("ka", "ㄎㄚ"), ("ke", "ㄎㄜ"), ("ku", "ㄎㄨ"), ("la", "ㄌㄚ"), ("le", "ㄌㄜ"), ("li", "ㄌㄧ"),
("lo", "ㄌㄛ"), ("lu", "ㄌㄨ"), ("lv", "ㄌㄩ"), ("ma", "ㄇㄚ"), ("me", "ㄇㄜ"), ("mi", "ㄇㄧ"), ("mo", "ㄇㄛ"), ("mu", "ㄇㄨ"),
("na", "ㄋㄚ"), ("ne", "ㄋㄜ"), ("ni", "ㄋㄧ"), ("nu", "ㄋㄨ"), ("nv", "ㄋㄩ"), ("ou", ""), ("pa", "ㄆㄚ"), ("pi", "ㄆㄧ"),
("po", "ㄆㄛ"), ("pu", "ㄆㄨ"), ("qi", "ㄑㄧ"), ("qu", "ㄑㄩ"), ("re", "ㄖㄜ"), ("ri", ""), ("ru", "ㄖㄨ"), ("sa", "ㄙㄚ"),
("se", "ㄙㄜ"), ("si", ""), ("su", "ㄙㄨ"), ("ta", "ㄊㄚ"), ("te", "ㄊㄜ"), ("ti", "ㄊㄧ"), ("tu", "ㄊㄨ"), ("wa", "ㄨㄚ"),
("wo", "ㄨㄛ"), ("wu", ""), ("xi", "ㄒㄧ"), ("xu", "ㄒㄩ"), ("ya", "ㄧㄚ"), ("ye", "ㄧㄝ"), ("yi", ""), ("yo", "ㄧㄛ"),
("yu", ""), ("za", "ㄗㄚ"), ("ze", "ㄗㄜ"), ("zi", ""), ("zu", "ㄗㄨ"), ("a", ""), ("e", ""), ("o", ""), ("q", ""),
("1", " "), ("2", "ˊ"), ("3", "ˇ"), ("4", "ˋ"), ("5", "˙"),
]

View File

@ -13,7 +13,7 @@ let package = Package(
), ),
], ],
dependencies: [ dependencies: [
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
.package(path: "../vChewing_IMKUtils"), .package(path: "../vChewing_IMKUtils"),
.package(path: "../vChewing_SwiftExtension"), .package(path: "../vChewing_SwiftExtension"),
], ],
@ -21,7 +21,7 @@ let package = Package(
.target( .target(
name: "Shared", name: "Shared",
dependencies: [ dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
.product(name: "IMKUtils", package: "vChewing_IMKUtils"), .product(name: "IMKUtils", package: "vChewing_IMKUtils"),
.product(name: "SwiftExtension", package: "vChewing_SwiftExtension"), .product(name: "SwiftExtension", package: "vChewing_SwiftExtension"),
] ]

View File

@ -8,7 +8,7 @@
// 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.
import AppKit import Foundation
@objcMembers public class Broadcaster: NSObject { @objcMembers public class Broadcaster: NSObject {
public static var shared = Broadcaster() public static var shared = Broadcaster()

View File

@ -6,8 +6,6 @@
// 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.
import Foundation
open class CandidateNode { open class CandidateNode {
public var name: String public var name: String
public var members: [CandidateNode] public var members: [CandidateNode]

View File

@ -6,8 +6,6 @@
// 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.
import Foundation
public extension CandidateNode { public extension CandidateNode {
convenience init( convenience init(
name: String, services: [CandidateTextService], previous: CandidateNode? = nil name: String, services: [CandidateTextService], previous: CandidateNode? = nil

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
// MARK: - InputSignalProtocol // MARK: - InputSignalProtocol

View File

@ -9,9 +9,9 @@
// UserDefRenderable AppKit SwiftUI // UserDefRenderable AppKit SwiftUI
import AppKit import AppKit
import CocoaExtension
import Foundation import Foundation
import IMKUtils import IMKUtils
import OSFrameworkImpl
public class UserDefRenderableCocoa: NSObject, Identifiable { public class UserDefRenderableCocoa: NSObject, Identifiable {
public let def: UserDef public let def: UserDef

View File

@ -6,8 +6,6 @@
// 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.
import Foundation
// MARK: - Bool Operators // MARK: - Bool Operators
public func |= (lhs: inout Bool, rhs: Bool) { public func |= (lhs: inout Bool, rhs: Bool) {
@ -22,25 +20,11 @@ public func ^= (lhs: inout Bool, rhs: Bool) {
lhs = lhs != rhs lhs = lhs != rhs
} }
// MARK: - String.localized extension // MARK: - Root Extensions (deduplicated)
public extension StringLiteralType {
var localized: String { NSLocalizedString(description, comment: "") }
}
// MARK: - Root Extensions
// Extend the RangeReplaceableCollection to allow it clean duplicated characters. // Extend the RangeReplaceableCollection to allow it clean duplicated characters.
// Ref: https://stackoverflow.com/questions/25738817/ // Ref: https://stackoverflow.com/questions/25738817/
public extension RangeReplaceableCollection where Element: Hashable { public extension RangeReplaceableCollection where Element: Hashable {
/// 使 NSOrderedSet class
var classDeduplicated: Self {
NSOrderedSet(array: Array(self)).compactMap { $0 as? Element.Type } as? Self ?? self
// Bug KeyValuePaired
// var set = Set<Element>()
// return filter { set.insert($0).inserted }
}
/// ///
/// - Remark: class class Identifiable /// - Remark: class class Identifiable
var deduplicated: Self { var deduplicated: Self {
@ -49,22 +33,6 @@ public extension RangeReplaceableCollection where Element: Hashable {
} }
} }
// MARK: - String Tildes Expansion Extension
public extension String {
var expandingTildeInPath: String {
(self as NSString).expandingTildeInPath
}
}
// MARK: - String Localized Error Extension
extension String: LocalizedError {
public var errorDescription: String? {
self
}
}
// MARK: - Ensuring trailing slash of a string // MARK: - Ensuring trailing slash of a string
public extension String { public extension String {
@ -77,21 +45,6 @@ public extension String {
// MARK: - CharCode printability check // MARK: - CharCode printability check
// Ref: https://forums.swift.org/t/57085/5
public extension UniChar {
var isPrintable: Bool {
guard Unicode.Scalar(UInt32(self)) != nil else {
struct NotAWholeScalar: Error {}
return false
}
return true
}
var isPrintableASCII: Bool {
(32 ... 126).contains(self)
}
}
public extension Unicode.Scalar { public extension Unicode.Scalar {
var isPrintableASCII: Bool { var isPrintableASCII: Bool {
(32 ... 126).contains(value) (32 ... 126).contains(value)
@ -133,70 +86,23 @@ public extension Bool {
} }
} }
// MARK: - User Defaults Storage
public extension UserDefaults {
//
static var pendingUnitTests = false
static var unitTests = UserDefaults(suiteName: "UnitTests")
static var current: UserDefaults {
pendingUnitTests ? .unitTests ?? .standard : .standard
}
}
// MARK: - Property Wrapper
// Ref: https://www.avanderlee.com/swift/property-wrappers/
@propertyWrapper
public struct AppProperty<Value> {
public let key: String
public let defaultValue: Value
public var container: UserDefaults { .current }
public init(key: String, defaultValue: Value) {
self.key = key
self.defaultValue = defaultValue
if container.object(forKey: key) == nil {
container.set(defaultValue, forKey: key)
}
}
public var wrappedValue: Value {
get {
container.object(forKey: key) as? Value ?? defaultValue
}
set {
container.set(newValue, forKey: key)
}
}
}
// MARK: - // MARK: -
// Ref: https://stackoverflow.com/a/32581409/4162914 // Ref: https://stackoverflow.com/a/32581409/4162914
public extension Double { public extension Double {
func rounded(toPlaces places: Int) -> Double { func rounded(toPlaces places: Int) -> Double {
let divisor = pow(10.0, Double(places)) let divisor = 10.0.mathPowered(by: places)
return (self * divisor).rounded() / divisor return (self * divisor).rounded() / divisor
} }
} }
// MARK: - String RegReplace Extension public extension Double {
func mathPowered(by operand: Int) -> Double {
// Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914 var target = self
public extension String { for _ in 0 ..< operand {
mutating func regReplace(pattern: String, replaceWith: String = "") { target = target * target
do { }
let regex = try NSRegularExpression( return target
pattern: pattern, options: [.caseInsensitive, .anchorsMatchLines]
)
let range = NSRange(startIndex..., in: self)
self = regex.stringByReplacingMatches(
in: self, options: [], range: range, withTemplate: replaceWith
)
} catch { return }
} }
} }
@ -236,26 +142,6 @@ public extension String {
var withEllipsis: String { self + "" } var withEllipsis: String { self + "" }
} }
// MARK: - Localized String Extension for Integers and Floats
public extension BinaryFloatingPoint {
func i18n(loc: String) -> String {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: loc)
formatter.numberStyle = .spellOut
return formatter.string(from: NSDecimalNumber(string: "\(self)")) ?? ""
}
}
public extension BinaryInteger {
func i18n(loc: String) -> String {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: loc)
formatter.numberStyle = .spellOut
return formatter.string(from: NSDecimalNumber(string: "\(self)")) ?? ""
}
}
// MARK: - Index Revolver (only for Array) // MARK: - Index Revolver (only for Array)
// Further discussion: https://forums.swift.org/t/62847 // Further discussion: https://forums.swift.org/t/62847
@ -283,31 +169,6 @@ public extension Int {
} }
} }
// MARK: - Parse String As Hex Literal
// Original author: Shiki Suen
// Refactored by: Isaac Xen
public extension String {
func parsedAsHexLiteral(encoding: CFStringEncodings? = nil) -> String? {
guard !isEmpty else { return nil }
var charBytes = [Int8]()
var buffer: Int?
compactMap(\.hexDigitValue).forEach { neta in
if let validBuffer = buffer {
charBytes.append(.init(bitPattern: UInt8(validBuffer << 4 + neta)))
buffer = nil
} else {
buffer = neta
}
}
let encodingUBE = CFStringBuiltInEncodings.UTF16BE.rawValue
let encodingRAW = encoding.map { UInt32($0.rawValue) } ?? encodingUBE
let result = CFStringCreateWithCString(nil, &charBytes, encodingRAW) as String?
return result?.isEmpty ?? true ? nil : result
}
}
// MARK: - Overlap Checker (for two sets) // MARK: - Overlap Checker (for two sets)
public extension Set where Element: Hashable { public extension Set where Element: Hashable {
@ -340,32 +201,6 @@ public extension Array where Element: Hashable {
} }
} }
// MARK: - Version Comparer.
public extension String {
/// ref: https://sarunw.com/posts/how-to-compare-two-app-version-strings-in-swift/
func versionCompare(_ otherVersion: String) -> ComparisonResult {
let versionDelimiter = "."
var versionComponents = components(separatedBy: versionDelimiter) // <1>
var otherVersionComponents = otherVersion.components(separatedBy: versionDelimiter)
let zeroDiff = versionComponents.count - otherVersionComponents.count // <2>
// <3> Compare normally if the formats are the same.
guard zeroDiff != 0 else { return compare(otherVersion, options: .numeric) }
let zeros = Array(repeating: "0", count: abs(zeroDiff)) // <4>
if zeroDiff > 0 {
otherVersionComponents.append(contentsOf: zeros) // <5>
} else {
versionComponents.append(contentsOf: zeros)
}
return versionComponents.joined(separator: versionDelimiter)
.compare(otherVersionComponents.joined(separator: versionDelimiter), options: .numeric) // <6>
}
}
// MARK: - Array Builder. // MARK: - Array Builder.
@resultBuilder @resultBuilder
@ -419,3 +254,33 @@ public extension Comparable {
return givenMap[returnableID] return givenMap[returnableID]
} }
} }
// MARK: - String.applyingTransform
public extension String {
/// This only works with ASCII chars for now.
func applyingTransformFW2HW(reverse: Bool) -> String {
var arr: [Character] = map { $0 }
for i in 0 ..< arr.count {
let oldChar = arr[i]
guard oldChar.unicodeScalars.count == 1 else { continue }
guard let oldCodePoint = oldChar.unicodeScalars.first?.value else { continue }
if reverse {
guard oldChar.isASCII else { continue }
} else {
guard oldCodePoint > 0xFEE0 || oldCodePoint == 0x3000 else { continue }
}
var newCodePoint: Int32 = reverse ? (Int32(oldCodePoint) + 0xFEE0) : (Int32(oldCodePoint) - 0xFEE0)
checkSpace: switch (oldCodePoint, reverse) {
case (0x3000, false): newCodePoint = 0x20
case (0x20, true): newCodePoint = 0x3000
default: break checkSpace
}
guard newCodePoint > 0 else { continue }
guard let newScalar = Unicode.Scalar(UInt16(newCodePoint)) else { continue }
let newChar = Character(newScalar)
arr[i] = newChar
}
return String(arr)
}
}

View File

@ -0,0 +1,190 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Foundation
// MARK: - String.localized extension
public extension StringLiteralType {
var localized: String { NSLocalizedString(description, comment: "") }
}
// MARK: - Root Extensions (classDeduplicated)
// Extend the RangeReplaceableCollection to allow it clean duplicated characters.
// Ref: https://stackoverflow.com/questions/25738817/
public extension RangeReplaceableCollection where Element: Hashable {
/// 使 NSOrderedSet class
var classDeduplicated: Self {
NSOrderedSet(array: Array(self)).compactMap { $0 as? Element.Type } as? Self ?? self
// Bug KeyValuePaired
// var set = Set<Element>()
// return filter { set.insert($0).inserted }
}
}
// MARK: - String Tildes Expansion Extension
public extension String {
var expandingTildeInPath: String {
(self as NSString).expandingTildeInPath
}
}
// MARK: - String Localized Error Extension
extension String: LocalizedError {
public var errorDescription: String? {
self
}
}
// MARK: - CharCode printability check for UniChar (CoreFoundation)
// Ref: https://forums.swift.org/t/57085/5
public extension UniChar {
var isPrintable: Bool {
guard Unicode.Scalar(UInt32(self)) != nil else {
struct NotAWholeScalar: Error {}
return false
}
return true
}
var isPrintableASCII: Bool {
(32 ... 126).contains(self)
}
}
// MARK: - User Defaults Storage
public extension UserDefaults {
//
static var pendingUnitTests = false
static var unitTests = UserDefaults(suiteName: "UnitTests")
static var current: UserDefaults {
pendingUnitTests ? .unitTests ?? .standard : .standard
}
}
// MARK: - Property Wrapper
// Ref: https://www.avanderlee.com/swift/property-wrappers/
@propertyWrapper
public struct AppProperty<Value> {
public let key: String
public let defaultValue: Value
public var container: UserDefaults { .current }
public init(key: String, defaultValue: Value) {
self.key = key
self.defaultValue = defaultValue
if container.object(forKey: key) == nil {
container.set(defaultValue, forKey: key)
}
}
public var wrappedValue: Value {
get {
container.object(forKey: key) as? Value ?? defaultValue
}
set {
container.set(newValue, forKey: key)
}
}
}
// MARK: - String RegReplace Extension
// Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914
public extension String {
mutating func regReplace(pattern: String, replaceWith: String = "") {
do {
let regex = try NSRegularExpression(
pattern: pattern, options: [.caseInsensitive, .anchorsMatchLines]
)
let range = NSRange(startIndex..., in: self)
self = regex.stringByReplacingMatches(
in: self, options: [], range: range, withTemplate: replaceWith
)
} catch { return }
}
}
// MARK: - Localized String Extension for Integers and Floats
public extension BinaryFloatingPoint {
func i18n(loc: String) -> String {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: loc)
formatter.numberStyle = .spellOut
return formatter.string(from: NSDecimalNumber(string: "\(self)")) ?? ""
}
}
public extension BinaryInteger {
func i18n(loc: String) -> String {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: loc)
formatter.numberStyle = .spellOut
return formatter.string(from: NSDecimalNumber(string: "\(self)")) ?? ""
}
}
// MARK: - Parse String As Hex Literal
// Original author: Shiki Suen
// Refactored by: Isaac Xen
public extension String {
func parsedAsHexLiteral(encoding: CFStringEncodings? = nil) -> String? {
guard !isEmpty else { return nil }
var charBytes = [Int8]()
var buffer: Int?
compactMap(\.hexDigitValue).forEach { neta in
if let validBuffer = buffer {
charBytes.append(.init(bitPattern: UInt8(validBuffer << 4 + neta)))
buffer = nil
} else {
buffer = neta
}
}
let encodingUBE = CFStringBuiltInEncodings.UTF16BE.rawValue
let encodingRAW = encoding.map { UInt32($0.rawValue) } ?? encodingUBE
let result = CFStringCreateWithCString(nil, &charBytes, encodingRAW) as String?
return result?.isEmpty ?? true ? nil : result
}
}
// MARK: - Version Comparer.
public extension String {
/// ref: https://sarunw.com/posts/how-to-compare-two-app-version-strings-in-swift/
func versionCompare(_ otherVersion: String) -> ComparisonResult {
let versionDelimiter = "."
var versionComponents = components(separatedBy: versionDelimiter) // <1>
var otherVersionComponents = otherVersion.components(separatedBy: versionDelimiter)
let zeroDiff = versionComponents.count - otherVersionComponents.count // <2>
// <3> Compare normally if the formats are the same.
guard zeroDiff != 0 else { return compare(otherVersion, options: .numeric) }
let zeros = Array(repeating: "0", count: abs(zeroDiff)) // <4>
if zeroDiff > 0 {
otherVersionComponents.append(contentsOf: zeros) // <5>
} else {
versionComponents.append(contentsOf: zeros)
}
return versionComponents.joined(separator: versionDelimiter)
.compare(otherVersionComponents.joined(separator: versionDelimiter), options: .numeric) // <6>
}
}

View File

@ -14,7 +14,7 @@ let package = Package(
], ],
dependencies: [ dependencies: [
.package(path: "../Fuziki_NSAttributedTextView"), .package(path: "../Fuziki_NSAttributedTextView"),
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
.package(path: "../vChewing_Shared"), .package(path: "../vChewing_Shared"),
], ],
targets: [ targets: [
@ -22,7 +22,7 @@ let package = Package(
name: "TooltipUI", name: "TooltipUI",
dependencies: [ dependencies: [
.product(name: "NSAttributedTextView", package: "Fuziki_NSAttributedTextView"), .product(name: "NSAttributedTextView", package: "Fuziki_NSAttributedTextView"),
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
.product(name: "Shared", package: "vChewing_Shared"), .product(name: "Shared", package: "vChewing_Shared"),
] ]
), ),

View File

@ -7,8 +7,8 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension
import NSAttributedTextView import NSAttributedTextView
import OSFrameworkImpl
import Shared import Shared
public class TooltipUI_LateCocoa: NSWindowController, TooltipUIProtocol { public class TooltipUI_LateCocoa: NSWindowController, TooltipUIProtocol {

View File

@ -13,13 +13,13 @@ let package = Package(
), ),
], ],
dependencies: [ dependencies: [
.package(path: "../vChewing_CocoaExtension"), .package(path: "../vChewing_OSFrameworkImpl"),
], ],
targets: [ targets: [
.target( .target(
name: "Uninstaller", name: "Uninstaller",
dependencies: [ dependencies: [
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), .product(name: "OSFrameworkImpl", package: "vChewing_OSFrameworkImpl"),
] ]
), ),
] ]

View File

@ -7,7 +7,7 @@
// requirements defined in MIT License. // requirements defined in MIT License.
import AppKit import AppKit
import CocoaExtension import OSFrameworkImpl
public enum Uninstaller { public enum Uninstaller {
// MARK: - Uninstall the input method. // MARK: - Uninstall the input method.

View File

@ -26,9 +26,8 @@
5B70F4EC2A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5B70F4E82A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png */; }; 5B70F4EC2A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5B70F4E82A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png */; };
5B765F09293A253C00122315 /* PhraseEditorUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5B765F08293A253C00122315 /* PhraseEditorUI */; }; 5B765F09293A253C00122315 /* PhraseEditorUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5B765F08293A253C00122315 /* PhraseEditorUI */; };
5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */; }; 5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5B7DA80228BF6BBA00D7B2AD /* fixinstall.sh */; };
5B963C9D28D5BFB800DCEE88 /* CocoaExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963C9C28D5BFB800DCEE88 /* CocoaExtension */; }; 5B963C9D28D5BFB800DCEE88 /* OSFrameworkImpl in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963C9C28D5BFB800DCEE88 /* OSFrameworkImpl */; };
5B963CA328D5C23600DCEE88 /* SwiftExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963CA228D5C23600DCEE88 /* SwiftExtension */; }; 5B963CA328D5C23600DCEE88 /* SwiftExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 5B963CA228D5C23600DCEE88 /* SwiftExtension */; };
5B98114828D6198700CBC605 /* PinyinPhonaConverter in Frameworks */ = {isa = PBXBuildFile; productRef = 5B98114728D6198700CBC605 /* PinyinPhonaConverter */; };
5BA8C30328DF0360004C5CC4 /* CandidateWindow in Frameworks */ = {isa = PBXBuildFile; productRef = 5BA8C30228DF0360004C5CC4 /* CandidateWindow */; }; 5BA8C30328DF0360004C5CC4 /* CandidateWindow in Frameworks */ = {isa = PBXBuildFile; productRef = 5BA8C30228DF0360004C5CC4 /* CandidateWindow */; };
5BAD0CD527D701F6003D127F /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; }; 5BAD0CD527D701F6003D127F /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; };
5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB75D27AED54C0023B93A /* Beep.m4a */; }; 5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB75D27AED54C0023B93A /* Beep.m4a */; };
@ -144,10 +143,8 @@
5B70F4E82A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "MenuIcon-TCVIM@2x.png"; sourceTree = "<group>"; }; 5B70F4E82A0BE900005EA8C4 /* MenuIcon-TCVIM@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "MenuIcon-TCVIM@2x.png"; sourceTree = "<group>"; };
5B765F07293A250000122315 /* vChewing_PhraseEditorUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_PhraseEditorUI; path = Packages/vChewing_PhraseEditorUI; sourceTree = "<group>"; }; 5B765F07293A250000122315 /* vChewing_PhraseEditorUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_PhraseEditorUI; path = Packages/vChewing_PhraseEditorUI; 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>"; };
5B963C9B28D5BE4100DCEE88 /* vChewing_CocoaExtension */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_CocoaExtension; path = Packages/vChewing_CocoaExtension; sourceTree = "<group>"; };
5B963C9E28D5C14600DCEE88 /* vChewing_Shared */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Shared; path = Packages/vChewing_Shared; sourceTree = "<group>"; }; 5B963C9E28D5C14600DCEE88 /* vChewing_Shared */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Shared; path = Packages/vChewing_Shared; sourceTree = "<group>"; };
5B963CA128D5C22D00DCEE88 /* vChewing_SwiftExtension */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_SwiftExtension; path = Packages/vChewing_SwiftExtension; sourceTree = "<group>"; }; 5B963CA128D5C22D00DCEE88 /* vChewing_SwiftExtension */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_SwiftExtension; path = Packages/vChewing_SwiftExtension; sourceTree = "<group>"; };
5B98114628D6198000CBC605 /* vChewing_PinyinPhonaConverter */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_PinyinPhonaConverter; path = Packages/vChewing_PinyinPhonaConverter; sourceTree = "<group>"; };
5BA8C30128DEFE4F004C5CC4 /* vChewing_CandidateWindow */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_CandidateWindow; path = Packages/vChewing_CandidateWindow; sourceTree = "<group>"; }; 5BA8C30128DEFE4F004C5CC4 /* vChewing_CandidateWindow */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_CandidateWindow; path = Packages/vChewing_CandidateWindow; sourceTree = "<group>"; };
5BAD29D12B7E1A1B0013D695 /* vChewing_KimoDataReader */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_KimoDataReader; path = Packages/vChewing_KimoDataReader; sourceTree = "<group>"; }; 5BAD29D12B7E1A1B0013D695 /* vChewing_KimoDataReader */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_KimoDataReader; path = Packages/vChewing_KimoDataReader; sourceTree = "<group>"; };
5BAD67E12ADAB62D005A4842 /* HangarRash_SwiftyCapsLockToggler */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = HangarRash_SwiftyCapsLockToggler; path = Packages/HangarRash_SwiftyCapsLockToggler; sourceTree = "<group>"; }; 5BAD67E12ADAB62D005A4842 /* HangarRash_SwiftyCapsLockToggler */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = HangarRash_SwiftyCapsLockToggler; path = Packages/HangarRash_SwiftyCapsLockToggler; sourceTree = "<group>"; };
@ -163,6 +160,7 @@
5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_NotifierUI; path = Packages/vChewing_NotifierUI; sourceTree = "<group>"; }; 5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_NotifierUI; path = Packages/vChewing_NotifierUI; sourceTree = "<group>"; };
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>"; };
5BDA45492B97588B00DFA179 /* vChewing_OSFrameworkImpl */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_OSFrameworkImpl; path = Packages/vChewing_OSFrameworkImpl; sourceTree = "<group>"; };
5BDB7A3028D47587001AC277 /* Jad_BookmarkManager */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Jad_BookmarkManager; path = Packages/Jad_BookmarkManager; sourceTree = "<group>"; }; 5BDB7A3028D47587001AC277 /* Jad_BookmarkManager */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Jad_BookmarkManager; path = Packages/Jad_BookmarkManager; sourceTree = "<group>"; };
5BDB7A3128D47587001AC277 /* DanielGalasko_FolderMonitor */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DanielGalasko_FolderMonitor; path = Packages/DanielGalasko_FolderMonitor; sourceTree = "<group>"; }; 5BDB7A3128D47587001AC277 /* DanielGalasko_FolderMonitor */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DanielGalasko_FolderMonitor; path = Packages/DanielGalasko_FolderMonitor; sourceTree = "<group>"; };
5BDB7A3228D47587001AC277 /* vChewing_Hotenka */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Hotenka; path = Packages/vChewing_Hotenka; sourceTree = "<group>"; }; 5BDB7A3228D47587001AC277 /* vChewing_Hotenka */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_Hotenka; path = Packages/vChewing_Hotenka; sourceTree = "<group>"; };
@ -229,8 +227,7 @@
5BDB7A4728D4824A001AC277 /* Tekkon in Frameworks */, 5BDB7A4728D4824A001AC277 /* Tekkon in Frameworks */,
5BDB7A3D28D4824A001AC277 /* Hotenka in Frameworks */, 5BDB7A3D28D4824A001AC277 /* Hotenka in Frameworks */,
5BDB7A3F28D4824A001AC277 /* LineReader in Frameworks */, 5BDB7A3F28D4824A001AC277 /* LineReader in Frameworks */,
5B963C9D28D5BFB800DCEE88 /* CocoaExtension in Frameworks */, 5B963C9D28D5BFB800DCEE88 /* OSFrameworkImpl in Frameworks */,
5B98114828D6198700CBC605 /* PinyinPhonaConverter in Frameworks */,
5BFC63CF28D4ACA3004A77B7 /* LangModelAssembly in Frameworks */, 5BFC63CF28D4ACA3004A77B7 /* LangModelAssembly in Frameworks */,
5BC5E02128DDEFE00094E427 /* TooltipUI in Frameworks */, 5BC5E02128DDEFE00094E427 /* TooltipUI in Frameworks */,
5B765F09293A253C00122315 /* PhraseEditorUI in Frameworks */, 5B765F09293A253C00122315 /* PhraseEditorUI in Frameworks */,
@ -389,7 +386,6 @@
5BDB7A3528D47587001AC277 /* RMJay_LineReader */, 5BDB7A3528D47587001AC277 /* RMJay_LineReader */,
5B6CA6272B8A1C9200A85050 /* vChewing_BrailleSputnik */, 5B6CA6272B8A1C9200A85050 /* vChewing_BrailleSputnik */,
5BA8C30128DEFE4F004C5CC4 /* vChewing_CandidateWindow */, 5BA8C30128DEFE4F004C5CC4 /* vChewing_CandidateWindow */,
5B963C9B28D5BE4100DCEE88 /* vChewing_CocoaExtension */,
5BDB7A3228D47587001AC277 /* vChewing_Hotenka */, 5BDB7A3228D47587001AC277 /* vChewing_Hotenka */,
5BFC63C728D49511004A77B7 /* vChewing_IMKUtils */, 5BFC63C728D49511004A77B7 /* vChewing_IMKUtils */,
5BAD29D12B7E1A1B0013D695 /* vChewing_KimoDataReader */, 5BAD29D12B7E1A1B0013D695 /* vChewing_KimoDataReader */,
@ -397,8 +393,8 @@
5B65FB322A9518C9007EEFB0 /* vChewing_MainAssembly */, 5B65FB322A9518C9007EEFB0 /* vChewing_MainAssembly */,
5BDB7A3328D47587001AC277 /* vChewing_Megrez */, 5BDB7A3328D47587001AC277 /* vChewing_Megrez */,
5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */, 5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */,
5BDA45492B97588B00DFA179 /* vChewing_OSFrameworkImpl */,
5B765F07293A250000122315 /* vChewing_PhraseEditorUI */, 5B765F07293A250000122315 /* vChewing_PhraseEditorUI */,
5B98114628D6198000CBC605 /* vChewing_PinyinPhonaConverter */,
5BC5E02228DE07250094E427 /* vChewing_PopupCompositionBuffer */, 5BC5E02228DE07250094E427 /* vChewing_PopupCompositionBuffer */,
5B963C9E28D5C14600DCEE88 /* vChewing_Shared */, 5B963C9E28D5C14600DCEE88 /* vChewing_Shared */,
5B963CA128D5C22D00DCEE88 /* vChewing_SwiftExtension */, 5B963CA128D5C22D00DCEE88 /* vChewing_SwiftExtension */,
@ -558,9 +554,8 @@
5BFC63C828D49754004A77B7 /* IMKUtils */, 5BFC63C828D49754004A77B7 /* IMKUtils */,
5BFC63CB28D49BBC004A77B7 /* UpdateSputnik */, 5BFC63CB28D49BBC004A77B7 /* UpdateSputnik */,
5BFC63CE28D4ACA3004A77B7 /* LangModelAssembly */, 5BFC63CE28D4ACA3004A77B7 /* LangModelAssembly */,
5B963C9C28D5BFB800DCEE88 /* CocoaExtension */, 5B963C9C28D5BFB800DCEE88 /* OSFrameworkImpl */,
5B963CA228D5C23600DCEE88 /* SwiftExtension */, 5B963CA228D5C23600DCEE88 /* SwiftExtension */,
5B98114728D6198700CBC605 /* PinyinPhonaConverter */,
5B40113828D7050D00A9D4CB /* Shared */, 5B40113828D7050D00A9D4CB /* Shared */,
5B40113B28D71C0100A9D4CB /* Uninstaller */, 5B40113B28D71C0100A9D4CB /* Uninstaller */,
5BC5E01D28DDE4770094E427 /* NotifierUI */, 5BC5E01D28DDE4770094E427 /* NotifierUI */,
@ -1377,18 +1372,14 @@
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = PhraseEditorUI; productName = PhraseEditorUI;
}; };
5B963C9C28D5BFB800DCEE88 /* CocoaExtension */ = { 5B963C9C28D5BFB800DCEE88 /* OSFrameworkImpl */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = CocoaExtension; productName = OSFrameworkImpl;
}; };
5B963CA228D5C23600DCEE88 /* SwiftExtension */ = { 5B963CA228D5C23600DCEE88 /* SwiftExtension */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = SwiftExtension; productName = SwiftExtension;
}; };
5B98114728D6198700CBC605 /* PinyinPhonaConverter */ = {
isa = XCSwiftPackageProductDependency;
productName = PinyinPhonaConverter;
};
5BA8C30228DF0360004C5CC4 /* CandidateWindow */ = { 5BA8C30228DF0360004C5CC4 /* CandidateWindow */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = CandidateWindow; productName = CandidateWindow;