Merge pull request #223 from zonble/master

Extracts preferences and emacs key detection from the input controller
This commit is contained in:
Weizhong Yang a.k.a zonble 2022-01-15 01:40:05 +08:00 committed by GitHub
commit 825ed4f122
19 changed files with 3095 additions and 318 deletions

View File

@ -47,6 +47,9 @@
D427F7B4279086DC004A2160 /* InputSourceHelper in Frameworks */ = {isa = PBXBuildFile; productRef = D427F7B3279086DC004A2160 /* InputSourceHelper */; };
D427F7B6279086F6004A2160 /* InputSourceHelper in Frameworks */ = {isa = PBXBuildFile; productRef = D427F7B5279086F6004A2160 /* InputSourceHelper */; };
D427F7C127908EFC004A2160 /* OpenCCBridge in Frameworks */ = {isa = PBXBuildFile; productRef = D427F7C027908EFC004A2160 /* OpenCCBridge */; };
D44FB74527915565003C80A6 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44FB74427915555003C80A6 /* Preferences.swift */; };
D44FB74727919D35003C80A6 /* EmacsKeyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44FB74627919C83003C80A6 /* EmacsKeyHelper.swift */; };
D44FB74A2791B829003C80A6 /* VXHanConvert in Frameworks */ = {isa = PBXBuildFile; productRef = D44FB7492791B829003C80A6 /* VXHanConvert */; };
D47F7DCE278BFB57002F9DD7 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D47F7DCD278BFB57002F9DD7 /* PreferencesWindowController.swift */; };
D47F7DD0278C0897002F9DD7 /* NonModalAlertWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D47F7DCF278C0897002F9DD7 /* NonModalAlertWindowController.swift */; };
D47F7DD3278C1263002F9DD7 /* UserOverrideModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D47F7DD2278C1263002F9DD7 /* UserOverrideModel.cpp */; };
@ -175,6 +178,9 @@
D427F7AC27907B7E004A2160 /* NotifierUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = NotifierUI; path = Packages/NotifierUI; sourceTree = "<group>"; };
D427F7B2279086B5004A2160 /* InputSourceHelper */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = InputSourceHelper; path = Packages/InputSourceHelper; sourceTree = "<group>"; };
D427F7BF27908EAC004A2160 /* OpenCCBridge */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OpenCCBridge; path = Packages/OpenCCBridge; sourceTree = "<group>"; };
D44FB74427915555003C80A6 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
D44FB74627919C83003C80A6 /* EmacsKeyHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmacsKeyHelper.swift; sourceTree = "<group>"; };
D44FB7482791B346003C80A6 /* VXHanConvert */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = VXHanConvert; path = Packages/VXHanConvert; sourceTree = "<group>"; };
D47F7DCD278BFB57002F9DD7 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = "<group>"; };
D47F7DCF278C0897002F9DD7 /* NonModalAlertWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonModalAlertWindowController.swift; sourceTree = "<group>"; };
D47F7DD1278C1263002F9DD7 /* UserOverrideModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserOverrideModel.h; sourceTree = "<group>"; };
@ -188,6 +194,7 @@
files = (
D427F7B4279086DC004A2160 /* InputSourceHelper in Frameworks */,
D427F7C127908EFC004A2160 /* OpenCCBridge in Frameworks */,
D44FB74A2791B829003C80A6 /* VXHanConvert in Frameworks */,
6A38BC2815FC158A00A8A51F /* InputMethodKit.framework in Frameworks */,
D427F7A927905E90004A2160 /* TooltipUI in Frameworks */,
D427F76A278C9E29004A2160 /* CandidateUI in Frameworks */,
@ -251,6 +258,8 @@
D41355D7278D7409005E5CBD /* LanguageModelManager.mm */,
6A0D4EC815FC0D6400ABF4B3 /* main.m */,
D427F76B278CA1BA004A2160 /* AppDelegate.swift */,
D44FB74427915555003C80A6 /* Preferences.swift */,
D44FB74627919C83003C80A6 /* EmacsKeyHelper.swift */,
D47F7DCF278C0897002F9DD7 /* NonModalAlertWindowController.swift */,
D47F7DCD278BFB57002F9DD7 /* PreferencesWindowController.swift */,
6A0D4EF615FC0DA600ABF4B3 /* McBopomofo-Prefix.pch */,
@ -407,6 +416,7 @@
D427F7AC27907B7E004A2160 /* NotifierUI */,
D427F7B2279086B5004A2160 /* InputSourceHelper */,
D427F7BF27908EAC004A2160 /* OpenCCBridge */,
D44FB7482791B346003C80A6 /* VXHanConvert */,
);
name = Packages;
sourceTree = "<group>";
@ -451,6 +461,7 @@
D427F7AD27907B8A004A2160 /* NotifierUI */,
D427F7B3279086DC004A2160 /* InputSourceHelper */,
D427F7C027908EFC004A2160 /* OpenCCBridge */,
D44FB7492791B829003C80A6 /* VXHanConvert */,
);
productName = McBopomofo;
productReference = 6A0D4EA215FC0D2D00ABF4B3 /* McBopomofo.app */;
@ -576,7 +587,9 @@
buildActionMask = 2147483647;
files = (
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
D44FB74727919D35003C80A6 /* EmacsKeyHelper.swift in Sources */,
6A0D4ED315FC0D6400ABF4B3 /* main.m in Sources */,
D44FB74527915565003C80A6 /* Preferences.swift in Sources */,
D47F7DD0278C0897002F9DD7 /* NonModalAlertWindowController.swift in Sources */,
D47F7DCE278BFB57002F9DD7 /* PreferencesWindowController.swift in Sources */,
6A0D4ED215FC0D6400ABF4B3 /* InputMethodController.mm in Sources */,
@ -1085,6 +1098,10 @@
isa = XCSwiftPackageProductDependency;
productName = OpenCCBridge;
};
D44FB7492791B829003C80A6 /* VXHanConvert */ = {
isa = XCSwiftPackageProductDependency;
productName = VXHanConvert;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */;

View File

@ -25,5 +25,8 @@ let package = Package(
dependencies: [
.product(name: "OpenCC", package: "SwiftyOpenCC")
]),
.testTarget(
name: "OpenCCBridgeTests",
dependencies: ["OpenCCBridge"]),
]
)

View File

@ -1,8 +1,10 @@
import Foundation
import OpenCC
// Since SwiftyOpenCC only provide Swift classes, we create an NSObject subclass
// in Swift in order to bridge the Swift classes into our Objective-C++ project.
/// A bridge to let Objctive-C code to access SwiftyOpenCC.
///
/// Since SwiftyOpenCC only provide Swift classes, we create an NSObject subclass
/// in Swift in order to bridge the Swift classes into our Objective-C++ project.
public class OpenCCBridge: NSObject {
private static let shared = OpenCCBridge()
private var converter: ChineseConverter?
@ -12,7 +14,11 @@ public class OpenCCBridge: NSObject {
super.init()
}
@objc public static func convert(_ string: String) -> String? {
/// Converts to Simplified Chinese.
///
/// - Parameter string: Text in Traditional Chinese.
/// - Returns: Text in Simplified Chinese.
@objc public static func convertToSimplified(_ string: String) -> String? {
shared.converter?.convert(string)
}
}

View File

@ -2,10 +2,9 @@ import XCTest
@testable import OpenCCBridge
final class OpenCCBridgeTests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(OpenCCBridge().text, "Hello, World!")
func testTC2SC() throws {
let text = "繁體中文轉簡體中文"
let converted = OpenCCBridge.convertToSimplified(text)
XCTAssert(converted == "繁体中文转简体中文")
}
}

7
Packages/VXHanConvert/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

View File

@ -0,0 +1,28 @@
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "VXHanConvert",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "VXHanConvert",
targets: ["VXHanConvert"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "VXHanConvert",
dependencies: []),
.testTarget(
name: "VXHanConvertTests",
dependencies: ["VXHanConvert"]),
]
)

View File

@ -0,0 +1,3 @@
# VXHanConvert
A description of this package.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,651 @@
/* VXHCTC2SCTable.c: Traditional Chinese -> Simplified Chinese conv. table
* (VX is abbr. for Vanilla OS X, a legacy from OpenVanilla 0.6.x)
*
* Copyright (c) 2004-2007 The OpenVanilla Project (http://openvanilla.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of OpenVanilla nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The data is derived from Perl's Encode::HanConvert (0.31),
* Copyright (c) 2002-2004 by Autrijus Tang
*
*/
unsigned short vxTC2SCTable[3059 * 2]={
0x2215,0xff0f, 0x2223,0xff5c, 0x2225,0x2016, 0x2266,0x2264, 0x2267,0x2265,
0x2550,0x3013, 0x255e,0x251d, 0x2561,0x2525, 0x256a,0x253f, 0x2574,0xff3f,
0x2594,0xffe3, 0x2f02,0x4e36, 0x2f03,0x4e3f, 0x2f07,0x4ea0, 0x2f0c,0x5182,
0x2f0d,0x5196, 0x2f0e,0x51ab, 0x2f13,0x52f9, 0x2f19,0x5369, 0x2f1b,0x53b6,
0x2f22,0x5902, 0x2f27,0x5b80, 0x2f2e,0x5ddb, 0x2f33,0x5e7a, 0x2f34,0x5e7f,
0x2f35,0x5ef4, 0x2f39,0x5f50, 0x2f3a,0x5f61, 0x2f41,0x6534, 0x2f46,0x65e0,
0x2f67,0x7592, 0x2faa,0x96b6, 0x301e,0xff02, 0x3029,0x6587, 0x3038,0x5341,
0x3039,0x5344, 0x303a,0x5345, 0x4e1f,0x4e22, 0x4e26,0x5e76, 0x4e82,0x4e71,
0x4e99,0x4e98, 0x4e9e,0x4e9a, 0x4eb9,0x5a13, 0x4f00,0x5fea, 0x4f15,0x592b,
0x4f1d,0x4f20, 0x4f47,0x4f2b, 0x4f48,0x5e03, 0x4f54,0x5360, 0x4f6a,0x5f8a,
0x4f75,0x5e76, 0x4f86,0x6765, 0x4f96,0x4ed1, 0x4fb6,0x4fa3, 0x4fb7,0x5c40,
0x4fc1,0x4fe3, 0x4fc2,0x7cfb, 0x4fdb,0x4fef, 0x4fe0,0x4fa0, 0x4ff6,0x501c,
0x5000,0x4f25, 0x5006,0x4fe9, 0x5009,0x4ed3, 0x500b,0x4e2a, 0x5011,0x4eec,
0x5016,0x5e78, 0x5023,0x4eff, 0x502b,0x4f26, 0x5049,0x4f1f, 0x5061,0x903c,
0x5062,0x8e3d, 0x506a,0x903c, 0x5074,0x4fa7, 0x5075,0x4fa6, 0x507d,0x4f2a,
0x5091,0x6770, 0x5092,0x5faf, 0x5096,0x4f27, 0x5098,0x4f1e, 0x5099,0x5907,
0x509a,0x6548, 0x50a2,0x5bb6, 0x50ad,0x4f63, 0x50af,0x506c, 0x50b3,0x4f20,
0x50b4,0x4f1b, 0x50b5,0x503a, 0x50b7,0x4f24, 0x50be,0x503e, 0x50c2,0x507b,
0x50c5,0x4ec5, 0x50c9,0x4f65, 0x50ca,0x4ed9, 0x50d1,0x4fa8, 0x50d5,0x4ec6,
0x50e3,0x50ed, 0x50e5,0x4fa5, 0x50e8,0x507e, 0x50f1,0x96c7, 0x50f9,0x4ef7,
0x5100,0x4eea, 0x5102,0x4fac, 0x5104,0x4ebf, 0x5105,0x5f53, 0x5108,0x4fa9,
0x5109,0x4fed, 0x510c,0x4fa5, 0x5110,0x50a7, 0x5114,0x4fe6, 0x5115,0x4faa,
0x5118,0x5c3d, 0x511f,0x507f, 0x512a,0x4f18, 0x5132,0x50a8, 0x5133,0x998b,
0x5137,0x4fea, 0x5138,0x7f57, 0x5139,0x6512, 0x513a,0x50a9, 0x513b,0x50a5,
0x513c,0x4fe8, 0x5147,0x51f6, 0x514c,0x5151, 0x5152,0x513f, 0x5157,0x5156,
0x5167,0x5185, 0x5169,0x4e24, 0x5188,0x7f51, 0x518a,0x518c, 0x5191,0x80c4,
0x51aa,0x5e42, 0x51c8,0x51c0, 0x51cd,0x51bb, 0x51dc,0x51db, 0x51f1,0x51ef,
0x5225,0x522b, 0x522a,0x5220, 0x5231,0x521b, 0x5244,0x522d, 0x5247,0x5219,
0x5249,0x9509, 0x524b,0x514b, 0x524e,0x5239, 0x525b,0x521a, 0x525d,0x5265,
0x526e,0x5250, 0x5274,0x5240, 0x5275,0x521b, 0x5277,0x94f2, 0x5283,0x5212,
0x5284,0x672d, 0x5287,0x5267, 0x5289,0x5218, 0x528a,0x523d, 0x528b,0x527f,
0x528c,0x523f, 0x528d,0x5251, 0x5291,0x5242, 0x52c1,0x52b2, 0x52d5,0x52a8,
0x52d7,0x52d6, 0x52d9,0x52a1, 0x52db,0x52cb, 0x52dd,0x80dc, 0x52de,0x52b3,
0x52e2,0x52bf, 0x52e3,0x7ee9, 0x52e6,0x527f, 0x52f1,0x52a2, 0x52f3,0x52cb,
0x52f5,0x52b1, 0x52f8,0x529d, 0x52fb,0x5300, 0x5309,0x7830, 0x530a,0x63ac,
0x531f,0x7095, 0x532d,0x5326, 0x532f,0x6c47, 0x5331,0x532e, 0x5340,0x533a,
0x5354,0x534f, 0x5379,0x6064, 0x537b,0x5374, 0x538e,0x7825, 0x5399,0x538d,
0x53a7,0x5386, 0x53ad,0x538c, 0x53b2,0x5389, 0x53b4,0x53a3, 0x53c3,0x53c2,
0x53e1,0x777f, 0x53e2,0x4e1b, 0x540b,0x5bf8, 0x542a,0x8bb9, 0x5433,0x5434,
0x5436,0x5450, 0x5442,0x5415, 0x544e,0x5c3a, 0x5467,0x8bcb, 0x54b7,0x5555,
0x54bc,0x5459, 0x54e1,0x5458, 0x5504,0x5457, 0x5505,0x542b, 0x551a,0x5423,
0x5538,0x5ff5, 0x554f,0x95ee, 0x555e,0x54d1, 0x555f,0x542f, 0x5562,0x5521,
0x5563,0x8854, 0x557f,0x5556, 0x559a,0x5524, 0x55a5,0x54a4, 0x55aa,0x4e27,
0x55ab,0x5403, 0x55ac,0x4e54, 0x55ae,0x5355, 0x55b2,0x54df, 0x55c6,0x545b,
0x55c7,0x556c, 0x55ce,0x5417, 0x55da,0x545c, 0x55e9,0x5522, 0x55f6,0x54d4,
0x5606,0x53f9, 0x560d,0x55bd, 0x5614,0x5455, 0x5616,0x5567, 0x5617,0x5c1d,
0x561c,0x551b, 0x5629,0x54d7, 0x562e,0x5520, 0x562f,0x5578, 0x5630,0x53fd,
0x5635,0x54d3, 0x5638,0x5452, 0x5641,0x6076, 0x5649,0x5556, 0x5653,0x5618,
0x5660,0x54d2, 0x5665,0x54dd, 0x5666,0x54d5, 0x566f,0x55f3, 0x5672,0x54d9,
0x5674,0x55b7, 0x5678,0x5428, 0x5679,0x5f53, 0x5680,0x549b, 0x5687,0x5413,
0x568c,0x54dc, 0x5690,0x5c1d, 0x5695,0x565c, 0x5699,0x556e, 0x56a5,0x54bd,
0x56a6,0x5456, 0x56a8,0x5499, 0x56aa,0x5556, 0x56ac,0x9891, 0x56ae,0x5411,
0x56b3,0x55be, 0x56b4,0x4e25, 0x56b6,0x5624, 0x56be,0x6b22, 0x56c0,0x556d,
0x56c1,0x55eb, 0x56c2,0x56a3, 0x56c5,0x5181, 0x56c8,0x5453, 0x56c9,0x7f57,
0x56cc,0x82cf, 0x56d1,0x5631, 0x56d3,0x556e, 0x56ea,0x56f1, 0x5707,0x56f5,
0x570b,0x56fd, 0x570c,0x5459, 0x570d,0x56f4, 0x5712,0x56ed, 0x5713,0x5706,
0x5716,0x56fe, 0x5718,0x56e2, 0x571e,0x683e, 0x5775,0x4e18, 0x5794,0x5819,
0x57b5,0x57ef, 0x57e1,0x57ad, 0x57f7,0x6267, 0x5801,0x575d, 0x5805,0x575a,
0x580a,0x57a9, 0x581d,0x57da, 0x582f,0x5c27, 0x5831,0x62a5, 0x5834,0x573a,
0x583d,0x5188, 0x583f,0x78b1, 0x584a,0x5757, 0x584b,0x8314, 0x584f,0x57b2,
0x5852,0x57d8, 0x5857,0x6d82, 0x5859,0x786e, 0x585a,0x51a2, 0x5862,0x575e,
0x5864,0x57d9, 0x586d,0x761f, 0x5874,0x580b, 0x5875,0x5c18, 0x5879,0x5811,
0x588a,0x57ab, 0x5891,0x5892, 0x589c,0x5760, 0x58ae,0x5815, 0x58b3,0x575f,
0x58bb,0x5899, 0x58be,0x57a6, 0x58c7,0x575b, 0x58ce,0x57d9, 0x58d3,0x538b,
0x58d8,0x5792, 0x58d9,0x5739, 0x58da,0x5786, 0x58de,0x574f, 0x58df,0x5784,
0x58e2,0x575c, 0x58e9,0x575d, 0x58ef,0x58ee, 0x58fa,0x58f6, 0x58fd,0x5bff,
0x5920,0x591f, 0x5922,0x68a6, 0x593e,0x5939, 0x5950,0x5942, 0x5967,0x5965,
0x5969,0x5941, 0x596a,0x593a, 0x596e,0x594b, 0x597c,0x59f9, 0x599d,0x5986,
0x59b3,0x4f60, 0x59cd,0x59d7, 0x59e6,0x5978, 0x59ea,0x4f84, 0x59ee,0x5ae6,
0x59f7,0x4f91, 0x5a1b,0x5a31, 0x5a37,0x5077, 0x5a41,0x5a04, 0x5a53,0x6deb,
0x5a5f,0x5a40, 0x5a66,0x5987, 0x5a6d,0x5a05, 0x5aa7,0x5a32, 0x5aaf,0x59ab,
0x5abc,0x5aaa, 0x5abd,0x5988, 0x5abf,0x6127, 0x5acb,0x8885, 0x5ad7,0x59aa,
0x5af5,0x59a9, 0x5afa,0x5a34, 0x5afb,0x5a34, 0x5b08,0x5a06, 0x5b0b,0x5a75,
0x5b0c,0x5a07, 0x5b19,0x5af1, 0x5b1d,0x8885, 0x5b21,0x5ad2, 0x5b24,0x5b37,
0x5b2a,0x5ad4, 0x5b2d,0x5976, 0x5b30,0x5a74, 0x5b38,0x5a76, 0x5b3d,0x61d2,
0x5b43,0x5a18, 0x5b4c,0x5a08, 0x5b6b,0x5b59, 0x5b77,0x6635, 0x5b78,0x5b66,
0x5b7f,0x5b6a, 0x5bae,0x5bab, 0x5bca,0x5bdd, 0x5bd1,0x5b9e, 0x5bd6,0x6d78,
0x5bd8,0x7f6e, 0x5be2,0x5bdd, 0x5be6,0x5b9e, 0x5be7,0x5b81, 0x5be9,0x5ba1,
0x5beb,0x5199, 0x5bec,0x5bbd, 0x5bf1,0x5453, 0x5bf5,0x5ba0, 0x5bf6,0x5b9d,
0x5c07,0x5c06, 0x5c08,0x4e13, 0x5c0b,0x5bfb, 0x5c0d,0x5bf9, 0x5c0e,0x5bfc,
0x5c12,0x5c14, 0x5c1f,0x9c9c, 0x5c37,0x5c34, 0x5c46,0x5c4a, 0x5c4d,0x5c38,
0x5c5c,0x5c49, 0x5c62,0x5c61, 0x5c64,0x5c42, 0x5c68,0x5c66, 0x5c6c,0x5c5e,
0x5c8a,0x5c9c, 0x5ca1,0x5188, 0x5ca5,0x5761, 0x5cf4,0x5c98, 0x5cf6,0x5c9b,
0x5cfd,0x5ce1, 0x5d0d,0x5d03, 0x5d11,0x6606, 0x5d17,0x5c97, 0x5d19,0x4ed1,
0x5d1a,0x5ce5, 0x5d20,0x5cbd, 0x5d22,0x5ce5, 0x5d30,0x5cb7, 0x5d33,0x5d5b,
0x5d50,0x5c9a, 0x5d51,0x7800, 0x5d55,0x9685, 0x5d68,0x575e, 0x5d7e,0x53c2,
0x5d81,0x5d5d, 0x5d84,0x5d2d, 0x5d87,0x5c96, 0x5d94,0x5d5a, 0x5d97,0x5d02,
0x5da0,0x5ce4, 0x5da7,0x5cc4, 0x5da8,0x5c99, 0x5dae,0x9669, 0x5db4,0x5c99,
0x5db8,0x5d58, 0x5dba,0x5cad, 0x5dbc,0x5c7f, 0x5dbd,0x5cb3, 0x5dcb,0x5cbf,
0x5dd2,0x5ce6, 0x5dd4,0x5dc5, 0x5dd6,0x5ca9, 0x5df0,0x5def, 0x5df9,0x537a,
0x5e25,0x5e05, 0x5e2b,0x5e08, 0x5e33,0x5e10, 0x5e36,0x5e26, 0x5e40,0x5e27,
0x5e43,0x5e0f, 0x5e4e,0x5e42, 0x5e57,0x5e3c, 0x5e58,0x5e3b, 0x5e59,0x5e55,
0x5e5f,0x5e1c, 0x5e63,0x5e01, 0x5e6b,0x5e2e, 0x5e6c,0x5e31, 0x5e79,0x5e72,
0x5e7e,0x51e0, 0x5eab,0x5e93, 0x5ec1,0x5395, 0x5ec2,0x53a2, 0x5ec4,0x53a9,
0x5ec8,0x53a6, 0x5ed5,0x836b, 0x5eda,0x53a8, 0x5edd,0x53ae, 0x5edf,0x5e99,
0x5ee0,0x5382, 0x5ee1,0x5e91, 0x5ee2,0x5e9f, 0x5ee3,0x5e7f, 0x5ee9,0x5eea,
0x5eec,0x5e90, 0x5ef3,0x5385, 0x5f12,0x5f11, 0x5f14,0x540a, 0x5f33,0x5f2a,
0x5f35,0x5f20, 0x5f37,0x5f3a, 0x5f46,0x522b, 0x5f48,0x5f39, 0x5f4a,0x5f3a,
0x5f4c,0x5f25, 0x5f4e,0x5f2f, 0x5f54,0x5f55, 0x5f59,0x6c47, 0x5f5e,0x5f5d,
0x5f65,0x5f66, 0x5f6b,0x96d5, 0x5f7e,0x4f36, 0x5f7f,0x4f5b, 0x5f8c,0x540e,
0x5f91,0x5f84, 0x5f9e,0x4ece, 0x5fa0,0x5f95, 0x5fa9,0x590d, 0x5fac,0x65c1,
0x5fb9,0x5f7b, 0x5fe3,0x6025, 0x600c,0x6000, 0x6033,0x604d, 0x6046,0x6052,
0x6049,0x65e8, 0x6065,0x803b, 0x6085,0x60a6, 0x6090,0x54f2, 0x60b5,0x6005,
0x60b6,0x95f7, 0x60bd,0x51c4, 0x60bf,0x60ca, 0x60c7,0x6566, 0x60c8,0x60dd,
0x60e1,0x6076, 0x60e4,0x5a6a, 0x60f1,0x607c, 0x60f2,0x607d, 0x60f7,0x8822,
0x60fb,0x607b, 0x60fc,0x51ff, 0x6105,0x5ff1, 0x611b,0x7231, 0x611c,0x60ec,
0x6128,0x60ab, 0x612c,0x8bc9, 0x6134,0x6006, 0x6137,0x607a, 0x613e,0x5ffe,
0x6144,0x6817, 0x6147,0x6bb7, 0x614b,0x6001, 0x614d,0x6120, 0x6158,0x60e8,
0x615a,0x60ed, 0x615f,0x6078, 0x6163,0x60ef, 0x616a,0x6004, 0x616b,0x6002,
0x616e,0x8651, 0x6173,0x60ad, 0x6174,0x6151, 0x6176,0x5e86, 0x6179,0x7857,
0x617c,0x621a, 0x617e,0x6b32, 0x6182,0x5fe7, 0x6183,0x6a3d, 0x618a,0x60eb,
0x6190,0x601c, 0x6191,0x51ed, 0x6192,0x6126, 0x6193,0x60e0, 0x619a,0x60ee,
0x61a4,0x6124, 0x61ab,0x60af, 0x61ad,0x6a3d, 0x61ae,0x6003, 0x61b2,0x5baa,
0x61b6,0x5fc6, 0x61c3,0x52e4, 0x61c7,0x6073, 0x61c9,0x5e94, 0x61cc,0x603f,
0x61cd,0x61d4, 0x61de,0x8499, 0x61df,0x603c, 0x61e3,0x61d1, 0x61e8,0x6079,
0x61e9,0x75d2, 0x61f2,0x60e9, 0x61f6,0x61d2, 0x61f7,0x6000, 0x61f8,0x60ac,
0x61fa,0x5fcf, 0x61fc,0x60e7, 0x61fd,0x6b22, 0x61fe,0x6151, 0x6200,0x604b,
0x6207,0x6206, 0x6209,0x94ba, 0x6214,0x620b, 0x6227,0x6217, 0x6229,0x622c,
0x6230,0x6218, 0x6232,0x620f, 0x6236,0x6237, 0x625e,0x634d, 0x6260,0x53c9,
0x6261,0x62d6, 0x6283,0x62da, 0x62ad,0x8200, 0x62b4,0x62fd, 0x62cb,0x629b,
0x62d1,0x94b3, 0x632c,0x62d4, 0x633c,0x632a, 0x633e,0x631f, 0x6344,0x6551,
0x6368,0x820d, 0x636b,0x626a, 0x6372,0x5377, 0x6383,0x626b, 0x6384,0x62a1,
0x6399,0x6323, 0x639b,0x6302, 0x639c,0x62bb, 0x639e,0x78b0, 0x63a1,0x91c7,
0x63a4,0x632a, 0x63af,0x636e, 0x63c0,0x62e3, 0x63da,0x626c, 0x63db,0x6362,
0x63eb,0x63ea, 0x63ee,0x6325, 0x63f0,0x8f70, 0x63f9,0x80cc, 0x6406,0x6784,
0x640a,0x638f, 0x640d,0x635f, 0x6412,0x699c, 0x6416,0x6447, 0x6417,0x6363,
0x6424,0x627c, 0x6425,0x6376, 0x6427,0x6247, 0x6428,0x62d3, 0x642b,0x642c,
0x6436,0x62a2, 0x6439,0x627c, 0x643e,0x69a8, 0x6440,0x6342, 0x6443,0x625b,
0x6451,0x63b4, 0x645c,0x63bc, 0x645f,0x6402, 0x646f,0x631a, 0x6473,0x62a0,
0x6476,0x629f, 0x647b,0x63ba, 0x6488,0x635e, 0x6490,0x6491, 0x6493,0x6320,
0x6498,0x642d, 0x649a,0x637b, 0x649f,0x6322, 0x64a2,0x63b8, 0x64a3,0x63b8,
0x64a5,0x62e8, 0x64a6,0x626f, 0x64ab,0x629a, 0x64b2,0x6251, 0x64b3,0x63ff,
0x64bb,0x631e, 0x64be,0x631d, 0x64bf,0x6361, 0x64c1,0x62e5, 0x64c4,0x63b3,
0x64c7,0x62e9, 0x64ca,0x51fb, 0x64cb,0x6321, 0x64cf,0x64ce, 0x64d4,0x62c5,
0x64da,0x636e, 0x64e0,0x6324, 0x64e9,0x6363, 0x64ec,0x62df, 0x64ef,0x6448,
0x64f0,0x62e7, 0x64f1,0x6401, 0x64f2,0x63b7, 0x64f4,0x6269, 0x64f7,0x64b7,
0x64fa,0x6446, 0x64fb,0x64de, 0x64fc,0x64b8, 0x64fe,0x6270, 0x64ff,0x63b7,
0x6504,0x6445, 0x6506,0x64b5, 0x650f,0x62e2, 0x6513,0x6434, 0x6514,0x62e6,
0x6516,0x6484, 0x6517,0x6343, 0x6519,0x6400, 0x651b,0x64ba, 0x651c,0x643a,
0x651d,0x6444, 0x6522,0x6512, 0x6523,0x631b, 0x6524,0x644a, 0x6529,0x6321,
0x652a,0x6405, 0x652c,0x63fd, 0x6537,0x8003, 0x6557,0x8d25, 0x6558,0x53d9,
0x6575,0x654c, 0x6576,0x9635, 0x6578,0x6570, 0x657a,0x9a71, 0x6582,0x655b,
0x6583,0x6bd9, 0x6592,0x6591, 0x6595,0x6593, 0x65ac,0x65a9, 0x65b2,0x65ab,
0x65b7,0x65ad, 0x65bc,0x4e8e, 0x65c2,0x65d7, 0x65e1,0x65e0, 0x6607,0x5347,
0x662b,0x7166, 0x663a,0x70b3, 0x6642,0x65f6, 0x6649,0x664b, 0x665d,0x663c,
0x6665,0x7696, 0x6688,0x6655, 0x6689,0x6656, 0x6698,0x65f8, 0x66a2,0x7545,
0x66ab,0x6682, 0x66b1,0x6635, 0x66c4,0x6654, 0x66c6,0x5386, 0x66c7,0x6619,
0x66c9,0x6653, 0x66cf,0x5411, 0x66d6,0x66a7, 0x66e0,0x65f7, 0x66ec,0x6652,
0x66f8,0x4e66, 0x6703,0x4f1a, 0x6722,0x671b, 0x6727,0x80e7, 0x672e,0x672f,
0x6747,0x572c, 0x6771,0x4e1c, 0x6774,0x9528, 0x6792,0x4e2b, 0x679f,0x6a80,
0x67b4,0x62d0, 0x67df,0x6960, 0x67f5,0x6805, 0x6814,0x5951, 0x687f,0x6746,
0x6887,0x6994, 0x6894,0x6800, 0x689d,0x6761, 0x689f,0x67ad, 0x68b1,0x6346,
0x68c4,0x5f03, 0x68d6,0x67a8, 0x68d7,0x67a3, 0x68df,0x680b, 0x68e7,0x6808,
0x68f2,0x6816, 0x690f,0x6860, 0x6917,0x7887, 0x6937,0x7f04, 0x694a,0x6768,
0x6953,0x67ab, 0x6965,0x6966, 0x6968,0x6862, 0x696d,0x4e1a, 0x6975,0x6781,
0x69a6,0x5e72, 0x69aa,0x6769, 0x69ae,0x8363, 0x69bf,0x6864, 0x69c3,0x76d8,
0x69cb,0x6784, 0x69cd,0x67aa, 0x69d3,0x6760, 0x69e7,0x6920, 0x69e8,0x6901,
0x69f3,0x6868, 0x69fc,0x89c4, 0x69fe,0x5881, 0x6a01,0x6869, 0x6a02,0x4e50,
0x6a05,0x679e, 0x6a11,0x6881, 0x6a13,0x697c, 0x6a19,0x6807, 0x6a1e,0x67a2,
0x6a23,0x6837, 0x6a38,0x6734, 0x6a39,0x6811, 0x6a3a,0x6866, 0x6a46,0x65e0,
0x6a48,0x6861, 0x6a4b,0x6865, 0x6a55,0x6491, 0x6a5f,0x673a, 0x6a62,0x692d,
0x6a64,0x854a, 0x6a6b,0x6a2a, 0x6a7e,0x78b0, 0x6a81,0x6aa9, 0x6a89,0x67fd,
0x6a94,0x6863, 0x6a9c,0x6867, 0x6aa2,0x68c0, 0x6aa3,0x6a2f, 0x6aa5,0x8223,
0x6aae,0x68bc, 0x6aaf,0x53f0, 0x6ab3,0x69df, 0x6ab8,0x67e0, 0x6abb,0x69db,
0x6ac2,0x68f9, 0x6ac3,0x67dc, 0x6ad3,0x6a79, 0x6ada,0x6988, 0x6adb,0x6809,
0x6add,0x691f, 0x6ade,0x6a7c, 0x6adf,0x680e, 0x6ae5,0x6a71, 0x6ae7,0x69e0,
0x6ae8,0x680c, 0x6aea,0x67a5, 0x6aeb,0x6a65, 0x6aec,0x6987, 0x6af0,0x69d0,
0x6af3,0x680a, 0x6af8,0x6989, 0x6afa,0x68c2, 0x6afb,0x6a31, 0x6b04,0x680f,
0x6b0a,0x6743, 0x6b0b,0x68f9, 0x6b0f,0x6924, 0x6b11,0x6512, 0x6b12,0x683e,
0x6b16,0x6984, 0x6b1e,0x68c2, 0x6b2c,0x54b3, 0x6b3d,0x94a6, 0x6b4e,0x53f9,
0x6b50,0x6b27, 0x6b5b,0x655b, 0x6b5f,0x6b24, 0x6b61,0x6b22, 0x6b72,0x5c81,
0x6b77,0x5386, 0x6b78,0x5f52, 0x6b7e,0x6b81, 0x6b7f,0x6b81, 0x6b80,0x592d,
0x6b98,0x6b8b, 0x6b9e,0x6b92, 0x6ba4,0x6b87, 0x6bab,0x6b9a, 0x6bad,0x50f5,
0x6bae,0x6b93, 0x6baf,0x6ba1, 0x6bb2,0x6b7c, 0x6bba,0x6740, 0x6bbc,0x58f3,
0x6bbd,0x6dc6, 0x6bc0,0x6bc1, 0x6bc6,0x6bb4, 0x6bc9,0x533b, 0x6bd8,0x6bd7,
0x6bde,0x7eb0, 0x6be0,0x8888, 0x6be7,0x7ed2, 0x6bec,0x7403, 0x6bff,0x6bf5,
0x6c08,0x6be1, 0x6c0c,0x6c07, 0x6c23,0x6c14, 0x6c2b,0x6c22, 0x6c2c,0x6c29,
0x6c33,0x6c32, 0x6c3e,0x6cdb, 0x6c4e,0x6cdb, 0x6c59,0x6c61, 0x6c7a,0x51b3,
0x6c7b,0x6d52, 0x6c8d,0x51b1, 0x6c92,0x6ca1, 0x6c96,0x51b2, 0x6cb4,0x6eaf,
0x6cc1,0x51b5, 0x6d29,0x6cc4, 0x6d36,0x6c79, 0x6d6c,0x91cc, 0x6d79,0x6d43,
0x6d87,0x6cfe, 0x6db7,0x6d2b, 0x6dbc,0x51c9, 0x6dbd,0x6df9, 0x6dcf,0x6491,
0x6dd2,0x51c4, 0x6dda,0x6cea, 0x6de5,0x6e0c, 0x6de8,0x51c0, 0x6dea,0x6ca6,
0x6df5,0x6e0a, 0x6df6,0x6d9e, 0x6dfa,0x6d45, 0x6e19,0x6da3, 0x6e1b,0x51cf,
0x6e26,0x6da1, 0x6e2c,0x6d4b, 0x6e2e,0x83cf, 0x6e3e,0x6d51, 0x6e4a,0x51d1,
0x6e5e,0x6d48, 0x6e63,0x6cef, 0x6e67,0x6d8c, 0x6e6f,0x6c64, 0x6e88,0x6ca9,
0x6e96,0x51c6, 0x6e9d,0x6c9f, 0x6eab,0x6e29, 0x6eb0,0x7691, 0x6eb9,0x6eaf,
0x6ebc,0x6e7f, 0x6ec4,0x6ca7, 0x6ec5,0x706d, 0x6ecc,0x6da4, 0x6ece,0x8365,
0x6eec,0x6caa, 0x6eef,0x6ede, 0x6ef2,0x6e17, 0x6ef7,0x5364, 0x6ef8,0x6d52,
0x6efe,0x6eda, 0x6eff,0x6ee1, 0x6f01,0x6e14, 0x6f1a,0x6ca4, 0x6f22,0x6c49,
0x6f23,0x6d9f, 0x6f27,0x5e72, 0x6f2c,0x6e0d, 0x6f32,0x6da8, 0x6f35,0x6e86,
0x6f38,0x6e10, 0x6f3f,0x6d46, 0x6f41,0x988d, 0x6f51,0x6cfc, 0x6f54,0x6d01,
0x6f5a,0x6f47, 0x6f5b,0x6f5c, 0x6f5f,0x8204, 0x6f64,0x6da6, 0x6f6c,0x6ee9,
0x6f6f,0x6d54, 0x6f70,0x6e83, 0x6f77,0x6ed7, 0x6f7f,0x6da0, 0x6f80,0x6da9,
0x6f82,0x6f84, 0x6f86,0x6d47, 0x6f87,0x6d9d, 0x6f94,0x6d69, 0x6f97,0x6da7,
0x6fa0,0x6e11, 0x6fa3,0x6d63, 0x6fa4,0x6cfd, 0x6fa6,0x6eea, 0x6fa9,0x6cf6,
0x6fab,0x85d5, 0x6fae,0x6d4d, 0x6fb1,0x6dc0, 0x6fc1,0x6d4a, 0x6fc3,0x6d53,
0x6fc7,0x6da9, 0x6fca,0x8c41, 0x6fd4,0x5f25, 0x6fd5,0x6e7f, 0x6fd8,0x6cde,
0x6fdb,0x8499, 0x6fdf,0x6d4e, 0x6fe4,0x6d9b, 0x6feb,0x6ee5, 0x6fec,0x6d5a,
0x6ff0,0x6f4d, 0x6ff1,0x6ee8, 0x6ffa,0x6e85, 0x6ffc,0x6cfa, 0x6ffe,0x6ee4,
0x7005,0x6ee2, 0x7006,0x6e0e, 0x7009,0x6cfb, 0x700b,0x6e16, 0x700f,0x6d4f,
0x7015,0x6fd2, 0x7018,0x6cf8, 0x701d,0x6ca5, 0x701f,0x6f47, 0x7020,0x6f46,
0x7026,0x6f74, 0x7027,0x6cf7, 0x7028,0x6fd1, 0x7030,0x5f25, 0x7032,0x6f4b,
0x703e,0x6f9c, 0x7043,0x6ca3, 0x7044,0x6ee0, 0x7051,0x6d12, 0x7055,0x6f13,
0x7058,0x6ee9, 0x705d,0x704f, 0x7060,0x6f24, 0x7063,0x6e7e, 0x7064,0x6ee6,
0x7068,0x8d63, 0x7069,0x6edf, 0x707d,0x707e, 0x70a4,0x7167, 0x70ba,0x4e3a,
0x70cf,0x4e4c, 0x70f4,0x70c3, 0x7121,0x65e0, 0x7123,0x7092, 0x7146,0x867e,
0x7147,0x8f89, 0x7149,0x70bc, 0x7152,0x709c, 0x7156,0x6696, 0x7159,0x70df,
0x7162,0x8315, 0x7165,0x7115, 0x7169,0x70e6, 0x716c,0x7080, 0x7192,0x8367,
0x7197,0x709d, 0x71b1,0x70ed, 0x71be,0x70bd, 0x71bf,0x714c, 0x71c1,0x70e8,
0x71c4,0x7130, 0x71c8,0x706f, 0x71c9,0x7096, 0x71d0,0x78f7, 0x71d2,0x70e7,
0x71d9,0x70eb, 0x71dc,0x7116, 0x71df,0x8425, 0x71e6,0x707f, 0x71ec,0x6bc1,
0x71ed,0x70db, 0x71f4,0x70e9, 0x71fb,0x718f, 0x71fc,0x70ec, 0x71fe,0x7118,
0x71ff,0x8000, 0x720d,0x70c1, 0x7210,0x7089, 0x7213,0x7130, 0x721b,0x70c2,
0x721f,0x6b22, 0x722d,0x4e89, 0x723a,0x7237, 0x723e,0x5c14, 0x7246,0x5899,
0x724b,0x7b3a, 0x7253,0x699c, 0x7258,0x724d, 0x7260,0x5b83, 0x7274,0x62b5,
0x727d,0x7275, 0x7296,0x8366, 0x729b,0x7266, 0x72a2,0x728a, 0x72a5,0x71ac,
0x72a7,0x727a, 0x72c0,0x72b6, 0x72cc,0x7329, 0x72f9,0x72ed, 0x72fd,0x72c8,
0x730b,0x98d9, 0x7319,0x72f0, 0x7336,0x72b9, 0x733b,0x72f2, 0x7343,0x5446,
0x7344,0x72f1, 0x7345,0x72ee, 0x7349,0x699b, 0x734e,0x5956, 0x7358,0x6bd9,
0x7367,0x72f7, 0x7368,0x72ec, 0x736a,0x72ef, 0x736b,0x7303, 0x7370,0x72de,
0x7372,0x83b7, 0x7375,0x730e, 0x7377,0x72b7, 0x7378,0x517d, 0x737a,0x736d,
0x737b,0x732e, 0x737c,0x7315, 0x7380,0x7321, 0x7381,0x7303, 0x7383,0x883c,
0x7385,0x5999, 0x7386,0x5179, 0x7394,0x948f, 0x73a1,0x740a, 0x73a8,0x73cf,
0x73ea,0x572d, 0x73ee,0x4f69, 0x73fd,0x7487, 0x73fe,0x73b0, 0x740d,0x7483,
0x7416,0x76cf, 0x7431,0x96d5, 0x743a,0x73d0, 0x743f,0x73f2, 0x744b,0x73ae,
0x7463,0x7410, 0x7464,0x7476, 0x7469,0x83b9, 0x746a,0x739b, 0x746f,0x7405,
0x7485,0x7410, 0x7486,0x7403, 0x7489,0x740f, 0x749a,0x743c, 0x74a3,0x7391,
0x74a6,0x7477, 0x74b0,0x73af, 0x74bd,0x73ba, 0x74bf,0x7487, 0x74ca,0x743c,
0x74cf,0x73d1, 0x74d4,0x748e, 0x74d5,0x5f25, 0x74da,0x74d2, 0x750c,0x74ef,
0x7515,0x74ee, 0x7516,0x7f42, 0x7522,0x4ea7, 0x7526,0x82cf, 0x753f,0x6c13,
0x755d,0x4ea9, 0x7562,0x6bd5, 0x756b,0x753b, 0x756c,0x7572, 0x7570,0x5f02,
0x7576,0x5f53, 0x757d,0x7583, 0x7587,0x7574, 0x758a,0x53e0, 0x7598,0x809b,
0x75bf,0x75f1, 0x75ce,0x7b54, 0x75cf,0x75d2, 0x75d1,0x606b, 0x75d9,0x75c9,
0x75e0,0x9178, 0x75f2,0x9ebb, 0x75f3,0x9ebb, 0x75fa,0x75f9, 0x75fe,0x75b4,
0x7609,0x6108, 0x760b,0x75af, 0x760d,0x75a1, 0x7613,0x75ea, 0x7616,0x5591,
0x761e,0x7617, 0x7621,0x75ae, 0x7627,0x759f, 0x7628,0x766b, 0x763a,0x7618,
0x7642,0x7597, 0x7646,0x75e8, 0x7647,0x75eb, 0x7648,0x5e9f, 0x7649,0x7605,
0x7652,0x6108, 0x7658,0x75a0, 0x765f,0x762a, 0x7661,0x75f4, 0x7662,0x75d2,
0x7664,0x7596, 0x7665,0x75c7, 0x7669,0x765e, 0x766c,0x7663, 0x766d,0x763f,
0x766e,0x763e, 0x7670,0x75c8, 0x7671,0x762b, 0x7672,0x766b, 0x767c,0x53d1,
0x7681,0x7682, 0x768f,0x86d4, 0x769a,0x7691, 0x769b,0x777d, 0x769c,0x98a2,
0x76b0,0x75b1, 0x76b8,0x76b2, 0x76ba,0x76b1, 0x76bb,0x9f44, 0x76c3,0x676f,
0x76dc,0x76d7, 0x76de,0x76cf, 0x76e1,0x5c3d, 0x76e3,0x76d1, 0x76e4,0x76d8,
0x76e7,0x5362, 0x76ea,0x8361, 0x7725,0x7726, 0x773b,0x4ec5, 0x773e,0x4f17,
0x7744,0x77a7, 0x774f,0x56f0, 0x775c,0x7741, 0x775e,0x7750, 0x7760,0x7737,
0x776a,0x777e, 0x7787,0x772f, 0x779e,0x7792, 0x77ad,0x4e86, 0x77bc,0x7751,
0x77c7,0x8499, 0x77c9,0x9891, 0x77d3,0x80e7, 0x77d9,0x77b0, 0x77da,0x77a9,
0x77ef,0x77eb, 0x7832,0x70ae, 0x7843,0x6731, 0x7864,0x7856, 0x7868,0x7817,
0x786f,0x781a, 0x78a2,0x7823, 0x78a9,0x7855, 0x78aa,0x7827, 0x78ad,0x7800,
0x78ba,0x786e, 0x78bb,0x786e, 0x78bc,0x7801, 0x78da,0x7816, 0x78df,0x788c,
0x78e3,0x789c, 0x78e5,0x78ca, 0x78e7,0x789b, 0x78ef,0x77f6, 0x78fd,0x7857,
0x790c,0x78ca, 0x790e,0x7840, 0x7914,0x9739, 0x7919,0x788d, 0x7921,0x7934,
0x7926,0x77ff, 0x7927,0x78ca, 0x792a,0x783a, 0x792b,0x783e, 0x792c,0x77fe,
0x7931,0x783b, 0x7945,0x8884, 0x7950,0x4f51, 0x7955,0x79d8, 0x7961,0x5939,
0x797f,0x7984, 0x798d,0x7978, 0x798e,0x796f, 0x79a6,0x5fa1, 0x79aa,0x7985,
0x79ae,0x793c, 0x79b0,0x7962, 0x79b1,0x7977, 0x79bf,0x79c3, 0x79c8,0x7c7c,
0x79d6,0x53ea, 0x79fa,0x79bb, 0x7a05,0x7a0e, 0x7a08,0x79c6, 0x7a1c,0x68f1,
0x7a1f,0x7980, 0x7a2e,0x79cd, 0x7a31,0x79f0, 0x7a40,0x8c37, 0x7a4c,0x7a23,
0x7a4d,0x79ef, 0x7a4e,0x9896, 0x7a60,0x79fe, 0x7a61,0x7a51, 0x7a62,0x79fd,
0x7a68,0x9893, 0x7a69,0x7a33, 0x7a6b,0x83b7, 0x7a6d,0x7a06, 0x7a75,0x6316,
0x7a9e,0x51fc, 0x7aa9,0x7a9d, 0x7aaa,0x6d3c, 0x7aae,0x7a77, 0x7aaf,0x7a91,
0x7ab4,0x586b, 0x7ab6,0x7aad, 0x7aba,0x7aa5, 0x7ac4,0x7a9c, 0x7ac5,0x7a8d,
0x7ac7,0x7aa6, 0x7aca,0x7a83, 0x7af6,0x7ade, 0x7b46,0x7b14, 0x7b4d,0x7b0b,
0x7b66,0x7ba1, 0x7b67,0x7b15, 0x7b69,0x7b52, 0x7b6d,0x7b97, 0x7b74,0x5395,
0x7b87,0x4e2a, 0x7b8b,0x7b3a, 0x7b8e,0x7bea, 0x7b8f,0x7b5d, 0x7ba0,0x68f0,
0x7bc0,0x8282, 0x7bc4,0x8303, 0x7bc9,0x7b51, 0x7bcb,0x7ba7, 0x7bdb,0x7bac,
0x7be0,0x7b71, 0x7be4,0x7b03, 0x7be9,0x7b5b, 0x7bf3,0x7b5a, 0x7c00,0x7ba6,
0x7c0d,0x7bd3, 0x7c11,0x84d1, 0x7c1e,0x7baa, 0x7c21,0x7b80, 0x7c23,0x7bd1,
0x7c2b,0x7bab, 0x7c30,0x7b85, 0x7c37,0x6a90, 0x7c3d,0x7b7e, 0x7c3e,0x5e18,
0x7c43,0x7bee, 0x7c49,0x7b1e, 0x7c4c,0x7b79, 0x7c50,0x85e4, 0x7c5c,0x7ba8,
0x7c5f,0x7c41, 0x7c60,0x7b3c, 0x7c64,0x7b7e, 0x7c65,0x9fa0, 0x7c69,0x7b3e,
0x7c6a,0x7c16, 0x7c6c,0x7bf1, 0x7c6e,0x7ba9, 0x7c72,0x5401, 0x7c79,0x5986,
0x7ca7,0x5986, 0x7cb5,0x7ca4, 0x7cba,0x7a17, 0x7cdd,0x7cc1, 0x7cde,0x7caa,
0x7ce2,0x6a21, 0x7ce7,0x7cae, 0x7cf0,0x56e2, 0x7cf2,0x7c9d, 0x7cf4,0x7c74,
0x7cf6,0x7c9c, 0x7cfe,0x7ea0, 0x7d00,0x7eaa, 0x7d02,0x7ea3, 0x7d04,0x7ea6,
0x7d05,0x7ea2, 0x7d06,0x7ea1, 0x7d07,0x7ea5, 0x7d08,0x7ea8, 0x7d09,0x7eab,
0x7d0b,0x7eb9, 0x7d0d,0x7eb3, 0x7d10,0x7ebd, 0x7d13,0x7ebe, 0x7d14,0x7eaf,
0x7d15,0x7eb0, 0x7d17,0x7eb1, 0x7d19,0x7eb8, 0x7d1a,0x7ea7, 0x7d1b,0x7eb7,
0x7d1c,0x7ead, 0x7d21,0x7eba, 0x7d29,0x7ef8, 0x7d2e,0x624e, 0x7d30,0x7ec6,
0x7d31,0x7ec2, 0x7d32,0x7ec1, 0x7d33,0x7ec5, 0x7d39,0x7ecd, 0x7d3a,0x7ec0,
0x7d3c,0x7ecb, 0x7d3f,0x7ed0, 0x7d40,0x7ecc, 0x7d42,0x7ec8, 0x7d43,0x5f26,
0x7d44,0x7ec4, 0x7d46,0x7eca, 0x7d4e,0x7ed7, 0x7d4f,0x7ec1, 0x7d50,0x7ed3,
0x7d55,0x7edd, 0x7d56,0x7ea9, 0x7d5b,0x7ee6, 0x7d5c,0x6d01, 0x7d5e,0x7ede,
0x7d61,0x7edc, 0x7d62,0x7eda, 0x7d66,0x7ed9, 0x7d68,0x7ed2, 0x7d70,0x7ed6,
0x7d71,0x7edf, 0x7d72,0x4e1d, 0x7d73,0x7edb, 0x7d79,0x7ee2, 0x7d81,0x7ed1,
0x7d83,0x7ee1, 0x7d86,0x7ee0, 0x7d88,0x7ee8, 0x7d8d,0x7ecb, 0x7d8f,0x7ee5,
0x7d91,0x56f0, 0x7d93,0x7ecf, 0x7d9c,0x7efc, 0x7d9e,0x7f0d, 0x7da0,0x7eff,
0x7da2,0x7ef8, 0x7da3,0x7efb, 0x7dac,0x7ef6, 0x7dad,0x7ef4, 0x7db0,0x7efe,
0x7db1,0x7eb2, 0x7db2,0x7f51, 0x7db4,0x7f00, 0x7db5,0x5f69, 0x7db8,0x7eb6,
0x7db9,0x7efa, 0x7dba,0x7eee, 0x7dbb,0x7efd, 0x7dbd,0x7ef0, 0x7dbe,0x7eeb,
0x7dbf,0x7ef5, 0x7dc4,0x7ef2, 0x7dc7,0x7f01, 0x7dca,0x7d27, 0x7dcb,0x7eef,
0x7dd2,0x7eea, 0x7dd7,0x7f03, 0x7dd8,0x7f04, 0x7dd9,0x7f02, 0x7dda,0x7ebf,
0x7ddd,0x7f09, 0x7dde,0x7f0e, 0x7de0,0x7f14, 0x7de1,0x7f17, 0x7de3,0x7f18,
0x7de6,0x7f0c, 0x7de8,0x7f16, 0x7de9,0x7f13, 0x7dec,0x7f05, 0x7def,0x7eac,
0x7df1,0x7f11, 0x7df2,0x7f08, 0x7df4,0x7ec3, 0x7df6,0x7f0f, 0x7df9,0x7f07,
0x7dfb,0x81f4, 0x7e08,0x8426, 0x7e09,0x7f19, 0x7e0a,0x7f22, 0x7e0b,0x7f12,
0x7e10,0x7ec9, 0x7e11,0x7f23, 0x7e1a,0x7ee6, 0x7e1b,0x7f1a, 0x7e1d,0x7f1c,
0x7e1e,0x7f1f, 0x7e1f,0x7f1b, 0x7e23,0x53bf, 0x7e2b,0x7f1d, 0x7e2d,0x7f21,
0x7e2e,0x7f29, 0x7e2f,0x6f14, 0x7e31,0x7eb5, 0x7e32,0x7f27, 0x7e34,0x7ea4,
0x7e35,0x7f26, 0x7e36,0x7d77, 0x7e37,0x7f15, 0x7e39,0x7f25, 0x7e3d,0x603b,
0x7e3e,0x7ee9, 0x7e43,0x7ef7, 0x7e45,0x7f2b, 0x7e46,0x7f2a, 0x7e48,0x8941,
0x7e52,0x7f2f, 0x7e54,0x7ec7, 0x7e55,0x7f2e, 0x7e56,0x4f1e, 0x7e59,0x7ffb,
0x7e5a,0x7f2d, 0x7e5e,0x7ed5, 0x7e61,0x7ee3, 0x7e62,0x7f0b, 0x7e69,0x7ef3,
0x7e6a,0x7ed8, 0x7e6b,0x7cfb, 0x7e6d,0x8327, 0x7e6f,0x7f33, 0x7e70,0x7f32,
0x7e73,0x7f34, 0x7e79,0x7ece, 0x7e7c,0x7ee7, 0x7e7d,0x7f24, 0x7e7e,0x7f31,
0x7e88,0x7f2c, 0x7e8a,0x7ea9, 0x7e8c,0x7eed, 0x7e8d,0x7d2f, 0x7e8f,0x7f20,
0x7e93,0x7f28, 0x7e94,0x624d, 0x7e96,0x7ea4, 0x7e98,0x7f35, 0x7e9c,0x7f06,
0x7f3d,0x94b5, 0x7f3e,0x74f6, 0x7f48,0x575b, 0x7f4b,0x74ee, 0x7f4c,0x7f42,
0x7f4f,0x5786, 0x7f70,0x7f5a, 0x7f75,0x9a82, 0x7f77,0x7f62, 0x7f7c,0x6bd5,
0x7f83,0x5e42, 0x7f85,0x7f57, 0x7f86,0x7f74, 0x7f88,0x7f81, 0x7f8b,0x8288,
0x7f91,0x8bf1, 0x7f95,0x6302, 0x7fa2,0x7ed2, 0x7fa5,0x7f9f, 0x7fa8,0x7fa1,
0x7fa9,0x4e49, 0x7fb6,0x81bb, 0x7fd2,0x4e60, 0x7fe8,0x7fc5, 0x7feb,0x73a9,
0x7ff9,0x7fd8, 0x8011,0x4e13, 0x8021,0x9504, 0x802c,0x8027, 0x8056,0x5723,
0x805d,0x9998, 0x805e,0x95fb, 0x806f,0x8054, 0x8070,0x806a, 0x8072,0x58f0,
0x8073,0x8038, 0x8075,0x8069, 0x8076,0x8042, 0x8077,0x804c, 0x8079,0x804d,
0x807d,0x542c, 0x807e,0x804b, 0x8085,0x8083, 0x808a,0x81c6, 0x8090,0x80f3,
0x80ca,0x6710, 0x80d1,0x80a2, 0x8105,0x80c1, 0x8108,0x8109, 0x8115,0x8118,
0x811b,0x80eb, 0x8123,0x5507, 0x8125,0x8118, 0x8129,0x4fee, 0x812b,0x8131,
0x8139,0x80c0, 0x813a,0x8106, 0x814e,0x80be, 0x8161,0x8136, 0x8166,0x8111,
0x816b,0x80bf, 0x8173,0x811a, 0x8178,0x80a0, 0x8183,0x817d, 0x819a,0x80a4,
0x81a0,0x80f6, 0x81a9,0x817b, 0x81ac,0x8106, 0x81bd,0x80c6, 0x81be,0x810d,
0x81bf,0x8113, 0x81c9,0x8138, 0x81cd,0x8110, 0x81cf,0x8191, 0x81d5,0x8198,
0x81d8,0x814a, 0x81d9,0x80ed, 0x81da,0x80ea, 0x81dd,0x88f8, 0x81df,0x810f,
0x81e0,0x8114, 0x81e2,0x81dc, 0x81e5,0x5367, 0x81e8,0x4e34, 0x81fa,0x53f0,
0x8207,0x4e0e, 0x8208,0x5174, 0x8209,0x4e3e, 0x820a,0x65e7, 0x8216,0x94fa,
0x8259,0x8231, 0x8264,0x8223, 0x8266,0x8230, 0x826b,0x823b, 0x8271,0x8270,
0x8277,0x8273, 0x8278,0x8349, 0x8290,0x82c4, 0x8294,0x5349, 0x82bb,0x520d,
0x82c3,0x8307, 0x82e7,0x82ce, 0x8316,0x835e, 0x8332,0x5179, 0x8337,0x8585,
0x834a,0x8346, 0x834c,0x62e3, 0x8373,0x8c46, 0x838a,0x5e84, 0x8396,0x830e,
0x8399,0x8347, 0x83a2,0x835a, 0x83a4,0x8c46, 0x83a7,0x82cb, 0x83c9,0x7eff,
0x83d1,0x707e, 0x83e2,0x62b1, 0x83ef,0x534e, 0x8407,0x82cc, 0x840a,0x83b1,
0x842c,0x4e07, 0x8435,0x83b4, 0x8437,0x5ced, 0x8449,0x53f6, 0x8452,0x836d,
0x8460,0x53c2, 0x8466,0x82c7, 0x846e,0x846d, 0x846f,0x836f, 0x8477,0x8364,
0x847e,0x852b, 0x8494,0x83b3, 0x849e,0x8385, 0x84a8,0x831c, 0x84a9,0x83f9,
0x84bc,0x82cd, 0x84c0,0x836a, 0x84c6,0x5e2d, 0x84cb,0x76d6, 0x84e8,0x839c,
0x84ee,0x83b2, 0x84ef,0x82c1, 0x84f1,0x8d2b, 0x84f4,0x83bc, 0x84fb,0x827a,
0x84fd,0x835c, 0x8506,0x83f1, 0x8514,0x535c, 0x8515,0x8482, 0x851e,0x848c,
0x8523,0x848b, 0x8525,0x8471, 0x8526,0x8311, 0x852d,0x836b, 0x8541,0x8368,
0x8546,0x8487, 0x854e,0x835e, 0x8553,0x82b8, 0x8555,0x83b8, 0x8558,0x835b,
0x8562,0x8489, 0x8569,0x8361, 0x856a,0x829c, 0x856d,0x8427, 0x8577,0x84e3,
0x8580,0x8574, 0x8588,0x835f, 0x8589,0x79fd, 0x858a,0x84df, 0x858c,0x8297,
0x8591,0x59dc, 0x8594,0x8537, 0x8599,0x5243, 0x859f,0x83b6, 0x85a6,0x8350,
0x85a9,0x8428, 0x85b6,0x57cb, 0x85ba,0x8360, 0x85c2,0x4e1b, 0x85c7,0x84e3,
0x85cd,0x84dd, 0x85ce,0x8369, 0x85dd,0x827a, 0x85e5,0x836f, 0x85ea,0x85ae,
0x85f6,0x82c8, 0x85f9,0x853c, 0x85fa,0x853a, 0x8604,0x8572, 0x8606,0x82a6,
0x8607,0x82cf, 0x8609,0x7816, 0x860a,0x8574, 0x860b,0x82f9, 0x8617,0x8616,
0x861a,0x85d3, 0x861c,0x83ca, 0x861e,0x8539, 0x8620,0x8537, 0x8622,0x830f,
0x862a,0x863c, 0x862d,0x5170, 0x863a,0x84e0, 0x863f,0x841d, 0x8653,0x8327,
0x8655,0x5904, 0x8656,0x5b93, 0x865b,0x865a, 0x865c,0x864f, 0x865f,0x53f7,
0x8667,0x4e8f, 0x866f,0x866c, 0x8685,0x8695, 0x8696,0x8788, 0x869a,0x86a7,
0x86a1,0x869d, 0x86a5,0x86d4, 0x86bf,0x547c, 0x86e3,0x9c92, 0x86fa,0x86f1,
0x86fb,0x8715, 0x8706,0x86ac, 0x870b,0x8793, 0x8711,0x86cb, 0x8728,0x8776,
0x873a,0x9713, 0x8755,0x8680, 0x875e,0x7338, 0x875f,0x732c, 0x8761,0x8815,
0x8766,0x867e, 0x8768,0x8671, 0x876f,0x733f, 0x8773,0x73b3, 0x8778,0x8717,
0x8784,0x86f3, 0x8798,0x8681, 0x879e,0x8682, 0x87a2,0x8424, 0x87bb,0x877c,
0x87be,0x8693, 0x87c4,0x86f0, 0x87c8,0x8748, 0x87e3,0x866e, 0x87ec,0x8749,
0x87ef,0x86f2, 0x87f2,0x866b, 0x87f6,0x86cf, 0x87f7,0x87b3, 0x87fa,0x87ee,
0x87fb,0x8681, 0x87ff,0x881b, 0x8805,0x8747, 0x8806,0x867f, 0x880d,0x874e,
0x8810,0x86f4, 0x8811,0x877e, 0x8814,0x869d, 0x881f,0x8721, 0x8823,0x86ce,
0x8831,0x86ca, 0x8836,0x8695, 0x883b,0x86ee, 0x884a,0x8511, 0x8853,0x672f,
0x8855,0x540c, 0x8856,0x5f04, 0x885b,0x536b, 0x885d,0x51b2, 0x8879,0x53ea,
0x8889,0x70ab, 0x8893,0x888d, 0x8898,0x7617, 0x889e,0x886e, 0x889f,0x7c97,
0x88ba,0x5939, 0x88ca,0x8885, 0x88cc,0x5939, 0x88cf,0x91cc, 0x88dc,0x8865,
0x88dd,0x88c5, 0x88e1,0x91cc, 0x88fd,0x5236, 0x8907,0x590d, 0x890e,0x8896,
0x892d,0x8885, 0x8932,0x88e4, 0x8933,0x88e2, 0x8935,0x7f21, 0x8938,0x891b,
0x893b,0x4eb5, 0x8946,0x5e5e, 0x8949,0x88e5, 0x8956,0x8884, 0x895d,0x88e3,
0x8960,0x88c6, 0x8962,0x8892, 0x8964,0x8934, 0x896a,0x889c, 0x896d,0x7f2c,
0x896f,0x886c, 0x8972,0x88ad, 0x8988,0x6838, 0x898b,0x89c1, 0x898f,0x89c4,
0x8993,0x89c5, 0x8995,0x2171, 0x8996,0x89c6, 0x8998,0x89c7, 0x899c,0x773a,
0x89a1,0x89cb, 0x89a6,0x89ce, 0x89aa,0x4eb2, 0x89ac,0x89ca, 0x89af,0x89cf,
0x89b2,0x89d0, 0x89b7,0x89d1, 0x89ba,0x89c9, 0x89bd,0x89c8, 0x89bf,0x89cc,
0x89c0,0x89c2, 0x89d4,0x7b4b, 0x89dd,0x62b5, 0x89f4,0x89de, 0x89f6,0x89ef,
0x89f8,0x89e6, 0x8a02,0x8ba2, 0x8a03,0x8ba3, 0x8a08,0x8ba1, 0x8a0a,0x8baf,
0x8a0c,0x8ba7, 0x8a0e,0x8ba8, 0x8a0f,0x5401, 0x8a10,0x8ba6, 0x8a13,0x8bad,
0x8a15,0x8baa, 0x8a16,0x8bab, 0x8a17,0x6258, 0x8a18,0x8bb0, 0x8a1b,0x8bb9,
0x8a1d,0x8bb6, 0x8a1f,0x8bbc, 0x8a22,0x6b23, 0x8a23,0x8bc0, 0x8a25,0x8bb7,
0x8a2a,0x8bbf, 0x8a2d,0x8bbe, 0x8a31,0x8bb8, 0x8a34,0x8bc9, 0x8a36,0x8bc3,
0x8a3a,0x8bca, 0x8a3b,0x6ce8, 0x8a3c,0x8bc1, 0x8a3f,0x8a3e, 0x8a41,0x8bc2,
0x8a46,0x8bcb, 0x8a4e,0x8bb5, 0x8a50,0x8bc8, 0x8a52,0x8bd2, 0x8a54,0x8bcf,
0x8a55,0x8bc4, 0x8a56,0x8bd0, 0x8a58,0x8bce, 0x8a5b,0x8bc5, 0x8a5e,0x8bcd,
0x8a60,0x548f, 0x8a61,0x8be9, 0x8a62,0x8be2, 0x8a63,0x8be3, 0x8a66,0x8bd5,
0x8a69,0x8bd7, 0x8a6b,0x8be7, 0x8a6c,0x8bdf, 0x8a6d,0x8be1, 0x8a6e,0x8be0,
0x8a70,0x8bd8, 0x8a71,0x8bdd, 0x8a72,0x8be5, 0x8a73,0x8be6, 0x8a75,0x8bdc,
0x8a7c,0x8bd9, 0x8a7f,0x8bd6, 0x8a84,0x8bd4, 0x8a85,0x8bdb, 0x8a86,0x8bd3,
0x8a87,0x5938, 0x8a8c,0x5fd7, 0x8a8d,0x8ba4, 0x8a91,0x8bf3, 0x8a92,0x8bf6,
0x8a95,0x8bde, 0x8a96,0x6096, 0x8a98,0x8bf1, 0x8a9a,0x8bee, 0x8a9e,0x8bed,
0x8aa0,0x8bda, 0x8aa1,0x8beb, 0x8aa3,0x8bec, 0x8aa4,0x8bef, 0x8aa5,0x8bf0,
0x8aa6,0x8bf5, 0x8aa8,0x8bf2, 0x8aaa,0x8bf4, 0x8ab0,0x8c01, 0x8ab2,0x8bfe,
0x8ab6,0x8c07, 0x8ab9,0x8bfd, 0x8abc,0x8c0a, 0x8abf,0x8c03, 0x8ac2,0x8c04,
0x8ac4,0x8c06, 0x8ac7,0x8c08, 0x8ac9,0x8bff, 0x8acb,0x8bf7, 0x8acd,0x8be4,
0x8acf,0x8bf9, 0x8ad1,0x8bfc, 0x8ad2,0x8c05, 0x8ad6,0x8bba, 0x8ad7,0x8c02,
0x8adb,0x8c00, 0x8adc,0x8c0d, 0x8ade,0x8c1d, 0x8ae0,0x55a7, 0x8ae2,0x8be8,
0x8ae4,0x8c14, 0x8ae6,0x8c1b, 0x8ae7,0x8c10, 0x8aeb,0x8c0f, 0x8aed,0x8c15,
0x8aee,0x8c18, 0x8af1,0x8bb3, 0x8af3,0x8c19, 0x8af6,0x8c0c, 0x8af7,0x8bbd,
0x8af8,0x8bf8, 0x8afa,0x8c1a, 0x8afc,0x8c16, 0x8afe,0x8bfa, 0x8b00,0x8c0b,
0x8b01,0x8c12, 0x8b02,0x8c13, 0x8b04,0x8a8a, 0x8b05,0x8bcc, 0x8b0a,0x8c0e,
0x8b0e,0x8c1c, 0x8b10,0x8c27, 0x8b14,0x8c11, 0x8b16,0x8c21, 0x8b17,0x8c24,
0x8b19,0x8c26, 0x8b1a,0x8c25, 0x8b1b,0x8bb2, 0x8b1d,0x8c22, 0x8b20,0x8c23,
0x8b28,0x8c1f, 0x8b2b,0x8c2a, 0x8b2c,0x8c2c, 0x8b2e,0x5567, 0x8b2f,0x8bc5,
0x8b33,0x8bb4, 0x8b39,0x8c28, 0x8b3c,0x547c, 0x8b3e,0x8c29, 0x8b41,0x54d7,
0x8b46,0x563b, 0x8b48,0x619d, 0x8b49,0x8bc1, 0x8b4b,0x8c30, 0x8b4e,0x8c32,
0x8b4f,0x8ba5, 0x8b54,0x64b0, 0x8b56,0x8c2e, 0x8b58,0x8bc6, 0x8b59,0x8c2f,
0x8b5a,0x8c2d, 0x8b5c,0x8c31, 0x8b5f,0x566a, 0x8b63,0x9a8c, 0x8b6b,0x8c35,
0x8b6d,0x6bc1, 0x8b6f,0x8bd1, 0x8b70,0x8bae, 0x8b74,0x8c34, 0x8b77,0x62a4,
0x8b7d,0x8a89, 0x8b7e,0x8c2b, 0x8b80,0x8bfb, 0x8b85,0x5ba1, 0x8b8a,0x53d8,
0x8b8c,0x5bb4, 0x8b8e,0x96e0, 0x8b92,0x8c17, 0x8b93,0x8ba9, 0x8b95,0x8c30,
0x8b96,0x8c36, 0x8b99,0x6b22, 0x8b9a,0x8d5e, 0x8b9c,0x8c20, 0x8b9e,0x8c33,
0x8c3f,0x6eaa, 0x8c48,0x5c82, 0x8c4e,0x7ad6, 0x8c50,0x4e30, 0x8c54,0x8273,
0x8c6c,0x732a, 0x8c8d,0x72f8, 0x8c93,0x732b, 0x8c9d,0x8d1d, 0x8c9e,0x8d1e,
0x8ca0,0x8d1f, 0x8ca1,0x8d22, 0x8ca2,0x8d21, 0x8ca4,0x72b4, 0x8ca7,0x8d2b,
0x8ca8,0x8d27, 0x8ca9,0x8d29, 0x8caa,0x8d2a, 0x8cab,0x8d2f, 0x8cac,0x8d23,
0x8caf,0x8d2e, 0x8cb0,0x8d33, 0x8cb2,0x8d40, 0x8cb3,0x8d30, 0x8cb4,0x8d35,
0x8cb6,0x8d2c, 0x8cb7,0x4e70, 0x8cb8,0x8d37, 0x8cba,0x8d36, 0x8cbb,0x8d39,
0x8cbc,0x8d34, 0x8cbd,0x8d3b, 0x8cbf,0x8d38, 0x8cc0,0x8d3a, 0x8cc1,0x8d32,
0x8cc2,0x8d42, 0x8cc3,0x8d41, 0x8cc4,0x8d3f, 0x8cc5,0x8d45, 0x8cc7,0x8d44,
0x8cc8,0x8d3e, 0x8cca,0x8d3c, 0x8cd1,0x8d48, 0x8cd2,0x8d4a, 0x8cd3,0x5bbe,
0x8cd5,0x8d47, 0x8cda,0x8d49, 0x8cdc,0x8d50, 0x8cdd,0x741b, 0x8cde,0x8d4f,
0x8ce0,0x8d54, 0x8ce1,0x8d53, 0x8ce2,0x8d24, 0x8ce3,0x5356, 0x8ce4,0x8d31,
0x8ce6,0x8d4b, 0x8ce7,0x8d55, 0x8cea,0x8d28, 0x8cec,0x8d26, 0x8ced,0x8d4c,
0x8cf4,0x8d56, 0x8cf8,0x5269, 0x8cfa,0x8d5a, 0x8cfb,0x8d59, 0x8cfc,0x8d2d,
0x8cfd,0x8d5b, 0x8cfe,0x8d5c, 0x8d04,0x8d3d, 0x8d05,0x8d58, 0x8d08,0x8d60,
0x8d0a,0x8d5e, 0x8d0d,0x8d61, 0x8d0f,0x8d62, 0x8d10,0x8d46, 0x8d13,0x8d43,
0x8d16,0x8d4e, 0x8d17,0x8d5d, 0x8d1b,0x8d63, 0x8d78,0x8d76, 0x8d95,0x8d76,
0x8d99,0x8d75, 0x8da8,0x8d8b, 0x8dae,0x8e81, 0x8db2,0x8db1, 0x8de1,0x8ff9,
0x8df0,0x80fc, 0x8df4,0x8e29, 0x8dfc,0x5c40, 0x8e10,0x8df5, 0x8e21,0x8737,
0x8e30,0x903e, 0x8e34,0x8e0a, 0x8e4c,0x8dc4, 0x8e53,0x905b, 0x8e55,0x8df8,
0x8e5a,0x8d9f, 0x8e5d,0x5c63, 0x8e5e,0x8e2f, 0x8e5f,0x8ff9, 0x8e60,0x8dd6,
0x8e62,0x8e2f, 0x8e63,0x8e52, 0x8e64,0x8e2a, 0x8e67,0x7cdf, 0x8e78,0x8e8f,
0x8e7a,0x8df7, 0x8e82,0x8e0f, 0x8e89,0x8db8, 0x8e8a,0x8e0c, 0x8e8b,0x8dfb,
0x8e8d,0x8dc3, 0x8e91,0x8e2f, 0x8e92,0x8dde, 0x8e93,0x8e2c, 0x8e95,0x8e70,
0x8e9a,0x8df9, 0x8ea1,0x8e51, 0x8ea5,0x8e7f, 0x8ea6,0x8e9c, 0x8eaa,0x8e8f,
0x8ec0,0x8eaf, 0x8eca,0x8f66, 0x8ecb,0x8f67, 0x8ecc,0x8f68, 0x8ecd,0x519b,
0x8ed2,0x8f69, 0x8ed4,0x8f6b, 0x8edb,0x8f6d, 0x8edf,0x8f6f, 0x8eeb,0x8f78,
0x8ef6,0x8f6d, 0x8ef8,0x8f74, 0x8ef9,0x8f75, 0x8efa,0x8f7a, 0x8efb,0x8f72,
0x8efc,0x8f76, 0x8efe,0x8f7c, 0x8f03,0x8f83, 0x8f05,0x8f82, 0x8f07,0x8f81,
0x8f09,0x8f7d, 0x8f0a,0x8f7e, 0x8f12,0x8f84, 0x8f13,0x633d, 0x8f14,0x8f85,
0x8f15,0x8f7b, 0x8f1b,0x8f86, 0x8f1c,0x8f8e, 0x8f1d,0x8f89, 0x8f1e,0x8f8b,
0x8f1f,0x8f8d, 0x8f20,0x9505, 0x8f25,0x8f8a, 0x8f26,0x8f87, 0x8f29,0x8f88,
0x8f2a,0x8f6e, 0x8f2f,0x8f91, 0x8f33,0x8f8f, 0x8f37,0x8f70, 0x8f38,0x8f93,
0x8f3b,0x8f90, 0x8f3e,0x8f97, 0x8f3f,0x8206, 0x8f42,0x6bc2, 0x8f44,0x8f96,
0x8f45,0x8f95, 0x8f46,0x8f98, 0x8f49,0x8f6c, 0x8f4d,0x8f99, 0x8f4e,0x8f7f,
0x8f54,0x8f9a, 0x8f5d,0x8206, 0x8f5e,0x69db, 0x8f5f,0x8f70, 0x8f61,0x8f94,
0x8f62,0x8f79, 0x8f64,0x8f73, 0x8fa6,0x529e, 0x8fad,0x8f9e, 0x8fae,0x8fab,
0x8faf,0x8fa9, 0x8fb2,0x519c, 0x8fc6,0x8fe4, 0x8ff4,0x56de, 0x8ffa,0x4e43,
0x8fff,0x9002, 0x9015,0x8ff3, 0x9019,0x8fd9, 0x9023,0x8fde, 0x9031,0x5468,
0x9032,0x8fdb, 0x9049,0x4fa6, 0x904a,0x6e38, 0x904b,0x8fd0, 0x904e,0x8fc7,
0x9054,0x8fbe, 0x9055,0x8fdd, 0x9059,0x9065, 0x905c,0x900a, 0x905d,0x6c93,
0x905e,0x9012, 0x9060,0x8fdc, 0x9069,0x9002, 0x906f,0x9041, 0x9070,0x9012,
0x9072,0x8fdf, 0x9076,0x7ed5, 0x9077,0x8fc1, 0x9078,0x9009, 0x907a,0x9057,
0x907c,0x8fbd, 0x9081,0x8fc8, 0x9084,0x8fd8, 0x9087,0x8fe9, 0x908a,0x8fb9,
0x908f,0x903b, 0x9090,0x9026, 0x90c3,0x5408, 0x90df,0x90cf, 0x90f5,0x90ae,
0x9101,0x90b6, 0x9106,0x90d3, 0x9109,0x4e61, 0x9112,0x90b9, 0x9114,0x90ac,
0x9116,0x90e7, 0x9118,0x5889, 0x9126,0x8bb8, 0x9127,0x9093, 0x912d,0x90d1,
0x9130,0x90bb, 0x9132,0x90f8, 0x9134,0x90ba, 0x9136,0x90d0, 0x913a,0x909d,
0x9148,0x90e6, 0x9183,0x814c, 0x9186,0x76cf, 0x919c,0x4e11, 0x919e,0x915d,
0x91ab,0x533b, 0x91ac,0x9171, 0x91b1,0x7c95, 0x91c0,0x917f, 0x91c1,0x8845,
0x91c3,0x917e, 0x91c5,0x917d, 0x91c6,0x91c7, 0x91cb,0x91ca, 0x91d0,0x5398,
0x91d3,0x9486, 0x91d4,0x9487, 0x91d5,0x948c, 0x91d7,0x948a, 0x91d8,0x9489,
0x91d9,0x948b, 0x91dd,0x9488, 0x91e3,0x9493, 0x91e4,0x9490, 0x91e6,0x6263,
0x91e7,0x948f, 0x91e9,0x9492, 0x91f4,0x710a, 0x91f5,0x9497, 0x91f7,0x948d,
0x91f9,0x9495, 0x9200,0x94af, 0x9201,0x94ab, 0x9204,0x94ad, 0x9205,0x94a5,
0x9206,0x94c5, 0x9209,0x94a0, 0x920d,0x949d, 0x9210,0x94a4, 0x9211,0x94a3,
0x9214,0x949e, 0x9215,0x94ae, 0x921e,0x94a7, 0x9223,0x9499, 0x9225,0x94ac,
0x9226,0x949b, 0x9227,0x94aa, 0x922e,0x94cc, 0x9230,0x94c8, 0x9233,0x94b6,
0x9234,0x94c3, 0x9237,0x94b4, 0x9238,0x94b9, 0x9239,0x94cd, 0x923a,0x94b0,
0x923d,0x94b8, 0x923e,0x94c0, 0x923f,0x94bf, 0x9240,0x94be, 0x9245,0x949c,
0x9246,0x94bb, 0x9248,0x94ca, 0x9249,0x94c9, 0x924b,0x5228, 0x924d,0x94cb,
0x924f,0x9504, 0x9251,0x94c2, 0x9257,0x94b3, 0x925a,0x94c6, 0x925b,0x94c5,
0x925e,0x94ba, 0x9264,0x94a9, 0x9266,0x94b2, 0x926c,0x94bc, 0x926d,0x94bd,
0x9272,0x950e, 0x9278,0x94f0, 0x927a,0x94d2, 0x927b,0x94ec, 0x927f,0x94ea,
0x9280,0x94f6, 0x9283,0x94f3, 0x9285,0x94dc, 0x9291,0x94e3, 0x9293,0x94e8,
0x9295,0x94c1, 0x9296,0x94e2, 0x9298,0x94ed, 0x929a,0x94eb, 0x929c,0x8854,
0x92a0,0x94d1, 0x92a3,0x94f7, 0x92a5,0x94f1, 0x92a6,0x94df, 0x92a8,0x94f5,
0x92a9,0x94e5, 0x92aa,0x94d5, 0x92ab,0x94ef, 0x92ac,0x94d0, 0x92b2,0x710a,
0x92b3,0x9510, 0x92b5,0x94ff, 0x92b7,0x9500, 0x92b9,0x9508, 0x92bb,0x9511,
0x92bc,0x9509, 0x92c1,0x94dd, 0x92c2,0x9545, 0x92c3,0x9512, 0x92c5,0x950c,
0x92c7,0x94a1, 0x92cc,0x94e4, 0x92cd,0x9b3b, 0x92cf,0x94d7, 0x92d2,0x950b,
0x92dd,0x950a, 0x92df,0x9513, 0x92e4,0x9504, 0x92e6,0x9514, 0x92e8,0x9507,
0x92ea,0x94fa, 0x92ee,0x94d6, 0x92ef,0x9506, 0x92f0,0x9502, 0x92f1,0x94fd,
0x92f8,0x952f, 0x92fc,0x94a2, 0x9301,0x951e, 0x9304,0x5f55, 0x9306,0x9516,
0x9308,0x9529, 0x9310,0x9525, 0x9312,0x9515, 0x9315,0x951f, 0x9318,0x9524,
0x9319,0x9531, 0x931a,0x94ee, 0x931b,0x951b, 0x931e,0x9566, 0x931f,0x952c,
0x9320,0x952d, 0x9321,0x951c, 0x9322,0x94b1, 0x9326,0x9526, 0x9328,0x951a,
0x932b,0x9521, 0x932e,0x9522, 0x932f,0x9519, 0x9333,0x9530, 0x9336,0x8868,
0x9338,0x94fc, 0x9346,0x9494, 0x9347,0x9534, 0x934b,0x9505, 0x934d,0x9540,
0x9354,0x9537, 0x9358,0x94e1, 0x935a,0x9496, 0x935b,0x953b, 0x9364,0x9538,
0x9365,0x9532, 0x936c,0x9539, 0x9370,0x953e, 0x9375,0x952e, 0x9376,0x9536,
0x937a,0x9517, 0x937c,0x9488, 0x937e,0x953a, 0x9382,0x9541, 0x938a,0x9551,
0x938c,0x9570, 0x9392,0x8028, 0x9394,0x7194, 0x9396,0x9501, 0x9397,0x67aa,
0x9398,0x9549, 0x939a,0x9524, 0x939d,0x951d, 0x93a2,0x94a8, 0x93a6,0x954f,
0x93a7,0x94e0, 0x93a9,0x94e9, 0x93aa,0x953c, 0x93ac,0x9550, 0x93ae,0x9547,
0x93b0,0x9552, 0x93b3,0x954d, 0x93b5,0x9553, 0x93c3,0x955e, 0x93c7,0x955f,
0x93c8,0x94fe, 0x93cc,0x9546, 0x93cd,0x9559, 0x93d1,0x955d, 0x93d7,0x94ff,
0x93d8,0x9535, 0x93dc,0x9557, 0x93dd,0x9558, 0x93de,0x955b, 0x93df,0x94f2,
0x93e1,0x955c, 0x93e2,0x9556, 0x93e4,0x9542, 0x93e8,0x933e, 0x93ec,0x7f45,
0x93f5,0x94e7, 0x93f7,0x9564, 0x93f9,0x956a, 0x93fd,0x9508, 0x9400,0x67dc,
0x9403,0x94d9, 0x940b,0x94f4, 0x9410,0x9563, 0x9411,0x9532, 0x9412,0x94f9,
0x9413,0x9566, 0x9414,0x9561, 0x9418,0x949f, 0x9419,0x956b, 0x9420,0x9568,
0x9428,0x9544, 0x942b,0x954c, 0x942e,0x9570, 0x9431,0x5251, 0x9432,0x956f,
0x9433,0x956d, 0x9435,0x94c1, 0x9436,0x949a, 0x9438,0x94ce, 0x943a,0x94db,
0x943f,0x9571, 0x9440,0x953f, 0x9444,0x94f8, 0x944a,0x956c, 0x944c,0x9554,
0x9451,0x9274, 0x9452,0x9274, 0x9460,0x94c4, 0x9463,0x9573, 0x9464,0x5228,
0x946a,0x7089, 0x946d,0x9567, 0x9470,0x94a5, 0x9472,0x9576, 0x9473,0x952e,
0x9475,0x7f50, 0x9477,0x954a, 0x947c,0x9523, 0x947d,0x94bb, 0x947e,0x92ae,
0x947f,0x51ff, 0x9481,0x9562, 0x9482,0x954b, 0x9577,0x957f, 0x9580,0x95e8,
0x9582,0x95e9, 0x9583,0x95ea, 0x9586,0x95eb, 0x9589,0x95ed, 0x958b,0x5f00,
0x958c,0x95f6, 0x958e,0x95f3, 0x958f,0x95f0, 0x9591,0x95f2, 0x9592,0x95f2,
0x9593,0x95f4, 0x9594,0x95f5, 0x9598,0x95f8, 0x95a1,0x9602, 0x95a3,0x9601,
0x95a4,0x9601, 0x95a5,0x9600, 0x95a8,0x95fa, 0x95a9,0x95fd, 0x95ab,0x9603,
0x95ac,0x9606, 0x95ad,0x95fe, 0x95b1,0x9605, 0x95b6,0x960a, 0x95b9,0x9609,
0x95bb,0x960e, 0x95bc,0x960f, 0x95bd,0x960d, 0x95be,0x9608, 0x95bf,0x960c,
0x95c0,0x54c4, 0x95c3,0x9612, 0x95c6,0x677f, 0x95c7,0x6697, 0x95c8,0x95f1,
0x95ca,0x9614, 0x95cb,0x9615, 0x95cc,0x9611, 0x95d0,0x9617, 0x95d4,0x9616,
0x95d5,0x9619, 0x95d6,0x95ef, 0x95dc,0x5173, 0x95de,0x961a, 0x95e1,0x9610,
0x95e2,0x8f9f, 0x95e5,0x95fc, 0x9623,0x5c79, 0x9624,0x9640, 0x9628,0x5384,
0x962c,0x5751, 0x962f,0x5740, 0x9658,0x9649, 0x965d,0x9655, 0x965e,0x5347,
0x9663,0x9635, 0x9670,0x9634, 0x9673,0x9648, 0x9678,0x9646, 0x967d,0x9633,
0x9684,0x5824, 0x9689,0x9667, 0x968a,0x961f, 0x968e,0x9636, 0x9695,0x9668,
0x969b,0x9645, 0x96a4,0x9893, 0x96a8,0x968f, 0x96aa,0x9669, 0x96ae,0x8dfb,
0x96b1,0x9690, 0x96b4,0x9647, 0x96b8,0x96b6, 0x96bb,0x53ea, 0x96cb,0x96bd,
0x96d6,0x867d, 0x96d9,0x53cc, 0x96db,0x96cf, 0x96dc,0x6742, 0x96de,0x9e21,
0x96e2,0x79bb, 0x96e3,0x96be, 0x96f0,0x6c1b, 0x96f2,0x4e91, 0x96fb,0x7535,
0x9711,0x6cbe, 0x9712,0x9634, 0x9724,0x6e9c, 0x9727,0x96fe, 0x973d,0x9701,
0x9742,0x96f3, 0x9743,0x970d, 0x9744,0x972d, 0x9748,0x7075, 0x975a,0x9753,
0x975c,0x9759, 0x9766,0x8146, 0x9768,0x9765, 0x977d,0x7eca, 0x9780,0x9f17,
0x9781,0x97b4, 0x978f,0x5de9, 0x979c,0x7ef1, 0x97a1,0x9f19, 0x97a6,0x79cb,
0x97c1,0x7f30, 0x97c3,0x9791, 0x97c6,0x5343, 0x97c9,0x97af, 0x97cb,0x97e6,
0x97cc,0x97e7, 0x97d3,0x97e9, 0x97d9,0x97ea, 0x97dc,0x97ec, 0x97dd,0x97b2,
0x97de,0x97eb, 0x97fb,0x97f5, 0x97ff,0x54cd, 0x9801,0x9875, 0x9802,0x9876,
0x9803,0x9877, 0x9805,0x9879, 0x9806,0x987a, 0x9807,0x9878, 0x9808,0x987b,
0x980a,0x987c, 0x980c,0x9882, 0x980e,0x9880, 0x980f,0x9883, 0x9810,0x9884,
0x9811,0x987d, 0x9812,0x9881, 0x9813,0x987f, 0x9816,0x6cee, 0x9817,0x9887,
0x9818,0x9886, 0x981c,0x988c, 0x9821,0x9889, 0x9824,0x9890, 0x9826,0x988f,
0x982b,0x4fef, 0x982d,0x5934, 0x9830,0x988a, 0x9837,0x9894, 0x9838,0x9888,
0x9839,0x9893, 0x983b,0x9891, 0x9846,0x9897, 0x984c,0x9898, 0x984d,0x989d,
0x984e,0x989a, 0x984f,0x989c, 0x9850,0x8be8, 0x9853,0x989b, 0x9858,0x613f,
0x9859,0x98a1, 0x985b,0x98a0, 0x985e,0x7c7b, 0x9862,0x989f, 0x9865,0x98a2,
0x9867,0x987e, 0x986b,0x98a4, 0x986f,0x663e, 0x9870,0x98a6, 0x9871,0x9885,
0x9873,0x989e, 0x9874,0x98a7, 0x98a8,0x98ce, 0x98ae,0x98d1, 0x98af,0x98d2,
0x98b1,0x53f0, 0x98b3,0x522e, 0x98b6,0x98d3, 0x98ba,0x626c, 0x98bc,0x98d5,
0x98bf,0x5e06, 0x98c4,0x98d8, 0x98c6,0x98d9, 0x98db,0x98de, 0x98e2,0x9965,
0x98e9,0x9968, 0x98ea,0x996a, 0x98eb,0x996b, 0x98ed,0x996c, 0x98ef,0x996d,
0x98f2,0x996e, 0x98f4,0x9974, 0x98fc,0x9972, 0x98fd,0x9971, 0x98fe,0x9970,
0x9903,0x997a, 0x9905,0x997c, 0x9908,0x7ccd, 0x9909,0x9977, 0x990a,0x517b,
0x990c,0x9975, 0x9911,0x997d, 0x9912,0x9981, 0x9913,0x997f, 0x9918,0x9980,
0x991a,0x80b4, 0x991b,0x9984, 0x991e,0x996f, 0x9921,0x9985, 0x9927,0x5582,
0x9928,0x9986, 0x992c,0x7cca, 0x9931,0x7cc7, 0x9933,0x9967, 0x9935,0x5582,
0x993c,0x9969, 0x993d,0x9988, 0x993e,0x998f, 0x993f,0x998a, 0x9943,0x998d,
0x9945,0x9992, 0x9947,0x996b, 0x9948,0x9990, 0x9949,0x9991, 0x994b,0x9988,
0x994c,0x9994, 0x9951,0x9965, 0x9952,0x9976, 0x9957,0x98e8, 0x995c,0x990d,
0x995e,0x998b, 0x995f,0x9977, 0x99ac,0x9a6c, 0x99ad,0x9a6d, 0x99ae,0x51af,
0x99b1,0x9a6e, 0x99b3,0x9a70, 0x99b4,0x9a6f, 0x99bd,0x7d77, 0x99c1,0x9a73,
0x99d0,0x9a7b, 0x99d1,0x9a7d, 0x99d2,0x9a79, 0x99d4,0x9a75, 0x99d5,0x9a7e,
0x99d8,0x9a80, 0x99d9,0x9a78, 0x99db,0x9a76, 0x99dd,0x9a7c, 0x99df,0x9a77,
0x99e2,0x9a88, 0x99ed,0x9a87, 0x99ee,0x9a73, 0x99f1,0x9a86, 0x99ff,0x9a8f,
0x9a01,0x9a8b, 0x9a03,0x5446, 0x9a05,0x9a93, 0x9a0d,0x9a92, 0x9a0e,0x9a91,
0x9a0f,0x9a90, 0x9a16,0x9a9b, 0x9a19,0x9a97, 0x9a23,0x9b03, 0x9a2b,0x9a9e,
0x9a2d,0x9a98, 0x9a2e,0x9a9d, 0x9a30,0x817e, 0x9a32,0x8349, 0x9a36,0x9a7a,
0x9a37,0x9a9a, 0x9a38,0x9a9f, 0x9a3e,0x9aa1, 0x9a40,0x84e6, 0x9a41,0x9a9c,
0x9a42,0x9a96, 0x9a43,0x9aa0, 0x9a44,0x9aa2, 0x9a45,0x9a71, 0x9a4a,0x9a85,
0x9a4d,0x9a81, 0x9a4f,0x9aa3, 0x9a55,0x9a84, 0x9a57,0x9a8c, 0x9a5a,0x60ca,
0x9a5b,0x9a7f, 0x9a5f,0x9aa4, 0x9a62,0x9a74, 0x9a64,0x9aa7, 0x9a65,0x9aa5,
0x9a66,0x9aa6, 0x9a6a,0x9a8a, 0x9a6b,0x9a89, 0x9aaf,0x80ae, 0x9abb,0x80ef,
0x9abe,0x9ca0, 0x9abf,0x80fc, 0x9ac6,0x818a, 0x9acf,0x9ac5, 0x9ad2,0x810f,
0x9ad4,0x4f53, 0x9ad5,0x9acc, 0x9ad6,0x9acb, 0x9ae3,0x4eff, 0x9aee,0x53d1,
0x9af1,0x2171, 0x9af3,0x9ae6, 0x9b06,0x677e, 0x9b0d,0x80e1, 0x9b12,0x7f1c,
0x9b1a,0x987b, 0x9b22,0x9b13, 0x9b25,0x6597, 0x9b27,0x95f9, 0x9b28,0x54c4,
0x9b29,0x960b, 0x9b2e,0x9604, 0x9b31,0x90c1, 0x9b4a,0x872e, 0x9b4e,0x9b49,
0x9b58,0x9b47, 0x9b5a,0x9c7c, 0x9b6f,0x9c81, 0x9b74,0x9c82, 0x9b77,0x9c7f,
0x9b7c,0x9c88, 0x9b86,0x9c9a, 0x9b90,0x9c90, 0x9b91,0x9c8d, 0x9b92,0x9c8b,
0x9b9a,0x9c92, 0x9b9e,0x9c95, 0x9baa,0x9c94, 0x9bab,0x9c9b, 0x9bad,0x9c91,
0x9bae,0x9c9c, 0x9bc0,0x9ca7, 0x9bc1,0x9ca0, 0x9bc7,0x9ca9, 0x9bc9,0x9ca4,
0x9bca,0x9ca8, 0x9bd4,0x9cbb, 0x9bd6,0x9cad, 0x9bd7,0x9c9e, 0x9bdb,0x9cb7,
0x9be1,0x9cb1, 0x9be2,0x9cb5, 0x9be4,0x9cb2, 0x9be7,0x9cb3, 0x9be8,0x9cb8,
0x9bea,0x9cae, 0x9beb,0x9cb0, 0x9bf0,0x9cb6, 0x9bfd,0x9cab, 0x9c08,0x9cbd,
0x9c09,0x9cc7, 0x9c0d,0x9cc5, 0x9c12,0x9cc6, 0x9c13,0x9cc3, 0x9c23,0x9ca5,
0x9c25,0x9ccf, 0x9c28,0x9cce, 0x9c29,0x9cd0, 0x9c2d,0x9ccd, 0x9c31,0x9ca2,
0x9c32,0x9ccc, 0x9c33,0x9cd3, 0x9c37,0x9ca6, 0x9c39,0x9ca3, 0x9c3b,0x9cd7,
0x9c3c,0x9cdb, 0x9c3e,0x9cd4, 0x9c48,0x9cd5, 0x9c49,0x9cd6, 0x9c4d,0x9c85,
0x9c52,0x9cdf, 0x9c54,0x9cdd, 0x9c56,0x9cdc, 0x9c57,0x9cde, 0x9c58,0x9c9f,
0x9c5f,0x9c8e, 0x9c60,0x810d, 0x9c63,0x9cdd, 0x9c67,0x9ce2, 0x9c6d,0x9c9a,
0x9c77,0x9cc4, 0x9c78,0x9c88, 0x9c7a,0x9ca1, 0x9ce5,0x9e1f, 0x9ce7,0x51eb,
0x9ce9,0x9e20, 0x9cf3,0x51e4, 0x9cf4,0x9e23, 0x9cf5,0x9e28, 0x9cf6,0x9e22,
0x9d03,0x89d6, 0x9d06,0x9e29, 0x9d07,0x9e28, 0x9d08,0x96c1, 0x9d09,0x9e26,
0x9d12,0x4ee4, 0x9d15,0x9e35, 0x9d1b,0x9e33, 0x9d1d,0x9e32, 0x9d1f,0x9e31,
0x9d23,0x9e2a, 0x9d26,0x9e2f, 0x9d28,0x9e2d, 0x9d2f,0x9e38, 0x9d30,0x9e39,
0x9d3b,0x9e3f, 0x9d3f,0x9e3d, 0x9d42,0x9e3a, 0x9d43,0x9e3c, 0x9d51,0x9e43,
0x9d52,0x9e46, 0x9d53,0x9e41, 0x9d5c,0x9e48, 0x9d5d,0x9e45, 0x9d60,0x9e44,
0x9d61,0x9e49, 0x9d6a,0x9e4c, 0x9d6c,0x9e4f, 0x9d6f,0x9e4e, 0x9d70,0x96d5,
0x9d72,0x9e4a, 0x9d87,0x9e2b, 0x9d89,0x9e51, 0x9d98,0x9e55, 0x9d9a,0x9e57,
0x9da9,0x9e5c, 0x9daf,0x83ba, 0x9db4,0x9e64, 0x9db8,0x5f31, 0x9dbb,0x9e58,
0x9dbc,0x9e63, 0x9dbf,0x9e5a, 0x9dc2,0x9e5e, 0x9dd3,0x9e67, 0x9dd7,0x9e25,
0x9dd9,0x9e37, 0x9dda,0x9e68, 0x9de5,0x9e36, 0x9de6,0x9e6a, 0x9def,0x9e69,
0x9df0,0x71d5, 0x9df2,0x9e6b, 0x9df3,0x9e47, 0x9df8,0x9e6c, 0x9df9,0x9e70,
0x9dfa,0x9e6d, 0x9e15,0x9e2c, 0x9e1a,0x9e66, 0x9e1b,0x9e73, 0x9e1d,0x9e42,
0x9e1e,0x9e3e, 0x9e75,0x5364, 0x9e79,0x54b8, 0x9e7a,0x9e7e, 0x9e7c,0x7877,
0x9e7d,0x76d0, 0x9e83,0x6d0b, 0x9e91,0x8c8c, 0x9e97,0x4e3d, 0x9ea4,0x7c97,
0x9ea5,0x9ea6, 0x9ea9,0x9eb8, 0x9ead,0x5305, 0x9eb5,0x9762, 0x9ebc,0x4e48,
0x9ec3,0x9ec4, 0x9ecc,0x9ec9, 0x9ede,0x70b9, 0x9ee8,0x515a, 0x9ef0,0x7f1c,
0x9ef2,0x9eea, 0x9ef4,0x9709, 0x9ef7,0x9ee9, 0x9efd,0x9efe, 0x9eff,0x9f0b,
0x9f07,0x9ccc, 0x9f09,0x9f0d, 0x9f1e,0x51ac, 0x9f34,0x9f39, 0x9f4a,0x9f50,
0x9f4b,0x658b, 0x9f4e,0x8d4d, 0x9f4f,0x9f51, 0x9f52,0x9f7f, 0x9f54,0x9f80,
0x9f59,0x9f85, 0x9f5c,0x9f87, 0x9f5f,0x9f83, 0x9f60,0x9f86, 0x9f61,0x9f84,
0x9f63,0x51fa, 0x9f66,0x9f88, 0x9f67,0x556e, 0x9f6a,0x9f8a, 0x9f6c,0x9f89,
0x9f70,0x548b, 0x9f72,0x9f8b, 0x9f76,0x816d, 0x9f77,0x9f8c, 0x9f8d,0x9f99,
0x9f90,0x5e9e, 0x9f94,0x9f9a, 0x9f95,0x9f9b, 0x9f9c,0x9f9f, 0x9fa2,0x548c,
0x9fa4,0x8c10, 0xfa0c,0x5140, 0xfe30,0xff1a, 0xfe31,0xff5c, 0xfe35,0xff08,
0xfe3f,0x2227, 0xfe40,0x2228, 0xfe50,0xff0c, 0xfe51,0x3001, 0xfe52,0xff0e,
0xfe54,0xff1b, 0xfe55,0xff1a, 0xfe56,0xff1f, 0xfe57,0xff01, 0xfe59,0xff08,
0xfe5a,0xff09, 0xfe5b,0xff5b, 0xfe5c,0xff5d, 0xfe5d,0x3014, 0xfe5e,0x3015,
0xfe5f,0xff03, 0xfe60,0xff06, 0xfe61,0xff0a, 0xfe68,0xff3c, 0xff02,0x201d,
0xff07,0x2019, 0xffe2,0x300c, 0xffe4,0x2506
};

View File

@ -0,0 +1,69 @@
#import "VXHanConvert.h"
const size_t vxSC2TCTableSize = 8189;
extern unsigned short vxSC2TCTable[];
const size_t vxTC2SCTableSize = 3059;
extern unsigned short vxTC2SCTable[];
struct VXHCData
{
unsigned short key, value;
};
int VXHCCompare(const void *a, const void *b)
{
unsigned short x=((const struct VXHCData*)a)->key, y=((const struct VXHCData*)b)->key;
if (x==y) return 0;
if (x<y) return -1;
return 1;
}
unsigned short VXHCFind(unsigned key, unsigned short *table, size_t size)
{
struct VXHCData k;
k.key=key;
struct VXHCData *d=(struct VXHCData*)bsearch(&k, table, size, sizeof(struct VXHCData), VXHCCompare);
if (!d) return 0;
return d->value;
}
unsigned short VXUCS2TradToSimpChinese(unsigned short c)
{
return VXHCFind(c, vxTC2SCTable, vxTC2SCTableSize);
}
unsigned short VXUCS2SimpToTradChinese(unsigned short c)
{
return VXHCFind(c, vxSC2TCTable, vxSC2TCTableSize);
}
@implementation VXHanConvert
+ (NSString *)convertToSimplifiedFrom:(NSString *)string NS_SWIFT_NAME(convertToSimplified(from:))
{
NSData *utf16Data = [string dataUsingEncoding:NSUTF16StringEncoding];
unsigned short * bytes = (unsigned short *)utf16Data.bytes;
for(NSInteger i = 0; i < utf16Data.length; i++) {
unsigned short c = bytes[i];
unsigned short value = VXUCS2TradToSimpChinese(c);
bytes[i] = value ? value : c;
}
return [[NSString alloc] initWithData:utf16Data encoding:NSUTF16StringEncoding];
}
+ (NSString *)convertToTraditionalFrom:(NSString *)string NS_SWIFT_NAME(convertToTraditional(from:))
{
NSData *utf16Data = [string dataUsingEncoding:NSUTF16StringEncoding];
unsigned short * bytes = (unsigned short *)utf16Data.bytes;
for(NSInteger i = 0; i < utf16Data.length; i++) {
unsigned short c = bytes[i];
unsigned short value = VXUCS2SimpToTradChinese(c);
bytes[i] = value ? value : c;
}
return [[NSString alloc] initWithData:utf16Data encoding:NSUTF16StringEncoding];
}
@end

View File

@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// The legacy chinese conversion library from OpenVanilla.
@interface VXHanConvert : NSObject
/// Converts to Simplified Chinese from Traditional Chinese.
/// @param string The traditional Chinese text.
+ (NSString *)convertToSimplifiedFrom:(NSString *)string NS_SWIFT_NAME(convertToSimplified(from:));
/// Convert to Traditional Chinese from Simplified CHinese.
/// @param string The Simplified Chinese text.
+ (NSString *)convertToTraditionalFrom:(NSString *)string NS_SWIFT_NAME(convertToTraditional(from:));
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,16 @@
import XCTest
@testable import VXHanConvert
final class VXHanConvertTests: XCTestCase {
func testSC2TC() {
let text = "简体中文转繁体中文"
let converted = VXHanConvert.convertToTraditional(from: text)
XCTAssert(converted == "簡體中文轉繁體中文")
}
func testTC2SC() {
let text = "繁體中文轉簡體中文"
let converted = VXHanConvert.convertToSimplified(from: text)
XCTAssert(converted == "繁体中文转简体中文")
}
}

View File

@ -19,14 +19,14 @@
<window title="Bopomofo Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" animationBehavior="default" id="1" userLabel="Window - Preferences">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="401" y="295" width="475" height="364"/>
<rect key="contentRect" x="401" y="295" width="475" height="438"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="475" height="364"/>
<rect key="frame" x="0.0" y="0.0" width="475" height="438"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="11">
<rect key="frame" x="38" y="326" width="183" height="17"/>
<rect key="frame" x="38" y="400" width="183" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Bopomofo Keyboard Layout:" id="12">
<font key="font" metaFont="system"/>
@ -35,7 +35,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="124">
<rect key="frame" x="225" y="289" width="156" height="26"/>
<rect key="frame" x="225" y="363" width="156" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="127">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -47,7 +47,7 @@
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="125">
<rect key="frame" x="16" y="295" width="205" height="17"/>
<rect key="frame" x="16" y="369" width="205" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Alphanumeric Keyboard Layout:" id="126">
<font key="font" metaFont="system"/>
@ -56,7 +56,7 @@
</textFieldCell>
</textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="109">
<rect key="frame" x="226" y="235" width="217" height="18"/>
<rect key="frame" x="226" y="309" width="217" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Space key chooses candidate" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="110">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -67,7 +67,7 @@
</connections>
</button>
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uHU-aL-du7">
<rect key="frame" x="228" y="262" width="209" height="25"/>
<rect key="frame" x="228" y="336" width="209" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="jQC-12-UuK">
<font key="font" metaFont="system"/>
@ -84,7 +84,7 @@
</connections>
</comboBox>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ETa-09-qWI">
<rect key="frame" x="38" y="268" width="183" height="16"/>
<rect key="frame" x="38" y="342" width="183" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Selection Keys:" id="FnD-oH-El5">
<font key="font" metaFont="system"/>
@ -93,7 +93,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3">
<rect key="frame" x="225" y="320" width="132" height="26"/>
<rect key="frame" x="225" y="394" width="132" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Standard" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="6" id="4">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -114,18 +114,18 @@
</popUpButtonCell>
</popUpButton>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
<rect key="frame" x="226" y="213" width="229" height="18"/>
<rect key="frame" x="226" y="287" width="229" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="ESC key clears entire input buffer" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="f2j-xD-4xK">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="atP-oI-qLL"/>
<binding destination="32" name="value" keyPath="values.EscToCleanInputBuffer" id="tD5-7J-qTF"/>
</connections>
</button>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="13">
<rect key="frame" x="63" y="178" width="155" height="17"/>
<rect key="frame" x="63" y="252" width="155" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Show Candidate Phrase:" id="14">
<font key="font" metaFont="system"/>
@ -134,7 +134,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="23">
<rect key="frame" x="80" y="132" width="138" height="17"/>
<rect key="frame" x="80" y="206" width="138" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate List Style:" id="24">
<font key="font" metaFont="system"/>
@ -143,7 +143,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28">
<rect key="frame" x="84" y="85" width="134" height="17"/>
<rect key="frame" x="84" y="159" width="134" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate Text Size:" id="29">
<font key="font" metaFont="system"/>
@ -151,8 +151,17 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MBE-hh-AxG">
<rect key="frame" x="45" y="103" width="173" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Chinese Conversion Engine:" id="hwF-gg-TYW">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="15">
<rect key="frame" x="227" y="157" width="213" height="38"/>
<rect key="frame" x="227" y="231" width="213" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="206" height="18"/>
@ -177,8 +186,34 @@
<binding destination="32" name="selectedTag" keyPath="values.SelectPhraseAfterCursorAsCandidate" id="104"/>
</connections>
</matrix>
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rAU-Xz-M2R">
<rect key="frame" x="227" y="82" width="213" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="206" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="ipi-25-nsn">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<cells>
<column>
<buttonCell type="radio" title="OpenCC" imagePosition="left" alignment="left" state="on" inset="2" id="gw4-Y9-fH4">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<buttonCell type="radio" title="Legacy VXHanConvert" imagePosition="left" alignment="left" tag="1" inset="2" id="Wfr-Lt-eVE">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</column>
</cells>
<connections>
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionEngine" id="qf2-qK-OJ0"/>
</connections>
</matrix>
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
<rect key="frame" x="227" y="111" width="207" height="38"/>
<rect key="frame" x="227" y="185" width="207" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="88" height="18"/>
@ -204,7 +239,7 @@
</connections>
</matrix>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="90">
<rect key="frame" x="224" y="77" width="86" height="26"/>
<rect key="frame" x="224" y="151" width="86" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="18" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="18" imageScaling="proportionallyDown" inset="2" selectedItem="96" id="91">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -226,8 +261,12 @@
<binding destination="32" name="selectedTag" keyPath="values.CandidateListTextSize" id="107"/>
</connections>
</popUpButton>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="BtG-38-RSK">
<rect key="frame" x="12" y="132" width="443" height="5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</box>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fc2-qh-r1H">
<rect key="frame" x="225" y="19" width="218" height="18"/>
<rect key="frame" x="226" y="19" width="218" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Check for updates automatically" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="Z9t-P0-BLF">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -239,7 +278,7 @@
</button>
</subviews>
</view>
<point key="canvasLocation" x="148.5" y="196"/>
<point key="canvasLocation" x="148.5" y="233"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="32"/>
</objects>

View File

@ -0,0 +1,54 @@
//
// EmacsKeyHelper.swift
//
// Copyright (c) 2011 The McBopomofo Project.
//
// Contributors:
// Mengjuei Hsieh (@mjhsieh)
// Weizhong Yang (@zonble)
//
// Based on the Syrup Project and the Formosana Library
// by Lukhnos Liu (@lukhnos).
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
import Cocoa
@objc enum McBopomofoEmacsKey: UInt16 {
case none = 0
case forward = 6 // F
case backward = 2 // B
case home = 1 // A
case end = 5 // E
case delete = 4 // D
case nextPage = 22 // V
}
class EmacsKeyHelper: NSObject {
@objc static func detect(charCode: UniChar, flags: NSEvent.ModifierFlags) -> McBopomofoEmacsKey {
if flags.contains(.control) {
return McBopomofoEmacsKey(rawValue: charCode) ?? .none
}
return .none;
}
}

View File

@ -72,9 +72,6 @@
// current input mode
NSString *_inputMode;
// if Chinese conversion is enabled
BOOL _chineseConversionEnabled;
BOOL _halfWidthPunctuationEnabled;
}
@end

View File

@ -45,6 +45,7 @@
@import NotifierUI;
@import TooltipUI;
@import OpenCCBridge;
@import VXHanConvert;
// C++ namespace usages
using namespace std;
@ -53,40 +54,7 @@ using namespace Formosa::Gramambular;
using namespace McBopomofo;
using namespace OpenVanilla;
// default, min and max candidate list text size
static const NSInteger kDefaultCandidateListTextSize = 16;
static const NSInteger kMinKeyLabelSize = 10;
static const NSInteger kMinCandidateListTextSize = 12;
static const NSInteger kMaxCandidateListTextSize = 196;
// default, min and max composing buffer size (in codepoints)
// modern Macs can usually work up to 16 codepoints when the builder still
// walks the grid with good performance; slower Macs (like old PowerBooks)
// will start to sputter beyond 12; such is the algorithmatic complexity
// of the Viterbi algorithm used in the builder library (at O(N^2))
static const NSInteger kDefaultComposingBufferSize = 10;
static const NSInteger kMinComposingBufferSize = 4;
static const NSInteger kMaxComposingBufferSize = 20;
// user defaults (app perferences) key names; in this project we use
// NSUserDefaults throughout and do not wrap them in another config object
static NSString *const kKeyboardLayoutPreferenceKey = @"KeyboardLayout";
static NSString *const kBasisKeyboardLayoutPreferenceKey = @"BasisKeyboardLayout"; // alphanumeric ("ASCII") input basis
static NSString *const kFunctionKeyKeyboardLayoutPreferenceKey = @"FunctionKeyKeyboardLayout"; // alphanumeric ("ASCII") input basis
static NSString *const kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey = @"FunctionKeyKeyboardLayoutOverrideIncludeShift"; // whether include shift
static NSString *const kCandidateListTextSizeKey = @"CandidateListTextSize";
static NSString *const kSelectPhraseAfterCursorAsCandidatePreferenceKey = @"SelectPhraseAfterCursorAsCandidate";
static NSString *const kUseHorizontalCandidateListPreferenceKey = @"UseHorizontalCandidateList";
static NSString *const kComposingBufferSizePreferenceKey = @"ComposingBufferSize";
static NSString *const kChooseCandidateUsingSpaceKey = @"ChooseCandidateUsingSpaceKey";
static NSString *const kChineseConversionEnabledKey = @"ChineseConversionEnabledKey";
static NSString *const kHalfWidthPunctuationEnabledKey = @"HalfWidthPunctuationEnabledKey";
static NSString *const kEscToCleanInputBufferKey = @"EscToCleanInputBufferKey";
// advanced (usually optional) settings
static NSString *const kCandidateTextFontName = @"CandidateTextFontName";
static NSString *const kCandidateKeyLabelFontName = @"CandidateKeyLabelFontName";
static NSString *const kCandidateKeys = @"CandidateKeys";
// input modes
static NSString *const kBopomofoModeIdentifier = @"org.openvanilla.inputmethod.McBopomofo.Bopomofo";
@ -106,16 +74,6 @@ enum {
kDeleteKeyCode = 117
};
typedef NS_ENUM(NSUInteger, McBpomofoEmacsKey) {
McBpomofoEmacsKeyNone,
McBpomofoEmacsKeyForward,
McBpomofoEmacsKeyBackward,
McBpomofoEmacsKeyHome,
McBpomofoEmacsKeyEnd,
McBpomofoEmacsKeyDelete,
McBpomofoEmacsKeyNextPage,
};
VTCandidateController *gCurrentCandidateController = nil;
// if DEBUG is defined, a DOT file (GraphViz format) will be written to the
@ -130,12 +88,6 @@ static inline NSString *LocalizationNotNeeded(NSString *s) {
return s;
}
// private methods
@interface McBopomofoInputMethodController ()
+ (VTHorizontalCandidateController *)horizontalCandidateController;
+ (VTVerticalCandidateController *)verticalCandidateController;
@end
@interface McBopomofoInputMethodController (VTCandidateController) <VTCandidateControllerDelegate>
@end
@ -201,8 +153,6 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
_composingBuffer = [[NSMutableString alloc] init];
_inputMode = kBopomofoModeIdentifier;
_chineseConversionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConversionEnabledKey];
_halfWidthPunctuationEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kHalfWidthPunctuationEnabledKey];
}
return self;
@ -212,42 +162,33 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
{
// a menu instance (autoreleased) is requested every time the user click on the input menu
NSMenu *menu = [[NSMenu alloc] initWithTitle:LocalizationNotNeeded(@"Input Method Menu")];
NSMenuItem *preferenceMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"McBopomofo Preferences", @"") action:@selector(showPreferences:) keyEquivalent:@""];
[menu addItem:preferenceMenuItem];
[menu addItemWithTitle:NSLocalizedString(@"McBopomofo Preferences", @"") action:@selector(showPreferences:) keyEquivalent:@""];
NSMenuItem *chineseConversionMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Chinese Conversion", @"") action:@selector(toggleChineseConverter:) keyEquivalent:@"g"];
chineseConversionMenuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl;
chineseConversionMenuItem.state = _chineseConversionEnabled ? NSControlStateValueOn : NSControlStateValueOff;
chineseConversionMenuItem.state = Preferences.chineseConversionEnabled ? NSControlStateValueOn : NSControlStateValueOff;
[menu addItem:chineseConversionMenuItem];
NSMenuItem *halfWidthPunctuationMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Use Half-Width Punctuations", @"") action:@selector(toggleHalfWidthPunctuation:) keyEquivalent:@""];
halfWidthPunctuationMenuItem.state = _halfWidthPunctuationEnabled ? NSControlStateValueOn : NSControlStateValueOff;
halfWidthPunctuationMenuItem.state = Preferences.halfWidthPunctuationEnabled ? NSControlStateValueOn : NSControlStateValueOff;
[menu addItem:halfWidthPunctuationMenuItem];
[menu addItem:[NSMenuItem separatorItem]];
[menu addItemWithTitle:NSLocalizedString(@"User Phrases", @"") action:NULL keyEquivalent:@""];
if (_inputMode == kPlainBopomofoModeIdentifier) {
NSMenuItem *editExcludedPhrasesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit Excluded Phrases", @"") action:@selector(openExcludedPhrasesPlainBopomofo:) keyEquivalent:@""];
[menu addItem:editExcludedPhrasesItem];
}
else {
NSMenuItem *editUserPhrasesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit User Phrases", @"") action:@selector(openUserPhrases:) keyEquivalent:@""];
[menu addItem:editUserPhrasesItem];
NSMenuItem *editExcludedPhrasesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit Excluded Phrases", @"") action:@selector(openExcludedPhrasesMcBopomofo:) keyEquivalent:@""];
[menu addItem:editExcludedPhrasesItem];
[menu addItemWithTitle:NSLocalizedString(@"Edit User Phrases", @"") action:@selector(openUserPhrases:) keyEquivalent:@""];
[menu addItemWithTitle:NSLocalizedString(@"Edit Excluded Phrases", @"") action:@selector(openExcludedPhrasesMcBopomofo:) keyEquivalent:@""];
}
NSMenuItem *reloadUserPhrasesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Reload User Phrases", @"") action:@selector(reloadUserPhrases:) keyEquivalent:@""];
[menu addItem:reloadUserPhrasesItem];
[menu addItemWithTitle:NSLocalizedString(@"Reload User Phrases", @"") action:@selector(reloadUserPhrases:) keyEquivalent:@""];
[menu addItem:[NSMenuItem separatorItem]];
NSMenuItem *updateCheckItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""];
[menu addItem:updateCheckItem];
NSMenuItem *aboutMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"About McBopomofo…", @"") action:@selector(showAbout:) keyEquivalent:@""];
[menu addItem:aboutMenuItem];
[menu addItemWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""];
[menu addItemWithTitle:NSLocalizedString(@"About McBopomofo…", @"") action:@selector(showAbout:) keyEquivalent:@""];
return menu;
}
@ -258,10 +199,7 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
[[NSUserDefaults standardUserDefaults] synchronize];
// Override the keyboard layout. Use US if not set.
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
if (!basisKeyboardLayoutID) {
basisKeyboardLayoutID = @"com.apple.keylayout.US";
}
NSString *basisKeyboardLayoutID = Preferences.basisKeyboardLayout;
[client overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
// reset the state
@ -272,49 +210,28 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
[_composingBuffer setString:@""];
// checks and populates the default settings
NSInteger keyboardLayout = [[NSUserDefaults standardUserDefaults] integerForKey:kKeyboardLayoutPreferenceKey];
switch (keyboardLayout) {
case 0:
switch (Preferences.keyboardLayout) {
case KeyboardLayoutStandard:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
break;
case 1:
case KeyboardLayoutEten:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETenLayout());
break;
case 2:
case KeyboardLayoutHsu:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HsuLayout());
break;
case 3:
case KeyboardLayoutEten26:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETen26Layout());
break;
case 4:
case KeyboardLayoutHanyuPinyin:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HanyuPinyinLayout());
break;
case 5:
case KeyboardLayoutIBM:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::IBMLayout());
break;
default:
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:kKeyboardLayoutPreferenceKey];
}
// set the size
NSInteger textSize = [[NSUserDefaults standardUserDefaults] integerForKey:kCandidateListTextSizeKey];
NSInteger previousTextSize = textSize;
if (textSize == 0) {
textSize = kDefaultCandidateListTextSize;
}
else if (textSize < kMinCandidateListTextSize) {
textSize = kMinCandidateListTextSize;
}
else if (textSize > kMaxCandidateListTextSize) {
textSize = kMaxCandidateListTextSize;
}
if (textSize != previousTextSize) {
[[NSUserDefaults standardUserDefaults] setInteger:textSize forKey:kCandidateListTextSizeKey];
}
if (![[NSUserDefaults standardUserDefaults] objectForKey:kChooseCandidateUsingSpaceKey]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kChooseCandidateUsingSpaceKey];
Preferences.keyboardLayout = KeyboardLayoutStandard;
}
[(AppDelegate *)[NSApp delegate] checkForUpdate];
@ -360,10 +277,7 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
[[NSUserDefaults standardUserDefaults] synchronize];
// Remember to override the keyboard layout again -- treat this as an activate eventy
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
if (!basisKeyboardLayoutID) {
basisKeyboardLayoutID = @"com.apple.keylayout.US";
}
NSString *basisKeyboardLayoutID = Preferences.basisKeyboardLayout;
[sender overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
_inputMode = newInputMode;
@ -388,6 +302,14 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
#pragma mark - IMKServerInput protocol methods
- (NSString *)_convertToSimplifiedChinese:(NSString *)text
{
if (Preferences.chineneConversionEngine == 1) {
return [VXHanConvert convertToSimplifiedFrom:text];
}
return [OpenCCBridge convertToSimplified:text];
}
- (void)commitComposition:(id)client
{
// if it's Terminal, we don't commit at the first call (the client of which will not be IPMDServerClientWrapper)
@ -402,9 +324,9 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
// Chinese conversion.
NSString *buffer = _composingBuffer;
BOOL chineseConversionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConversionEnabledKey];
if (chineseConversionEnabled) {
buffer = [OpenCCBridge convert:_composingBuffer];
if (Preferences.chineseConversionEnabled) {
buffer = [self _convertToSimplifiedChinese:_composingBuffer];
}
// commit the text, clear the state
@ -544,31 +466,16 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
// the user type along, the already composed text at front will
// be popped out
NSInteger _composingBufferSize = [[NSUserDefaults standardUserDefaults] integerForKey:kComposingBufferSizePreferenceKey];
NSInteger previousComposingBufferSize = _composingBufferSize;
NSInteger composingBufferSize = Preferences.composingBufferSize;
if (_composingBufferSize == 0) {
_composingBufferSize = kDefaultComposingBufferSize;
}
else if (_composingBufferSize < kMinComposingBufferSize) {
_composingBufferSize = kMinComposingBufferSize;
}
else if (_composingBufferSize > kMaxComposingBufferSize) {
_composingBufferSize = kMaxComposingBufferSize;
}
if (_composingBufferSize != previousComposingBufferSize) {
[[NSUserDefaults standardUserDefaults] setInteger:_composingBufferSize forKey:kComposingBufferSizePreferenceKey];
}
if (_builder->grid().width() > (size_t)_composingBufferSize) {
if (_builder->grid().width() > (size_t)composingBufferSize) {
if (_walkedNodes.size() > 0) {
NodeAnchor &anchor = _walkedNodes[0];
NSString *popedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
// Chinese conversion.
BOOL chineseConversionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConversionEnabledKey];
BOOL chineseConversionEnabled = Preferences.chineseConversionEnabled;
if (chineseConversionEnabled) {
popedText = [OpenCCBridge convert:popedText];
popedText = [self _convertToSimplifiedChinese:popedText];
}
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
_builder->removeHeadReadings(anchor.spanningLength);
@ -586,60 +493,11 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (string)_currentLayout
{
string layout = string("Standard_");;
NSInteger keyboardLayout = [[NSUserDefaults standardUserDefaults] integerForKey:kKeyboardLayoutPreferenceKey];
switch (keyboardLayout) {
case 0:
layout = string("Standard_");
break;
case 1:
layout = string("ETen_");
break;
case 2:
layout = string("ETen26_");
break;
case 3:
layout = string("Hsu_");
break;
case 4:
layout = string("HanyuPinyin_");
break;
case 5:
layout = string("IBM_");
break;
default:
break;
}
NSString *keyboardLayoutName = Preferences.keyboardLayoutName;
string layout = string(keyboardLayoutName.UTF8String) + string("_");
return layout;
}
- (McBpomofoEmacsKey)_detectEmacsKeyFromCharCode:(UniChar)charCode modifiers:(NSUInteger)flags
{
if (flags & NSControlKeyMask) {
char c = charCode + 'a' - 1;
if (c == 'a') {
return McBpomofoEmacsKeyHome;
}
else if (c == 'e') {
return McBpomofoEmacsKeyEnd;
}
else if (c == 'f') {
return McBpomofoEmacsKeyForward;
}
else if (c == 'b') {
return McBpomofoEmacsKeyBackward;
}
else if (c == 'd') {
return McBpomofoEmacsKeyDelete;
}
else if (c == 'v') {
return McBpomofoEmacsKeyNextPage;
}
}
return McBpomofoEmacsKeyNone;
}
- (BOOL)handleInputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
{
NSRect textFrame = NSZeroRect;
@ -665,7 +523,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
// get the unicode character code
UniChar charCode = [inputText length] ? [inputText characterAtIndex:0] : 0;
McBpomofoEmacsKey emacsKey = [self _detectEmacsKeyFromCharCode:charCode modifiers:flags];
McBopomofoEmacsKey emacsKey = [EmacsKeyHelper detectWithCharCode:charCode flags:flags];
if ([[client bundleIdentifier] isEqualToString:@"com.apple.Terminal"] && [NSStringFromClass([client class]) isEqualToString:@"IPMDServerClientWrapper"]) {
// special handling for com.apple.Terminal
@ -724,7 +582,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
// if we have candidate, it means we need to pass the event to the candidate handler
if ([_candidates count]) {
return [self _handleCandidateEventWithInputText:inputText charCode:charCode keyCode:keyCode emacsKey:(McBpomofoEmacsKey)emacsKey];
return [self _handleCandidateEventWithInputText:inputText charCode:charCode keyCode:keyCode emacsKey:(McBopomofoEmacsKey)emacsKey];
}
// If we have marker index.
@ -747,7 +605,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
// Shift + left
if ((keyCode == cursorBackwardKey || emacsKey == McBpomofoEmacsKeyBackward)
if ((keyCode == cursorBackwardKey || emacsKey == McBopomofoEmacsKeyBackward)
&& (flags & NSShiftKeyMask)) {
if (_builder->markerCursorIndex() > 0) {
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() - 1);
@ -759,7 +617,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
// Shift + Right
if ((keyCode == cursorForwardKey || emacsKey == McBpomofoEmacsKeyForward)
if ((keyCode == cursorForwardKey || emacsKey == McBopomofoEmacsKeyForward)
&& (flags & NSShiftKeyMask)) {
if (_builder->markerCursorIndex() < _builder->length()) {
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() + 1);
@ -835,7 +693,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
if (_bpmfReadingBuffer->isEmpty() && [_composingBuffer length] > 0 && (keyCode == extraChooseCandidateKey || charCode == 32 || (useVerticalMode && (keyCode == verticalModeOnlyChooseCandidateKey)))) {
if (charCode == 32) {
// if the spacebar is NOT set to be a selection key
if (![[NSUserDefaults standardUserDefaults] boolForKey:kChooseCandidateUsingSpaceKey]) {
if (!Preferences.chooseCandidateUsingSpace) {
if (_builder->cursorIndex() >= _builder->length()) {
[_composingBuffer appendString:@" "];
[self commitComposition:client];
@ -856,7 +714,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
// Esc
if (charCode == 27) {
BOOL escToClearInputBufferEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kEscToCleanInputBufferKey];
BOOL escToClearInputBufferEnabled = Preferences.escToCleanInputBuffer;
if (escToClearInputBufferEnabled) {
// if the optioon is enabled, we clear everythiong including the composing
@ -893,7 +751,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
}
// handle cursor backward
if (keyCode == cursorBackwardKey || emacsKey == McBpomofoEmacsKeyBackward) {
if (keyCode == cursorBackwardKey || emacsKey == McBopomofoEmacsKeyBackward) {
if (!_bpmfReadingBuffer->isEmpty()) {
[self beep];
}
@ -925,7 +783,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
}
// handle cursor forward
if (keyCode == cursorForwardKey || emacsKey == McBpomofoEmacsKeyForward) {
if (keyCode == cursorForwardKey || emacsKey == McBopomofoEmacsKeyForward) {
if (!_bpmfReadingBuffer->isEmpty()) {
[self beep];
}
@ -955,7 +813,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
if (keyCode == kHomeKeyCode || emacsKey == McBpomofoEmacsKeyHome) {
if (keyCode == kHomeKeyCode || emacsKey == McBopomofoEmacsKeyHome) {
if (!_bpmfReadingBuffer->isEmpty()) {
[self beep];
}
@ -976,7 +834,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
if (keyCode == kEndKeyCode || emacsKey == McBpomofoEmacsKeyEnd) {
if (keyCode == kEndKeyCode || emacsKey == McBopomofoEmacsKeyEnd) {
if (!_bpmfReadingBuffer->isEmpty()) {
[self beep];
}
@ -1029,7 +887,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
}
// Delete
if (keyCode == kDeleteKeyCode || emacsKey == McBpomofoEmacsKeyDelete) {
if (keyCode == kDeleteKeyCode || emacsKey == McBopomofoEmacsKeyDelete) {
if (_bpmfReadingBuffer->isEmpty()) {
if (![_composingBuffer length]) {
return NO;
@ -1079,7 +937,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
// if nothing is matched, see if it's a punctuation key for current layout.
string layout = [self _currentLayout];
string punctuationNamePrefix = (_halfWidthPunctuationEnabled ? string("_half_punctuation_"): string("_punctuation_"));
string punctuationNamePrefix = Preferences.halfWidthPunctuationEnabled ? string("_half_punctuation_"): string("_punctuation_");
string customPunctuation = punctuationNamePrefix + layout + string(1, (char)charCode);
if ([self _handlePunctuation:customPunctuation usingVerticalMode:useVerticalMode client:client]) {
return YES;
@ -1129,7 +987,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return NO;
}
- (BOOL)_handleCandidateEventWithInputText:(NSString *)inputText charCode:(UniChar)charCode keyCode:(NSUInteger)keyCode emacsKey:(McBpomofoEmacsKey)emacsKey
- (BOOL)_handleCandidateEventWithInputText:(NSString *)inputText charCode:(UniChar)charCode keyCode:(NSUInteger)keyCode emacsKey:(McBopomofoEmacsKey)emacsKey
{
BOOL cancelCandidateKey =
(charCode == 27) ||
@ -1152,7 +1010,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
[self candidateController:gCurrentCandidateController didSelectCandidateAtIndex:gCurrentCandidateController.selectedCandidateIndex];
return YES;
}
else if (charCode == 32 || keyCode == kPageDownKeyCode || emacsKey == McBpomofoEmacsKeyNextPage) {
else if (charCode == 32 || keyCode == kPageDownKeyCode || emacsKey == McBopomofoEmacsKeyNextPage) {
BOOL updated = [gCurrentCandidateController showNextPage];
if (!updated) {
[self beep];
@ -1186,7 +1044,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
}
else if (emacsKey == McBpomofoEmacsKeyBackward) {
else if (emacsKey == McBopomofoEmacsKeyBackward) {
BOOL updated = [gCurrentCandidateController highlightPreviousCandidate];
if (!updated) {
[self beep];
@ -1212,7 +1070,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
}
else if (emacsKey == McBpomofoEmacsKeyForward) {
else if (emacsKey == McBopomofoEmacsKeyForward) {
BOOL updated = [gCurrentCandidateController highlightNextCandidate];
if (!updated) {
[self beep];
@ -1256,7 +1114,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
return YES;
}
}
else if (keyCode == kHomeKeyCode || emacsKey == McBpomofoEmacsKeyHome) {
else if (keyCode == kHomeKeyCode || emacsKey == McBopomofoEmacsKeyHome) {
if (gCurrentCandidateController.selectedCandidateIndex == 0) {
[self beep];
@ -1268,7 +1126,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
[self updateClientComposingBuffer:_currentCandidateClient];
return YES;
}
else if ((keyCode == kEndKeyCode || emacsKey == McBpomofoEmacsKeyEnd) && [_candidates count] > 0) {
else if ((keyCode == kEndKeyCode || emacsKey == McBopomofoEmacsKeyEnd) && [_candidates count] > 0) {
if (gCurrentCandidateController.selectedCandidateIndex == [_candidates count] - 1) {
[self beep];
}
@ -1328,15 +1186,8 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (BOOL)handleEvent:(NSEvent *)event client:(id)client
{
if ([event type] == NSFlagsChanged) {
NSString *functionKeyKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kFunctionKeyKeyboardLayoutPreferenceKey];
if (!functionKeyKeyboardLayoutID) {
functionKeyKeyboardLayoutID = @"com.apple.keylayout.US";
}
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
if (!basisKeyboardLayoutID) {
basisKeyboardLayoutID = @"com.apple.keylayout.US";
}
NSString *functionKeyKeyboardLayoutID = Preferences.functionKeyboardLayout;
NSString *basisKeyboardLayoutID = Preferences.basisKeyboardLayout;
// If no override is needed, just return NO.
if ([functionKeyKeyboardLayoutID isEqualToString:basisKeyboardLayoutID]) {
@ -1344,7 +1195,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
}
// Function key pressed.
BOOL includeShift = [[NSUserDefaults standardUserDefaults] boolForKey:kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey];
BOOL includeShift = Preferences.functionKeyKeyboardLayoutOverrideIncludeShiftKey;
if (([event modifierFlags] & ~NSShiftKeyMask) || (([event modifierFlags] & NSShiftKeyMask) && includeShift)) {
// Override the keyboard layout and let the OS do its thing
[client overrideKeyboardWithKeyboardNamed:functionKeyKeyboardLayoutID];
@ -1417,10 +1268,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (size_t)actualCandidateCursorIndex
{
size_t cursorIndex = _builder->cursorIndex();
BOOL candidatePhraseLocatedAfterCursor = [[NSUserDefaults standardUserDefaults] boolForKey:kSelectPhraseAfterCursorAsCandidatePreferenceKey];
if (candidatePhraseLocatedAfterCursor) {
if (Preferences.selectPhraseAfterCursorAsCandidate) {
// MS Phonetics IME style, phrase is *after* the cursor, i.e. cursor is always *before* the phrase
if (cursorIndex < _builder->length()) {
++cursorIndex;
@ -1438,12 +1286,11 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (void)_showCandidateWindowUsingVerticalMode:(BOOL)useVerticalMode client:(id)client
{
// set the candidate panel style
BOOL useHorizontalCandidateList = [[NSUserDefaults standardUserDefaults] boolForKey:kUseHorizontalCandidateListPreferenceKey];
if (useVerticalMode) {
gCurrentCandidateController = [McBopomofoInputMethodController verticalCandidateController];
}
else if (useHorizontalCandidateList) {
else if (Preferences.useHorizontalCandidateList) {
gCurrentCandidateController = [McBopomofoInputMethodController horizontalCandidateController];
}
else {
@ -1451,16 +1298,16 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
}
// set the attributes for the candidate panel (which uses NSAttributedString)
NSInteger textSize = [[NSUserDefaults standardUserDefaults] integerForKey:kCandidateListTextSizeKey];
NSInteger textSize = Preferences.candidateListTextSize;
NSInteger keyLabelSize = textSize / 2;
if (keyLabelSize < kMinKeyLabelSize) {
keyLabelSize = kMinKeyLabelSize;
}
NSString *ctFontName = [[NSUserDefaults standardUserDefaults] stringForKey:kCandidateTextFontName];
NSString *klFontName = [[NSUserDefaults standardUserDefaults] stringForKey:kCandidateKeyLabelFontName];
NSString *ckeys = [[NSUserDefaults standardUserDefaults] stringForKey:kCandidateKeys];
NSString *ctFontName = Preferences.candidateTextFontName;
NSString *klFontName = Preferences.candidateKeyLabelFontName;
NSString *ckeys = Preferences.candidateKeys;
gCurrentCandidateController.keyLabelFont = klFontName ? [NSFont fontWithName:klFontName size:keyLabelSize] : [NSFont systemFontOfSize:keyLabelSize];
gCurrentCandidateController.candidateFont = ctFontName ? [NSFont fontWithName:ctFontName size:textSize] : [NSFont systemFontOfSize:textSize];
@ -1661,25 +1508,21 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (void)openUserPhrases:(id)sender
{
NSLog(@"openUserPhrases called");
[self _openUserFile:[LanguageModelManager userPhrasesDataPathMcBopomofo]];
}
- (void)openExcludedPhrasesPlainBopomofo:(id)sender
{
NSLog(@"openExcludedPhrasesPlainBopomofo called");
[self _openUserFile:[LanguageModelManager excludedPhrasesDataPathPlainBopomofo]];
}
- (void)openExcludedPhrasesMcBopomofo:(id)sender
{
NSLog(@"openExcludedPhrasesMcBopomofo called");
[self _openUserFile:[LanguageModelManager excludedPhrasesDataPathMcBopomofo]];
}
- (void)reloadUserPhrases:(id)sender
{
NSLog(@"reloadUserPhrases called");
[LanguageModelManager loadUserPhrasesModel];
}
@ -1691,22 +1534,21 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
- (void)toggleChineseConverter:(id)sender
{
_chineseConversionEnabled = !_chineseConversionEnabled;
[[NSUserDefaults standardUserDefaults] setBool:_chineseConversionEnabled forKey:kChineseConversionEnabledKey];
BOOL chineseConversionEnabled = [Preferences toggleChineseConversionEnabled];
[NotifierController notifyWithMessage:
_chineseConversionEnabled ?
chineseConversionEnabled ?
NSLocalizedString(@"Chinese conversion on", @"") :
NSLocalizedString(@"Chinese conversion off", @"") stay:NO];
}
- (void)toggleHalfWidthPunctuation:(id)sender
{
_halfWidthPunctuationEnabled = !_halfWidthPunctuationEnabled;
[[NSUserDefaults standardUserDefaults] setBool:_halfWidthPunctuationEnabled forKey:kHalfWidthPunctuationEnabledKey];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
[Preferences toogleHalfWidthPunctuationEnabled];
#pragma GCC diagnostic pop
}
@end
#pragma mark -

294
Source/Preferences.swift Normal file
View File

@ -0,0 +1,294 @@
//
// Preferences.swift
//
// Copyright (c) 2011 The McBopomofo Project.
//
// Contributors:
// Mengjuei Hsieh (@mjhsieh)
// Weizhong Yang (@zonble)
//
// Based on the Syrup Project and the Formosana Library
// by Lukhnos Liu (@lukhnos).
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
import Cocoa
private let kKeyboardLayoutPreferenceKey = "KeyboardLayout"
private let kBasisKeyboardLayoutPreferenceKey = "BasisKeyboardLayout"; // alphanumeric ("ASCII") input basi
private let kFunctionKeyKeyboardLayoutPreferenceKey = "FunctionKeyKeyboardLayout"; // alphanumeric ("ASCII") input basi
private let kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey = "FunctionKeyKeyboardLayoutOverrideIncludeShift"; // whether include shif
private let kCandidateListTextSizeKey = "CandidateListTextSize"
private let kSelectPhraseAfterCursorAsCandidatePreferenceKey = "SelectPhraseAfterCursorAsCandidate"
private let kUseHorizontalCandidateListPreferenceKey = "UseHorizontalCandidateList"
private let kComposingBufferSizePreferenceKey = "ComposingBufferSize"
private let kChooseCandidateUsingSpaceKey = "ChooseCandidateUsingSpaceKey"
private let kChineseConversionEnabledKey = "ChineseConversionEnabled"
private let kHalfWidthPunctuationEnabledKey = "HalfWidthPunctuationEnable"
private let kEscToCleanInputBufferKey = "EscToCleanInputBuffer"
private let kCandidateTextFontName = "CandidateTextFontName"
private let kCandidateKeyLabelFontName = "CandidateKeyLabelFontName"
private let kCandidateKeys = "CandidateKeys"
private let kChineseConversionEngineKey = "ChineseConversionEngine"
private let kDefaultCandidateListTextSize: CGFloat = 16
private let kMinKeyLabelSize: CGFloat = 10
private let kMinCandidateListTextSize: CGFloat = 12
private let kMaxCandidateListTextSize: CGFloat = 196
// default, min and max composing buffer size (in codepoints)
// modern Macs can usually work up to 16 codepoints when the builder still
// walks the grid with good performance; slower Macs (like old PowerBooks)
// will start to sputter beyond 12; such is the algorithmatic complexity
// of the Viterbi algorithm used in the builder library (at O(N^2))
private let kDefaultComposingBufferSize = 10
private let kMinComposingBufferSize = 4
private let kMaxComposingBufferSize = 20
private let kDefaultKeys = "123456789"
// MARK: Property wrappers
@propertyWrapper
struct UserDefault<Value> {
let key: String
let defaultValue: Value
var container: UserDefaults = .standard
var wrappedValue: Value {
get {
return container.object(forKey: key) as? Value ?? defaultValue
}
set {
container.set(newValue, forKey: key)
}
}
}
@propertyWrapper
struct CandidateListTextSize {
let key: String
let defaultValue: CGFloat = kDefaultCandidateListTextSize
lazy var container: UserDefault = {
UserDefault(key: key, defaultValue: defaultValue) }()
var wrappedValue: CGFloat {
mutating get {
var value = container.wrappedValue
if value < kMinCandidateListTextSize {
value = kMinCandidateListTextSize
} else if value > kMaxCandidateListTextSize {
value = kMaxCandidateListTextSize
}
return value
}
set {
var value = newValue
if value < kMinCandidateListTextSize {
value = kMinCandidateListTextSize
} else if value > kMaxCandidateListTextSize {
value = kMaxCandidateListTextSize
}
container.wrappedValue = value
}
}
}
@propertyWrapper
struct ComposingBufferSize {
let key: String
let defaultValue: Int = kDefaultComposingBufferSize
lazy var container: UserDefault = {
UserDefault(key: key, defaultValue: defaultValue) }()
var wrappedValue: Int {
mutating get {
let currentValue = container.wrappedValue
if currentValue < kMinComposingBufferSize {
return kMinComposingBufferSize
} else if currentValue > kMaxComposingBufferSize {
return kMaxComposingBufferSize
}
return currentValue
}
set {
var value = newValue
if value < kMinComposingBufferSize {
value = kMinComposingBufferSize
} else if value > kMaxComposingBufferSize {
value = kMaxComposingBufferSize
}
container.wrappedValue = value
}
}
}
@propertyWrapper
struct ComposingKeys {
let key: String
let defaultValue: String? = kCandidateKeys
lazy var container: UserDefault = {
UserDefault(key: key, defaultValue: defaultValue) }()
var wrappedValue: String? {
mutating get {
let value = container.wrappedValue
if let value = value {
if value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
return nil
}
}
return value
}
set {
let value = newValue
if let value = value {
if value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
container.wrappedValue = nil
return
}
}
container.wrappedValue = value
}
}
}
// MARK: -
@objc enum KeyboardLayout: Int {
case standard
case eten
case eten26
case hsu
case hanyuPinyin
case IBM
var name: String {
switch (self) {
case .standard:
return "Standard"
case .eten:
return "ETen"
case .eten26:
return "ETen26"
case .hsu:
return "Hsu"
case .hanyuPinyin:
return "HanyuPinyin"
case .IBM:
return "IBM"
}
}
}
@objc enum ChineseConversionEngine: Int {
case openCC
case vxHanConvert
var name: String {
switch (self) {
case .openCC:
return "OpenCC"
case .vxHanConvert:
return "VXHanConvert"
}
}
}
// MARK: -
class Preferences: NSObject {
@UserDefault(key: kKeyboardLayoutPreferenceKey, defaultValue: 0)
@objc static var keyboardLayout: Int
@objc static var keyboardLayoutName: String {
(KeyboardLayout(rawValue: self.keyboardLayout) ?? KeyboardLayout.standard).name
}
@UserDefault(key: kBasisKeyboardLayoutPreferenceKey, defaultValue: "com.apple.keylayout.US")
@objc static var basisKeyboardLayout: String
@UserDefault(key: kFunctionKeyKeyboardLayoutPreferenceKey, defaultValue: "com.apple.keylayout.US")
@objc static var functionKeyboardLayout: String
@UserDefault(key: kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey, defaultValue: false)
@objc static var functionKeyKeyboardLayoutOverrideIncludeShiftKey: Bool
@CandidateListTextSize(key: kCandidateListTextSizeKey)
@objc static var candidateListTextSize: CGFloat
@UserDefault(key: kSelectPhraseAfterCursorAsCandidatePreferenceKey, defaultValue: false)
@objc static var selectPhraseAfterCursorAsCandidate: Bool
@UserDefault(key: kUseHorizontalCandidateListPreferenceKey, defaultValue: false)
@objc static var useHorizontalCandidateList: Bool
@ComposingBufferSize(key: kComposingBufferSizePreferenceKey)
@objc static var composingBufferSize: Int
@UserDefault(key: kChooseCandidateUsingSpaceKey, defaultValue: true)
@objc static var chooseCandidateUsingSpace: Bool
@UserDefault(key: kChineseConversionEnabledKey, defaultValue: false)
@objc static var chineseConversionEnabled: Bool
@objc static func toggleChineseConversionEnabled() -> Bool {
chineseConversionEnabled = !chineseConversionEnabled
return chineseConversionEnabled
}
@UserDefault(key: kHalfWidthPunctuationEnabledKey, defaultValue: false)
@objc static var halfWidthPunctuationEnabled: Bool
@objc static func toogleHalfWidthPunctuationEnabled() -> Bool {
halfWidthPunctuationEnabled = !halfWidthPunctuationEnabled
return halfWidthPunctuationEnabled;
}
@UserDefault(key: kEscToCleanInputBufferKey, defaultValue: false)
@objc static var escToCleanInputBuffer: Bool
// MARK: Optional settings
@UserDefault(key: kCandidateTextFontName, defaultValue: nil)
@objc static var candidateTextFontName: String?
@UserDefault(key: kCandidateKeyLabelFontName, defaultValue: nil)
@objc static var candidateKeyLabelFontName: String?
@ComposingKeys(key: kCandidateKeys)
@objc static var candidateKeys: String?
@objc static var defaultKeys: String {
kDefaultKeys
}
@UserDefault(key: kChineseConversionEngineKey, defaultValue: 0)
@objc static var chineneConversionEngine: Int
@objc static var chineneConversionEngineName: String? {
return ChineseConversionEngine(rawValue: chineneConversionEngine)?.name
}
}

View File

@ -35,10 +35,6 @@
import Cocoa
import Carbon
private let kBasisKeyboardLayoutPreferenceKey = "BasisKeyboardLayout"
private let kCandidateKeys = "CandidateKeys"
private let kDefaultKeys = "123456789"
// Please note that the class should be exposed as "PreferencesWindowController"
// in Objective-C in order to let IMK to see the same class name as
// the "InputMethodServerPreferencesWindowControllerClass" in Info.plist.
@ -54,47 +50,70 @@ private let kDefaultKeys = "123456789"
basisKeyboardLayoutButton.menu?.removeAllItems()
let basisKeyboardLayoutID = UserDefaults.standard.string(forKey: kBasisKeyboardLayoutPreferenceKey)
let basisKeyboardLayoutID = Preferences.basisKeyboardLayout
for source in list {
if let categoryPtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceCategory) {
let category = Unmanaged<CFString>.fromOpaque(categoryPtr).takeUnretainedValue()
if category != kTISCategoryKeyboardInputSource {
func getString(_ key: CFString) -> String? {
if let ptr = TISGetInputSourceProperty(source, key) {
return String(Unmanaged<CFString>.fromOpaque(ptr).takeUnretainedValue())
}
return nil
}
func getBool(_ key: CFString) -> Bool? {
if let ptr = TISGetInputSourceProperty(source, key) {
return Unmanaged<CFBoolean>.fromOpaque(ptr).takeUnretainedValue() == kCFBooleanTrue
}
return nil
}
if let category = getString(kTISPropertyInputSourceCategory) {
if category != String(kTISCategoryKeyboardInputSource) {
continue
}
} else {
continue
}
if let asciiCapablePtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceIsASCIICapable) {
let asciiCapable = Unmanaged<CFBoolean>.fromOpaque(asciiCapablePtr).takeUnretainedValue()
if asciiCapable != kCFBooleanTrue {
if let asciiCapable = getBool(kTISPropertyInputSourceIsASCIICapable) {
if !asciiCapable {
continue
}
} else {
continue
}
if let sourceTypePtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceType) {
let sourceType = Unmanaged<CFString>.fromOpaque(sourceTypePtr).takeUnretainedValue()
if sourceType != kTISTypeKeyboardLayout {
if let sourceType = getString(kTISPropertyInputSourceType) {
if sourceType != String(kTISTypeKeyboardLayout) {
continue
}
} else {
continue
}
guard let sourceIDPtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceID),
let localizedNamePtr = TISGetInputSourceProperty(source, kTISPropertyLocalizedName) else {
guard let sourceID = getString(kTISPropertyInputSourceID),
let localizedName = getString(kTISPropertyLocalizedName) else {
continue
}
let sourceID = String(Unmanaged<CFString>.fromOpaque(sourceIDPtr).takeUnretainedValue())
let localizedName = String(Unmanaged<CFString>.fromOpaque(localizedNamePtr).takeUnretainedValue())
let menuItem = NSMenuItem()
menuItem.title = localizedName
menuItem.representedObject = sourceID
if let iconPtr = TISGetInputSourceProperty(source, kTISPropertyIconRef) {
let icon = IconRef(iconPtr)
let image = NSImage(iconRef: icon)
func resize( _ image: NSImage) -> NSImage {
let newImage = NSImage(size: NSSize(width: 16, height: 16))
newImage.lockFocus()
image.draw(in: NSRect(x: 0, y: 0, width: 16, height: 16))
newImage.unlockFocus()
return newImage
}
menuItem.image = resize(image)
}
if sourceID == "com.apple.keylayout.US" {
usKeyboardLayoutItem = menuItem
}
@ -106,37 +125,37 @@ private let kDefaultKeys = "123456789"
basisKeyboardLayoutButton.select(chosenItem ?? usKeyboardLayoutItem)
selectionKeyComboBox.usesDataSource = false
selectionKeyComboBox.addItems(withObjectValues: [kDefaultKeys, "asdfghjkl", "asdfzxcvb"])
selectionKeyComboBox.removeAllItems()
selectionKeyComboBox.addItems(withObjectValues: [Preferences.defaultKeys, "asdfghjkl", "asdfzxcvb"])
var candidateSelectionKeys = (UserDefaults.standard.string(forKey: kCandidateKeys) ?? kDefaultKeys)
.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
var candidateSelectionKeys = Preferences.candidateKeys ?? Preferences.defaultKeys
if candidateSelectionKeys.isEmpty {
candidateSelectionKeys = kDefaultKeys
candidateSelectionKeys = Preferences.defaultKeys
}
selectionKeyComboBox.stringValue = candidateSelectionKeys
}
@IBAction func updateBasisKeyboardLayoutAction(_ sender: Any) {
if let sourceID = basisKeyboardLayoutButton.selectedItem?.representedObject {
UserDefaults.standard.set(sourceID, forKey: kBasisKeyboardLayoutPreferenceKey)
if let sourceID = basisKeyboardLayoutButton.selectedItem?.representedObject as? String {
Preferences.basisKeyboardLayout = sourceID
}
}
@IBAction func changeSelectionKeyAction(_ sender: Any) {
let keys = (sender as AnyObject).stringValue.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if keys.count != 9 || !keys.canBeConverted(to: .ascii) {
selectionKeyComboBox.stringValue = kDefaultKeys
UserDefaults.standard.removeObject(forKey: kCandidateKeys)
selectionKeyComboBox.stringValue = Preferences.defaultKeys
Preferences.candidateKeys = nil
NSSound.beep()
return
}
selectionKeyComboBox.stringValue = keys
if keys == kDefaultKeys {
UserDefaults.standard.removeObject(forKey: kCandidateKeys)
if keys == Preferences.defaultKeys {
Preferences.candidateKeys = nil
} else {
UserDefaults.standard.set(keys, forKey: kCandidateKeys)
Preferences.candidateKeys = keys
}
}

View File

@ -19,14 +19,14 @@
<window title="注音偏好設定" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="1" userLabel="Window - Preferences">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="489" y="334" width="433" height="375"/>
<rect key="contentRect" x="489" y="334" width="446" height="456"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="433" height="375"/>
<rect key="frame" x="0.0" y="0.0" width="446" height="456"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3">
<rect key="frame" x="181" y="330" width="125" height="26"/>
<rect key="frame" x="181" y="411" width="125" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="4">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -49,7 +49,7 @@
</popUpButtonCell>
</popUpButton>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="11">
<rect key="frame" x="83" y="336" width="95" height="17"/>
<rect key="frame" x="83" y="417" width="95" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="注音鍵盤配置:" id="12">
<font key="font" metaFont="system"/>
@ -58,7 +58,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="112">
<rect key="frame" x="181" y="293" width="149" height="26"/>
<rect key="frame" x="181" y="374" width="149" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="115">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -70,7 +70,7 @@
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="13">
<rect key="frame" x="18" y="173" width="160" height="17"/>
<rect key="frame" x="18" y="254" width="160" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字時,候選詞起算點在:" id="14">
<font key="font" metaFont="system"/>
@ -79,7 +79,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="23">
<rect key="frame" x="40" y="127" width="138" height="17"/>
<rect key="frame" x="40" y="208" width="138" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="候選詞呈現方式:" id="24">
<font key="font" metaFont="system"/>
@ -88,7 +88,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28">
<rect key="frame" x="70" y="80" width="108" height="17"/>
<rect key="frame" x="70" y="161" width="108" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字窗文字大小:" id="29">
<font key="font" metaFont="system"/>
@ -97,7 +97,7 @@
</textFieldCell>
</textField>
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="15">
<rect key="frame" x="184" y="152" width="184" height="38"/>
<rect key="frame" x="184" y="233" width="184" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="184" height="18"/>
@ -123,7 +123,7 @@
</connections>
</matrix>
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
<rect key="frame" x="184" y="106" width="207" height="38"/>
<rect key="frame" x="184" y="187" width="207" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="207" height="18"/>
@ -149,7 +149,7 @@
</connections>
</matrix>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="90">
<rect key="frame" x="181" y="72" width="86" height="26"/>
<rect key="frame" x="181" y="153" width="86" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="18" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="18" imageScaling="proportionallyDown" inset="2" selectedItem="96" id="91">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -172,7 +172,7 @@
</connections>
</popUpButton>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="109">
<rect key="frame" x="182" y="232" width="231" height="18"/>
<rect key="frame" x="182" y="313" width="231" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="使用空白鍵選字" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="110">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -182,19 +182,8 @@
<binding destination="32" name="value" keyPath="values.ChooseCandidateUsingSpaceKey" id="111"/>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ooW-fi-BVN">
<rect key="frame" x="182" y="19" width="148" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="定期檢查是否有新版" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="rcF-Ys-CM3">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.CheckUpdateAutomatically" id="drP-1F-7NA"/>
</connections>
</button>
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bQw-gl-dUP">
<rect key="frame" x="184" y="259" width="206" height="25"/>
<rect key="frame" x="184" y="340" width="206" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="mNx-Jy-SJB">
<font key="font" metaFont="system"/>
@ -211,7 +200,7 @@
</connections>
</comboBox>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8KJ-n8-0Wd">
<rect key="frame" x="70" y="263" width="108" height="17"/>
<rect key="frame" x="70" y="344" width="108" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字鍵:" id="eBT-Tv-vED">
<font key="font" metaFont="system"/>
@ -220,18 +209,18 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" id="OrA-WH-e5x">
<rect key="frame" x="182" y="209" width="231" height="20"/>
<rect key="frame" x="182" y="290" width="231" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="按下 ESC 會清除整個輸入緩衝區" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="7gv-k3-Mbt">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/>
<binding destination="32" name="value" keyPath="values.EscToCleanInputBuffer" id="Van-yb-Rvz"/>
</connections>
</button>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="113">
<rect key="frame" x="70" y="299" width="108" height="17"/>
<rect key="frame" x="70" y="380" width="108" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="英數字鍵盤配置:" id="114">
<font key="font" metaFont="system"/>
@ -239,9 +228,59 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p0T-C5-tAj">
<rect key="frame" x="18" y="106" width="160" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="中文简繁转换引擎:" id="jd1-sb-9rA">
<font key="font" size="13" name=".PingFangTC-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gYl-c0-mKc">
<rect key="frame" x="184" y="85" width="213" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="206" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="6Rv-nk-W6S">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<cells>
<column>
<buttonCell type="radio" title="OpenCC" imagePosition="left" alignment="left" state="on" inset="2" id="dSV-QR-LWp">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<buttonCell type="radio" title="古早香草簡繁轉換引擎" imagePosition="left" alignment="left" tag="1" inset="2" id="cc7-hh-sKa">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</column>
</cells>
<connections>
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionEngine" id="RYU-BR-yvD"/>
</connections>
</matrix>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5B4-1Z-6Mz">
<rect key="frame" x="20" y="136" width="406" height="5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</box>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ooW-fi-BVN">
<rect key="frame" x="182" y="19" width="148" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="定期檢查是否有新版" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="rcF-Ys-CM3">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.CheckUpdateAutomatically" id="drP-1F-7NA"/>
</connections>
</button>
</subviews>
</view>
<point key="canvasLocation" x="182.5" y="201.5"/>
<point key="canvasLocation" x="189" y="242"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="32"/>
</objects>