2.7.5 // Further renovation. Merge PR#147 from upd/2.7.5

This commit is contained in:
ShikiSuen 2022-09-25 21:28:00 +08:00 committed by GitHub
commit 50ab1184ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
112 changed files with 1747 additions and 1398 deletions

View File

@ -17,13 +17,9 @@ $ Contributors and volunteers of the upstream repo, having no responsibility in
- Zonble Yang:
- McBopomofo for macOS 2.x architect.
- Voltaire candidate window MK2 (massively modified as MK3 in vChewing by Shiki Suen).
- Notifier window.
- App-style installer (only preserved for developer purposes).
- PrefMgr (userdefaults manager).
- Mengjuei Hsieh:
- McBopomofo for macOS 1.x main developer and architect.
- The original C++ version of the User Override Module.
- Shiki Suen is trying to rewrite this module in Swift (and CSharp) with further development.
Although there is no Lukhnos's codes left in the current repository, we still credit him for his previous work:
@ -32,6 +28,8 @@ Although there is no Lukhnos's codes left in the current repository, we still cr
- Shiki Suen's Megrez engine (MIT License) is basically a Swift-rewritten version of Gramambular 2 with further development.
- Developer of Mandarin syllable composer (removed since vChewing 1.5.7).
- Shiki Suen's Tekkon engine is made from scratch and has no relationship to Mandarin syllable composer.
- Developer of the original C++ version of the User Override Module MK2.
- Shiki Suen is trying to rewrite this module in Swift (and CSharp) with further development.
$ Special thanks to:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -48,7 +48,7 @@ public class NSAttributedTextView: NSView {
}
public var direction: writingDirection = .horizontal
public var fontSize: CGFloat = NSFont.systemFontSize {
public var fontSize: Double = NSFont.systemFontSize {
didSet {
attributes[.font] = NSFont.systemFont(ofSize: fontSize)
}

View File

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

View File

@ -0,0 +1,28 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "Voltaire",
platforms: [
.macOS(.v10_11)
],
products: [
.library(
name: "Voltaire",
targets: ["Voltaire"]
)
],
dependencies: [
.package(path: "../vChewing_CandidateWindow"),
.package(path: "../vChewing_Shared"),
],
targets: [
.target(
name: "Voltaire",
dependencies: [
.product(name: "Shared", package: "vChewing_Shared"),
.product(name: "CandidateWindow", package: "vChewing_CandidateWindow"),
]
)
]
)

View File

@ -0,0 +1,48 @@
# Voltaire
Voltaire is a UI component replacement for Apple's InputMethodKit (IMK). The
built-in candidate UI has a limited interaction model and is not very
extensible nor customizable.
The project also comes with a test app that demonstrates the features of the
UI component.
Voltaire MK3 provides following new features comparing to MK1 and MK2:
1. A brand-new candidate window design conforming to the latest macOS UI design style, plus a floating label indicating the current page number of candidates (a frequently-asked feature by vChewing users).
2. One class for both vertical and horizontal display purposes. This can be specified as a parameter on init().
3. Can specify whether default candidate fonts conform to MOE glyphs standard or continental glyphs standard, requiring macOS 12 Monterey or later.
4. Can specify whether page buttons are shown.
Regarding the horizontal and vertical layout:
1. It is recommended to use init() in lieu of directly changing the layout variable since the latter doesn't redraw page buttons correctly.
2. Vertical candidate mode doesn't support scrolling. This is a deliberated design.
---
Copyrights:
```
- (c) 2022 Shiki Suen for all modifications introduced to Voltaire MK3.
- (c) 2021 Zonble Yang for rewriting Voltaire MK2 in Swift.
- (c) 2012 Lukhnos Liu for Voltaire MK1 development in Objective-C.
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.
```

View File

@ -10,6 +10,10 @@
// Zonble Voltaire
import CandidateWindow
import Cocoa
import Shared
private class vwrCandidateUniversal: NSView {
var highlightedIndex: Int = 0 {
didSet { highlightedIndex = min(max(highlightedIndex, 0), dispCandidatesWithLabels.count - 1) }
@ -17,22 +21,23 @@ private class vwrCandidateUniversal: NSView {
var action: Selector?
weak var target: AnyObject?
weak var controller: AnyObject?
var isVerticalLayout = false
var fractionFontSize: CGFloat = 12.0
var fractionFontSize: Double = 12.0
private var keyLabels: [String] = []
private var displayedCandidates: [String] = []
private var dispCandidatesWithLabels: [String] = []
private var keyLabelHeight: CGFloat = 0
private var keyLabelWidth: CGFloat = 0
private var candidateTextHeight: CGFloat = 0
private var cellPadding: CGFloat = 0
private var keyLabelHeight: Double = 0
private var keyLabelWidth: Double = 0
private var candidateTextHeight: Double = 0
private var cellPadding: Double = 0
private var keyLabelAttrDict: [NSAttributedString.Key: AnyObject] = [:]
private var candidateAttrDict: [NSAttributedString.Key: AnyObject] = [:]
private var candidateWithLabelAttrDict: [NSAttributedString.Key: AnyObject] = [:]
private var windowWidth: CGFloat = 0 //
private var elementWidths: [CGFloat] = []
private var elementHeights: [CGFloat] = [] //
private var windowWidth: Double = 0 //
private var elementWidths: [Double] = []
private var elementHeights: [Double] = [] //
private var trackingHighlightedIndex: Int = .max {
didSet { trackingHighlightedIndex = max(trackingHighlightedIndex, 0) }
}
@ -50,17 +55,17 @@ private class vwrCandidateUniversal: NSView {
result.width = windowWidth
result.height = elementHeights.reduce(0, +)
case false:
result.width = elementWidths.reduce(0, +) + CGFloat(elementWidths.count)
result.width = elementWidths.reduce(0, +) + Double(elementWidths.count)
result.height = candidateTextHeight + cellPadding
}
}
return result
}
@objc(setKeyLabels:displayedCandidates:)
func set(keyLabels labels: [String], displayedCandidates candidates: [String]) {
guard let delegate = (controller as? CtlCandidateUniversal)?.delegate else { return }
let candidates = candidates.map { theCandidate -> String in
let theConverted = ChineseConverter.kanjiConversionIfRequired(theCandidate)
let theConverted = delegate.kanjiConversionIfRequired(theCandidate)
return (theCandidate == theConverted) ? theCandidate : "\(theConverted)(\(theCandidate))"
}
@ -69,9 +74,9 @@ private class vwrCandidateUniversal: NSView {
displayedCandidates = Array(candidates[0..<count])
dispCandidatesWithLabels = zip(keyLabels, displayedCandidates).map { $0 + $1 }
var newWidths = [CGFloat]()
var calculatedWindowWidth = CGFloat()
var newHeights = [CGFloat]()
var newWidths = [Double]()
var calculatedWindowWidth = Double()
var newHeights = [Double]()
let baseSize = NSSize(width: 10240.0, height: 10240.0)
for index in 0..<count {
let rctCandidate = (dispCandidatesWithLabels[index] as NSString).boundingRect(
@ -133,55 +138,15 @@ private class vwrCandidateUniversal: NSView {
cellPadding = ceil(biggestSize / 4.0) * 2
}
func ensureLangIdentifier(for attr: inout [NSAttributedString.Key: AnyObject]) {
if PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier {
switch IMEApp.currentInputMode {
case .imeModeCHS:
if #available(macOS 12.0, *) {
attr[.languageIdentifier] = "zh-Hans" as AnyObject
}
case .imeModeCHT:
if #available(macOS 12.0, *) {
attr[.languageIdentifier] =
(PrefMgr.shared.shiftJISShinjitaiOutputEnabled || PrefMgr.shared.chineseConversionEnabled)
? "ja" as AnyObject : "zh-Hant" as AnyObject
}
default:
break
}
}
}
var highlightedColor: NSColor {
var result = NSColor.alternateSelectedControlColor
var colorBlendAmount: CGFloat = NSApplication.isDarkMode ? 0.3 : 0.0
if #available(macOS 10.14, *), !NSApplication.isDarkMode, IMEApp.currentInputMode == .imeModeCHT {
colorBlendAmount = 0.15
}
// The background color of the highlightened candidate
switch IMEApp.currentInputMode {
case .imeModeCHS:
result = NSColor.systemRed
case .imeModeCHT:
result = NSColor.systemBlue
default: break
}
var blendingAgainstTarget: NSColor = NSApplication.isDarkMode ? NSColor.black : NSColor.white
if #unavailable(macOS 10.14) {
colorBlendAmount = 0.3
blendingAgainstTarget = NSColor.white
}
return result.blended(withFraction: colorBlendAmount, of: blendingAgainstTarget)!
}
override func draw(_: NSRect) {
guard let controller = controller as? CtlCandidateUniversal else { return }
let bounds = bounds
NSColor.controlBackgroundColor.setFill() // Candidate list panel base background
NSBezierPath.fill(bounds)
switch isVerticalLayout {
case true:
var accuHeight: CGFloat = 0
var accuHeight: Double = 0
for (index, elementHeight) in elementHeights.enumerated() {
let currentHeight = elementHeight
let rctCandidateArea = NSRect(
@ -200,7 +165,7 @@ private class vwrCandidateUniversal: NSView {
var activeCandidateIndexAttr = keyLabelAttrDict
var activeCandidateAttr = candidateAttrDict
if index == highlightedIndex {
highlightedColor.setFill()
controller.highlightedColor().setFill()
// Highlightened index text color
activeCandidateIndexAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor
.withAlphaComponent(0.84)
@ -209,7 +174,11 @@ private class vwrCandidateUniversal: NSView {
let path: NSBezierPath = .init(roundedRect: rctCandidateArea, xRadius: 6, yRadius: 6)
path.fill()
}
ensureLangIdentifier(for: &activeCandidateAttr)
if #available(macOS 12, *) {
if controller.useLangIdentifier {
activeCandidateAttr[.languageIdentifier] = controller.locale as AnyObject
}
}
(keyLabels[index] as NSString).draw(
in: rctLabel, withAttributes: activeCandidateIndexAttr
)
@ -219,7 +188,7 @@ private class vwrCandidateUniversal: NSView {
accuHeight += currentHeight
}
case false:
var accuWidth: CGFloat = 0
var accuWidth: Double = 0
for (index, elementWidth) in elementWidths.enumerated() {
let currentWidth = elementWidth
let rctCandidateArea = NSRect(
@ -239,7 +208,7 @@ private class vwrCandidateUniversal: NSView {
var activeCandidateIndexAttr = keyLabelAttrDict
var activeCandidateAttr = candidateAttrDict
if index == highlightedIndex {
highlightedColor.setFill()
controller.highlightedColor().setFill()
// Highlightened index text color
activeCandidateIndexAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor
.withAlphaComponent(0.84)
@ -248,7 +217,11 @@ private class vwrCandidateUniversal: NSView {
let path: NSBezierPath = .init(roundedRect: rctCandidateArea, xRadius: 6, yRadius: 6)
path.fill()
}
ensureLangIdentifier(for: &activeCandidateAttr)
if #available(macOS 12, *) {
if controller.useLangIdentifier {
activeCandidateAttr[.languageIdentifier] = controller.locale as AnyObject
}
}
(keyLabels[index] as NSString).draw(
in: rctLabel, withAttributes: activeCandidateIndexAttr
)
@ -267,7 +240,7 @@ private class vwrCandidateUniversal: NSView {
}
switch isVerticalLayout {
case true:
var accuHeight: CGFloat = 0.0
var accuHeight = 0.0
for (index, elementHeight) in elementHeights.enumerated() {
let currentHeight = elementHeight
@ -277,7 +250,7 @@ private class vwrCandidateUniversal: NSView {
accuHeight += currentHeight
}
case false:
var accuWidth: CGFloat = 0.0
var accuWidth = 0.0
for (index, elementWidth) in elementWidths.enumerated() {
let currentWidth = elementWidth
@ -322,7 +295,7 @@ private class vwrCandidateUniversal: NSView {
}
}
public class ctlCandidateUniversal: ctlCandidate {
public class CtlCandidateUniversal: CtlCandidate {
private var candidateView: vwrCandidateUniversal
private var prevPageButton: NSButton
private var nextPageButton: NSButton
@ -408,6 +381,7 @@ public class ctlCandidateUniversal: ctlCandidate {
super.init(layout)
window = panel
currentLayout = layout
candidateView.controller = self
candidateView.target = self
candidateView.action = #selector(candidateViewMouseDidClick(_:))
@ -431,9 +405,9 @@ public class ctlCandidateUniversal: ctlCandidate {
}
@discardableResult override public func showNextPage() -> Bool {
guard delegate != nil else { return false }
guard let delegate = delegate else { return false }
if pageCount == 1 { return highlightNextCandidate() }
if currentPageIndex + 1 >= pageCount { IMEApp.buzz() }
if currentPageIndex + 1 >= pageCount { delegate.buzz() }
currentPageIndex = (currentPageIndex + 1 >= pageCount) ? 0 : currentPageIndex + 1
if currentPageIndex == pageCount - 1 {
candidateView.highlightedIndex = min(lastPageContentCount - 1, candidateView.highlightedIndex)
@ -444,9 +418,9 @@ public class ctlCandidateUniversal: ctlCandidate {
}
@discardableResult override public func showPreviousPage() -> Bool {
guard delegate != nil else { return false }
guard let delegate = delegate else { return false }
if pageCount == 1 { return highlightPreviousCandidate() }
if currentPageIndex == 0 { IMEApp.buzz() }
if currentPageIndex == 0 { delegate.buzz() }
currentPageIndex = (currentPageIndex == 0) ? pageCount - 1 : currentPageIndex - 1
if currentPageIndex == pageCount - 1 {
candidateView.highlightedIndex = min(lastPageContentCount - 1, candidateView.highlightedIndex)
@ -459,7 +433,7 @@ public class ctlCandidateUniversal: ctlCandidate {
@discardableResult override public func highlightNextCandidate() -> Bool {
guard let delegate = delegate else { return false }
selectedCandidateIndex =
(selectedCandidateIndex + 1 >= delegate.candidateCountForController(self))
(selectedCandidateIndex + 1 >= delegate.candidatePairs().count)
? 0 : selectedCandidateIndex + 1
return true
}
@ -468,7 +442,7 @@ public class ctlCandidateUniversal: ctlCandidate {
guard let delegate = delegate else { return false }
selectedCandidateIndex =
(selectedCandidateIndex == 0)
? delegate.candidateCountForController(self) - 1 : selectedCandidateIndex - 1
? delegate.candidatePairs().count - 1 : selectedCandidateIndex - 1
return true
}
@ -478,7 +452,7 @@ public class ctlCandidateUniversal: ctlCandidate {
}
let result = currentPageIndex * keyLabels.count + index
return result < delegate.candidateCountForController(self) ? result : Int.max
return result < delegate.candidatePairs().count ? result : Int.max
}
override public var selectedCandidateIndex: Int {
@ -490,7 +464,7 @@ public class ctlCandidateUniversal: ctlCandidate {
return
}
let keyLabelCount = keyLabels.count
if newValue < delegate.candidateCountForController(self) {
if newValue < delegate.candidatePairs().count {
currentPageIndex = newValue / keyLabelCount
candidateView.highlightedIndex = newValue % keyLabelCount
layoutCandidateView()
@ -499,12 +473,12 @@ public class ctlCandidateUniversal: ctlCandidate {
}
}
extension ctlCandidateUniversal {
extension CtlCandidateUniversal {
private var pageCount: Int {
guard let delegate = delegate else {
return 0
}
let totalCount = delegate.candidateCountForController(self)
let totalCount = delegate.candidatePairs().count
let keyLabelCount = keyLabels.count
return totalCount / keyLabelCount + ((totalCount % keyLabelCount) != 0 ? 1 : 0)
}
@ -513,24 +487,22 @@ extension ctlCandidateUniversal {
guard let delegate = delegate else {
return 0
}
let totalCount = delegate.candidateCountForController(self)
let totalCount = delegate.candidatePairs().count
let keyLabelCount = keyLabels.count
return totalCount % keyLabelCount
}
private func layoutCandidateView() {
guard let delegate = delegate else {
return
}
guard let delegate = delegate, let window = window else { return }
candidateView.set(keyLabelFont: keyLabelFont, candidateFont: candidateFont)
var candidates = [(String, String)]()
let count = delegate.candidateCountForController(self)
let count = delegate.candidatePairs().count
let keyLabelCount = keyLabels.count
let begin = currentPageIndex * keyLabelCount
for index in begin..<min(begin + keyLabelCount, count) {
let candidate = delegate.ctlCandidate(self, candidateAtIndex: index)
let candidate = delegate.candidatePairAt(index)
candidates.append(candidate)
}
candidateView.set(
@ -540,14 +512,14 @@ extension ctlCandidateUniversal {
var frameRect = candidateView.frame
frameRect.size = newSize
candidateView.frame = frameRect
let counterHeight: CGFloat = newSize.height - 24
let counterHeight: Double = newSize.height - 24.0
if pageCount > 1, PrefMgr.shared.showPageButtonsInCandidateWindow {
if pageCount > 1, showPageButtons {
var buttonRect = nextPageButton.frame
let spacing: CGFloat = 0.0
let spacing = 0.0
if currentLayout == .horizontal { buttonRect.size.height = floor(newSize.height / 2) }
let buttonOriginY: CGFloat = {
let buttonOriginY: Double = {
if currentLayout == .vertical {
return counterHeight
}
@ -582,12 +554,12 @@ extension ctlCandidateUniversal {
rect.size.height += 3
rect.size.width += 4
let rectOriginY: CGFloat =
let rectOriginY: Double =
(currentLayout == .horizontal)
? (newSize.height - rect.height) / 2
: counterHeight
let rectOriginX: CGFloat =
PrefMgr.shared.showPageButtonsInCandidateWindow
let rectOriginX: Double =
showPageButtons
? newSize.width
: newSize.width + 4
rect.origin = NSPoint(x: rectOriginX, y: rectOriginY)
@ -598,12 +570,12 @@ extension ctlCandidateUniversal {
pageCounterLabel.isHidden = true
}
frameRect = window?.frame ?? NSRect.seniorTheBeast
frameRect = window.frame
let topLeftPoint = NSPoint(x: frameRect.origin.x, y: frameRect.origin.y + frameRect.size.height)
frameRect.size = newSize
frameRect.origin = NSPoint(x: topLeftPoint.x, y: topLeftPoint.y - frameRect.size.height)
window?.setFrame(frameRect, display: false)
window.setFrame(frameRect, display: false)
candidateView.setNeedsDisplay(candidateView.bounds)
}
@ -619,6 +591,6 @@ extension ctlCandidateUniversal {
}
@objc private func candidateViewMouseDidClick(_: Any) {
delegate?.candidateSelected(at: selectedCandidateIndex)
delegate?.candidatePairSelected(at: selectedCandidateIndex)
}
}

View File

@ -54,7 +54,7 @@ extension Preferences {
}
}
.modifier(Section.LabelWidthModifier(maximumWidth: $maximumLabelWidth))
.frame(width: CGFloat(contentWidth), alignment: .leading)
.frame(width: Double(contentWidth), alignment: .leading)
.padding(.vertical, 20)
.padding(.horizontal, 30)
}
@ -65,9 +65,9 @@ extension Preferences {
if index != sections.count - 1, sections[index].bottomDivider {
Divider()
// Strangely doesn't work without width being specified. Probably because of custom alignment.
.frame(width: CGFloat(contentWidth), height: 20)
.frame(width: Double(contentWidth), height: 20)
.alignmentGuide(.preferenceSectionLabel) {
$0[.leading] + CGFloat(max(minimumLabelWidth, maximumLabelWidth))
$0[.leading] + Double(max(minimumLabelWidth, maximumLabelWidth))
}
}
}

View File

@ -77,8 +77,8 @@ final class SegmentedControlStyleViewController: NSViewController, PreferencesSt
)
}()
let segmentBorderWidth = CGFloat(preferencePanes.count) + 1
let segmentWidth = segmentSize.width * CGFloat(preferencePanes.count) + segmentBorderWidth
let segmentBorderWidth = Double(preferencePanes.count) + 1
let segmentWidth = segmentSize.width * Double(preferencePanes.count) + segmentBorderWidth
let segmentHeight = segmentSize.height
segmentedControl.frame = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)

View File

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

View File

@ -0,0 +1,26 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "CandidateWindow",
platforms: [
.macOS(.v10_11)
],
products: [
.library(
name: "CandidateWindow",
targets: ["CandidateWindow"]
)
],
dependencies: [
.package(path: "../vChewing_Shared")
],
targets: [
.target(
name: "CandidateWindow",
dependencies: [
.product(name: "Shared", package: "vChewing_Shared")
]
)
]
)

View File

@ -0,0 +1,13 @@
# CandidateWindow
用以定義與威注音的選字窗有關的基礎內容,目前尚未完工。
```
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
```

View File

@ -0,0 +1,147 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
import Shared
open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
open var showPageButtons: Bool = false
open var currentLayout: CandidateLayout = .horizontal
open var locale: String = ""
open var useLangIdentifier: Bool = false
open func highlightedColor() -> NSColor {
var result = NSColor.alternateSelectedControlColor
var colorBlendAmount: Double = NSApplication.isDarkMode ? 0.3 : 0.0
if #available(macOS 10.14, *), !NSApplication.isDarkMode, locale == "zh-Hant" {
colorBlendAmount = 0.15
}
// The background color of the highlightened candidate
switch locale {
case "zh-Hans":
result = NSColor.systemRed
case "zh-Hant":
result = NSColor.systemBlue
case "ja":
result = NSColor.systemBrown
default: break
}
var blendingAgainstTarget: NSColor = NSApplication.isDarkMode ? NSColor.black : NSColor.white
if #unavailable(macOS 10.14) {
colorBlendAmount = 0.3
blendingAgainstTarget = NSColor.white
}
return result.blended(withFraction: colorBlendAmount, of: blendingAgainstTarget)!
}
open weak var delegate: CtlCandidateDelegate? {
didSet {
reloadData()
}
}
open var windowTopLeftPoint: NSPoint {
get {
guard let frameRect = window?.frame else { return NSPoint.zero }
return NSPoint(x: frameRect.minX, y: frameRect.maxY)
}
set {
DispatchQueue.main.async {
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0)
}
}
}
open var selectedCandidateIndex: Int = .max
open var visible = false {
didSet {
NSObject.cancelPreviousPerformRequests(withTarget: self)
DispatchQueue.main.async { [self] in
_ = visible ? window?.orderFront(self) : window?.orderOut(self)
}
}
}
public required init(_: CandidateLayout = .horizontal) {
super.init(window: .init())
visible = false
}
/// Sets the location of the candidate window.
///
/// Please note that the method has side effects that modifies
/// `windowTopLeftPoint` to make the candidate window to stay in at least
/// in a screen.
///
/// - Parameters:
/// - windowTopLeftPoint: The given location.
/// - height: The height that helps the window not to be out of the bottom
/// of a screen.
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
DispatchQueue.main.async { [self] in
guard let window = window, var screenFrame = NSScreen.main?.visibleFrame else { return }
let windowSize = window.frame.size
var adjustedPoint = windowTopLeftPoint
var delta = heightDelta
for frame in NSScreen.screens.map(\.visibleFrame).filter({ $0.contains(windowTopLeftPoint) }) {
screenFrame = frame
break
}
if delta > screenFrame.size.height / 2.0 { delta = 0.0 }
if adjustedPoint.y < screenFrame.minY + windowSize.height {
adjustedPoint.y = windowTopLeftPoint.y + windowSize.height + delta
}
adjustedPoint.y = min(adjustedPoint.y, screenFrame.maxY - 1.0)
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width - 1.0)
window.setFrameTopLeftPoint(adjustedPoint)
}
}
// MARK: - Contents that are not needed to be implemented here.
@available(*, unavailable)
public required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open var keyLabels: [CandidateKeyLabel] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
.map {
CandidateKeyLabel(key: $0, displayedText: $0)
}
open var candidateFont = NSFont.systemFont(ofSize: 18)
open var keyLabelFont = NSFont.monospacedDigitSystemFont(ofSize: 14, weight: .medium)
open var tooltip: String = ""
@discardableResult open func highlightNextCandidate() -> Bool {
false
}
@discardableResult open func highlightPreviousCandidate() -> Bool {
false
}
@discardableResult open func showNextPage() -> Bool {
false
}
@discardableResult open func showPreviousPage() -> Bool {
false
}
open func candidateIndexAtKeyLabelIndex(_: Int) -> Int {
Int.max
}
open func reloadData() {}
}

View File

@ -221,6 +221,15 @@ extension vChewingLM {
return !unigramsFor(key: key).isEmpty
}
///
/// - Parameters:
/// - key:
/// - value:
/// - Returns:
public func hasKeyValuePairFor(key: String, value: String) -> Bool {
unigramsFor(key: key).map(\.value).contains(value)
}
/// LMI
/// - Parameter key:
/// - Returns:

View File

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

View File

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

View File

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

View File

@ -0,0 +1,13 @@
# NotifierUI
威注音的飄雲通知視窗。
```
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
```

View File

@ -0,0 +1,155 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
public class Notifier: NSWindowController {
public static func notify(message: String) {
Self.message = message
}
static var message: String = "" {
didSet {
if !Self.message.isEmpty {
Self.message = Notifier(message).blankValue
}
}
}
// MARK: - Private Declarations
private static var instanceStack: [Notifier] = []
private let blankValue = ""
@discardableResult private init(_ message: String) {
let rawMessage = message.replacingOccurrences(of: "\n", with: "")
guard let screenRect = NSScreen.main?.visibleFrame, !rawMessage.isEmpty else {
super.init(window: nil)
return
}
let kLargeFontSize: Double = 17
let kSmallFontSize: Double = 15
let messageArray = message.components(separatedBy: "\n")
let paraStyle = NSMutableParagraphStyle()
paraStyle.setParagraphStyle(NSParagraphStyle.default)
paraStyle.alignment = .center
let attrTitle: [NSAttributedString.Key: AnyObject] = [
.foregroundColor: NSColor.controlTextColor,
.font: NSFont.boldSystemFont(ofSize: kLargeFontSize),
.paragraphStyle: paraStyle,
]
let attrString = NSMutableAttributedString(string: messageArray[0], attributes: attrTitle)
let attrAlt: [NSAttributedString.Key: AnyObject] = [
.foregroundColor: NSColor.secondaryLabelColor,
.font: NSFont.systemFont(ofSize: kSmallFontSize),
.paragraphStyle: paraStyle,
]
let additionalString = messageArray.count > 1 ? "\n\(messageArray[1])" : ""
let attrStringAlt = NSMutableAttributedString(string: additionalString, attributes: attrAlt)
attrString.insert(attrStringAlt, at: attrString.length)
let textRect: NSRect = attrString.boundingRect(
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin]
)
let windowWidth = Double(4) * kLargeFontSize + textRect.width
let contentRect = NSRect(x: 0, y: 0, width: windowWidth, height: 60.0)
var windowRect = contentRect
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
windowRect.origin.y = screenRect.maxY - windowRect.height - 10
let styleMask: NSWindow.StyleMask = [.borderless]
let transparentVisualEffect = NSVisualEffectView()
transparentVisualEffect.blendingMode = .behindWindow
transparentVisualEffect.state = .active
let theWindow = NSWindow(
contentRect: windowRect, styleMask: styleMask, backing: .buffered, defer: false
)
theWindow.contentView = transparentVisualEffect
theWindow.isMovableByWindowBackground = true
theWindow.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel))
theWindow.hasShadow = true
theWindow.backgroundColor = .textBackgroundColor
theWindow.title = ""
theWindow.titlebarAppearsTransparent = true
theWindow.titleVisibility = .hidden
theWindow.showsToolbarButton = false
theWindow.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
theWindow.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
theWindow.standardWindowButton(NSWindow.ButtonType.closeButton)?.isHidden = true
theWindow.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
theWindow.isReleasedWhenClosed = true
theWindow.isMovable = false
let lblMessage = NSTextField()
lblMessage.attributedStringValue = attrString
lblMessage.drawsBackground = false
lblMessage.font = .boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular))
lblMessage.frame = contentRect
lblMessage.isBezeled = false
lblMessage.isEditable = false
lblMessage.isSelectable = false
lblMessage.textColor = .controlTextColor
theWindow.contentView?.addSubview(lblMessage)
let x = lblMessage.frame.origin.x
let y = ((theWindow.frame.height) - textRect.height) / 1.9
let newFrame = NSRect(x: x, y: y, width: theWindow.frame.width, height: textRect.height)
lblMessage.frame = newFrame
super.init(window: theWindow)
display()
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override public func close() {
super.close()
}
}
// MARK: - Private Functions
extension Notifier {
private func shiftExistingWindowPositions() {
guard let window = window, !Self.instanceStack.isEmpty else { return }
for theInstanceWindow in Self.instanceStack.compactMap(\.window) {
var theOrigin = theInstanceWindow.frame
theOrigin.origin.y -= (10 + window.frame.height)
theInstanceWindow.setFrame(theOrigin, display: true)
}
}
private func fadeIn() {
guard let window = window else { return }
let afterRect = window.frame
var beforeRect = afterRect
beforeRect.origin.x -= 20
window.setFrame(beforeRect, display: true)
window.orderFront(self)
window.setFrame(afterRect, display: true, animate: true)
}
private func display() {
let existingInstanceArray = Self.instanceStack.compactMap(\.window)
if !existingInstanceArray.isEmpty {
existingInstanceArray.forEach { $0.alphaValue *= 0.5 }
}
shiftExistingWindowPositions()
fadeIn()
Self.instanceStack.insert(self, at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.close()
Self.instanceStack.removeAll(where: { $0.window == nil })
}
}
}

View File

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

View File

@ -0,0 +1,26 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "PopupCompositionBuffer",
platforms: [
.macOS(.v10_11)
],
products: [
.library(
name: "PopupCompositionBuffer",
targets: ["PopupCompositionBuffer"]
)
],
dependencies: [
.package(path: "../vChewing_Shared")
],
targets: [
.target(
name: "PopupCompositionBuffer",
dependencies: [
.product(name: "Shared", package: "vChewing_Shared")
]
)
]
)

View File

@ -0,0 +1,13 @@
# NotifierUI
威注音的浮動組字窗。
```
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
```

View File

@ -6,7 +6,10 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
public class ctlPopupCompositionBuffer: NSWindowController {
import Cocoa
import Shared
public class PopupCompositionBuffer: NSWindowController {
public var isTypingDirectionVertical = false {
didSet {
if #unavailable(macOS 10.14) {
@ -33,7 +36,7 @@ public class ctlPopupCompositionBuffer: NSWindowController {
panel.hasShadow = true
panel.backgroundColor = NSColor.controlBackgroundColor
panel.styleMask = .fullSizeContentView
panel.isMovable = false
messageTextField = NSTextField()
messageTextField.isEditable = false
messageTextField.isSelectable = false
@ -58,7 +61,7 @@ public class ctlPopupCompositionBuffer: NSWindowController {
return
}
let attrString: NSMutableAttributedString = .init(string: state.data.displayedTextConverted)
let attrString: NSMutableAttributedString = .init(string: state.displayedTextConverted)
let verticalAttributes: [NSAttributedString.Key: Any] = [
.verticalGlyphForm: true,
.paragraphStyle: {
@ -75,7 +78,7 @@ public class ctlPopupCompositionBuffer: NSWindowController {
if isTypingDirectionVertical {
attrString.setAttributes(
verticalAttributes, range: NSRange(location: 0, length: attrString.string.utf16.count)
verticalAttributes, range: NSRange(location: 0, length: attrString.length)
)
}
@ -95,8 +98,8 @@ public class ctlPopupCompositionBuffer: NSWindowController {
attrString.setAttributes(
markerAttributes,
range: NSRange(
location: state.data.u16MarkedRange.lowerBound,
length: state.data.u16MarkedRange.upperBound - state.data.u16MarkedRange.lowerBound
location: state.u16MarkedRange.lowerBound,
length: state.u16MarkedRange.upperBound - state.u16MarkedRange.lowerBound
)
)
@ -123,12 +126,12 @@ public class ctlPopupCompositionBuffer: NSWindowController {
isTypingDirectionVertical
? NSMutableAttributedString(string: "", attributes: cursorAttributes)
: NSMutableAttributedString(string: "_", attributes: cursorAttributes)
attrString.insert(attrCursor, at: state.data.u16Cursor)
attrString.insert(attrCursor, at: state.u16Cursor)
textShown = attrString
messageTextField.maximumNumberOfLines = 1
if let editor = messageTextField.currentEditor() {
editor.selectedRange = NSRange(state.data.u16MarkedRange)
editor.selectedRange = NSRange(state.u16MarkedRange)
}
window?.orderFront(nil)
set(windowOrigin: point)
@ -165,7 +168,7 @@ public class ctlPopupCompositionBuffer: NSWindowController {
with: NSSize(width: 1600.0, height: 1600.0),
options: [.usesLineFragmentOrigin, .usesFontLeading]
)
rect.size.width = max(rect.size.width, 20 * CGFloat(attrString.string.count)) + 2
rect.size.width = max(rect.size.width, 20 * Double(attrString.string.count)) + 2
rect.size.height *= 1.2
rect.size.height = max(22, rect.size.height)
if isTypingDirectionVertical {

View File

@ -0,0 +1,41 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
public protocol CtlCandidateDelegate: AnyObject {
func candidatePairs() -> [(String, String)]
func candidatePairAt(_ index: Int) -> (String, String)
func candidatePairSelected(at index: Int)
func buzz()
func kanjiConversionIfRequired(_ target: String) -> String
}
public protocol CtlCandidateProtocol {
var locale: String { get set }
var currentLayout: CandidateLayout { get set }
var delegate: CtlCandidateDelegate? { get set }
var selectedCandidateIndex: Int { get set }
var visible: Bool { get set }
var windowTopLeftPoint: NSPoint { get set }
var keyLabels: [CandidateKeyLabel] { get set }
var keyLabelFont: NSFont { get set }
var candidateFont: NSFont { get set }
var tooltip: String { get set }
var useLangIdentifier: Bool { get set }
var showPageButtons: Bool { get set }
init(_ layout: CandidateLayout)
func reloadData()
func showNextPage() -> Bool
func showPreviousPage() -> Bool
func highlightNextCandidate() -> Bool
func highlightPreviousCandidate() -> Bool
func candidateIndexAtKeyLabelIndex(_: Int) -> Int
func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: Double)
}

View File

@ -0,0 +1,64 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
// IMEState
public protocol IMEStateProtocol {
var type: StateType { get }
var data: StateDataProtocol { get }
var isASCIIMode: Bool { get set }
var isVerticalTyping: Bool { get set }
var isVerticalCandidateWindow: Bool { get set }
var candidates: [(String, String)] { get set }
var hasComposition: Bool { get }
var isCandidateContainer: Bool { get }
var displayedText: String { get }
var displayedTextConverted: String { get }
var textToCommit: String { get set }
var tooltip: String { get set }
var attributedString: NSAttributedString { get }
var convertedToInputting: IMEStateProtocol { get }
var isFilterable: Bool { get }
var isMarkedLengthValid: Bool { get }
var node: CandidateNode { get set }
var displayTextSegments: [String] { get }
var tooltipBackupForInputting: String { get set }
var markedRange: Range<Int> { get }
var u16MarkedRange: Range<Int> { get }
var u16Cursor: Int { get }
var cursor: Int { get set }
var marker: Int { get set }
}
public protocol StateDataProtocol {
var cursor: Int { get set }
var marker: Int { get set }
var markedRange: Range<Int> { get }
var u16MarkedRange: Range<Int> { get }
var u16Cursor: Int { get }
var textToCommit: String { get set }
var markedReadings: [String] { get set }
var displayTextSegments: [String] { get set }
var isFilterable: Bool { get }
var isVerticalTyping: Bool { get set }
var isMarkedLengthValid: Bool { get }
var candidates: [(String, String)] { get set }
var displayedText: String { get set }
var displayedTextConverted: String { get }
var tooltipBackupForInputting: String { get set }
var tooltip: String { get set }
var attributedStringNormal: NSAttributedString { get }
var attributedStringMarking: NSAttributedString { get }
var attributedStringPlaceholder: NSAttributedString { get }
var userPhraseDumped: String { get }
var userPhraseDumpedConverted: String { get }
var doesUserPhraseExist: Bool { get }
var tooltipColorState: TooltipColorState { get set }
mutating func updateTooltipForMarking()
}

View File

@ -103,6 +103,50 @@ public enum UserDef: String, CaseIterable {
}
}
// MARK: - Enums and Structs used by Candidate Window
public enum CandidateLayout {
case horizontal
case vertical
}
public struct CandidateKeyLabel {
public private(set) var key: String
public private(set) var displayedText: String
public init(key: String, displayedText: String) {
self.key = key
self.displayedText = displayedText
}
}
// MARK: - Tooltip Color States
public enum TooltipColorState {
case normal
case redAlert
case warning
case denialOverflow
case denialInsufficiency
case prompt
}
// MARK: - IMEState types.
// enum
public enum StateType: String {
case ofDeactivated = "Deactivated"
case ofEmpty = "Empty"
case ofAbortion = "Abortion" // Empty
case ofCommitting = "Committing"
case ofAssociates = "Associates"
case ofNotEmpty = "NotEmpty"
case ofInputting = "Inputting"
case ofMarking = "Marking"
case ofCandidates = "Candidates"
case ofSymbolTable = "SymbolTable"
}
// MARK: - Parser for Syllable composer
public enum KeyboardParser: Int, CaseIterable {

View File

@ -23,7 +23,7 @@ Regarding pinyin input support, we only support: Hanyu Pinyin, Secondary Pinyin,
### §1. 初期化
在你的 ctlInputMethod (InputMethodController) 或者 KeyHandler 內初期化一份 Tekkon.Composer 注拼槽副本(這裡將該副本命名為「`_composer`」)。由於 Tekkon.Composer 的型別是 Struct 型別所以其副本必須為變數var否則無法自我 mutate。
在你的 IMKInputController (InputMethodController) 或者 KeyHandler 內初期化一份 Tekkon.Composer 注拼槽副本(這裡將該副本命名為「`_composer`」)。由於 Tekkon.Composer 的型別是 Struct 型別所以其副本必須為變數var否則無法自我 mutate。
以 KeyHandler 為例:
```swift
@ -34,10 +34,10 @@ class KeyHandler: NSObject {
}
```
ctlInputMethod 為例:
IMKInputController 為例:
```swift
@objc(ctlInputMethod) // 根據 info.plist 內的情況來確定型別的命名
class ctlInputMethod: IMKInputController {
@objc(IMKMyInputController) // 根據 info.plist 內的情況來確定型別的命名
class IMKMyInputController: IMKInputController {
// 先設定好變數
var _composer: Tekkon.Composer = .init()
...
@ -45,7 +45,7 @@ class ctlInputMethod: IMKInputController {
```
由於 Swift 會在某個大副本KeyHandler 或者 ctlInputMethod 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Tekkon.Composer 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所使用的注音排列(是大千?還是倚天傳統?還是神通?等)。
由於 Swift 會在某個大副本KeyHandler 或者 IMKInputController 副本)被銷毀的時候自動銷毀其中的全部副本,所以 Tekkon.Composer 的副本初期化沒必要寫在 init() 當中。但你很可能會想在 init() 時指定 Tekkon.Composer 所使用的注音排列(是大千?還是倚天傳統?還是神通?等)。
這裡就需要在 _composer 這個副本所在的型別當中額外寫一個過程函式。
@ -159,9 +159,9 @@ final class TekkonTests: XCTestCase {
#### // 2. 訊號處理
無論是 KeyHandler 還是 ctlInputMethod 都得要處理被傳入的 NSEvent 當中的 charCode 訊號。
無論是 KeyHandler 還是 IMKInputController 都得要處理被傳入的 NSEvent 當中的 charCode 訊號。
比如 ctlInputMethod 內:
比如 IMKInputController 內:
```swift
func handleInputText(_ inputText: String?, key keyCode: Int, modifiers flags: Int, client: Any?) -> Bool {
...

View File

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

View File

@ -0,0 +1,30 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TooltipUI",
platforms: [
.macOS(.v10_11)
],
products: [
.library(
name: "TooltipUI",
targets: ["TooltipUI"]
)
],
dependencies: [
.package(path: "../Fuziki_NSAttributedTextView"),
.package(path: "../vChewing_CocoaExtension"),
.package(path: "../vChewing_Shared"),
],
targets: [
.target(
name: "TooltipUI",
dependencies: [
.product(name: "NSAttributedTextView", package: "Fuziki_NSAttributedTextView"),
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
.product(name: "Shared", package: "vChewing_Shared"),
]
)
]
)

View File

@ -0,0 +1,13 @@
# NotifierUI
威注音的工具提示視窗。
```
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
```

View File

@ -6,18 +6,12 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
import CocoaExtension
import NSAttributedTextView
import Shared
public class ctlTooltip: NSWindowController {
public enum ColorStates {
case normal
case redAlert
case warning
case denialOverflow
case denialInsufficiency
case prompt
}
public class TooltipUI: NSWindowController {
private var messageText: NSAttributedTooltipTextView
private var tooltip: String = "" {
didSet {
@ -43,6 +37,7 @@ public class ctlTooltip: NSWindowController {
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
panel.hasShadow = true
panel.backgroundColor = NSColor.controlBackgroundColor
panel.isMovable = false
messageText = NSAttributedTooltipTextView()
messageText.backgroundColor = NSColor.controlBackgroundColor
messageText.textColor = NSColor.textColor
@ -57,7 +52,7 @@ public class ctlTooltip: NSWindowController {
public func show(
tooltip: String = "", at point: NSPoint,
bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat,
bottomOutOfScreenAdjustmentHeight heightDelta: Double,
direction: NSAttributedTooltipTextView.writingDirection = .horizontal
) {
self.direction = direction
@ -66,7 +61,7 @@ public class ctlTooltip: NSWindowController {
set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta)
}
public func setColor(state: ColorStates) {
public func setColor(state: TooltipColorState) {
var backgroundColor = NSColor.controlBackgroundColor
var textColor = NSColor.textColor
switch state {
@ -123,7 +118,7 @@ public class ctlTooltip: NSWindowController {
window?.orderOut(nil)
}
private func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
private func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
guard let window = window else { return }
let windowSize = window.frame.size

View File

@ -91,7 +91,7 @@ P.S.: 威注音输入法的 Shift 按键监测功能仅借由对 NSEvent 讯号
威注音专案目前仅用到小麦注音的下述程式组件MIT License
- 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。
- Voltaire MK2 选字窗、飘云通知视窗 (by Zonble Yang),有大幅度修改。
- Voltaire MK2 选字窗 (by Zonble Yang),有大幅度修改。
威注音专案目前还用到如下的来自 Lukhnos Liu 的算法:

View File

@ -91,7 +91,7 @@ P.S.: 威注音輸入法的 Shift 按鍵監測功能僅藉由對 NSEvent 訊號
威注音專案目前僅用到小麥注音的下述程式組件MIT License
- 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。
- Voltaire MK2 選字窗、飄雲通知視窗 (by Zonble Yang),有大幅度修改。
- Voltaire MK2 選字窗 (by Zonble Yang),有大幅度修改。
威注音專案目前還用到如下的來自 Lukhnos Liu 的算法:

@ -1 +1 @@
Subproject commit 33487f554d2306f43d100c9c5b8ce99c2109ca52
Subproject commit 6f71610f126eee8efcce4a4ff832bec03af7c79b

View File

@ -73,7 +73,7 @@ public enum ChineseConverter {
///
/// - Parameter string: Text in Original Script.
/// - Returns: Text converted to Different Script.
public static func crossConvert(_ string: String) -> String? {
public static func crossConvert(_ string: String) -> String {
switch IMEApp.currentInputMode {
case .imeModeCHS:
return shared.convert(string, to: .zhHantTW)

View File

@ -7,46 +7,9 @@
// requirements defined in MIT License.
import LangModelAssembly
import Shared
// enum
public enum StateType: String {
case ofDeactivated = "Deactivated"
case ofEmpty = "Empty"
case ofAbortion = "Abortion" // Empty
case ofCommitting = "Committing"
case ofAssociates = "Associates"
case ofNotEmpty = "NotEmpty"
case ofInputting = "Inputting"
case ofMarking = "Marking"
case ofCandidates = "Candidates"
case ofSymbolTable = "SymbolTable"
}
// IMEState
public protocol IMEStateProtocol {
var type: StateType { get }
var data: StateData { get }
var isASCIIMode: Bool { get set }
var isVerticalTyping: Bool { get set }
var isVerticalCandidateWindow: Bool { get set }
var candidates: [(String, String)] { get }
var hasComposition: Bool { get }
var isCandidateContainer: Bool { get }
var displayedText: String { get }
var textToCommit: String { get set }
var tooltip: String { get set }
var attributedString: NSAttributedString { get }
var convertedToInputting: IMEState { get }
var isFilterable: Bool { get }
var isMarkedLengthValid: Bool { get }
var node: CandidateNode { get set }
var cursor: Int { get }
var displayTextSegments: [String] { get }
var tooltipBackupForInputting: String { get set }
var markedRange: Range<Int> { get }
}
/// ctlInputMethod
/// SessionCtl
///
/// Finite State Machine/
/// 使
@ -79,17 +42,17 @@ public protocol IMEStateProtocol {
/// - .SymbolTable:
public struct IMEState: IMEStateProtocol {
public var type: StateType = .ofEmpty
public var data: StateData = .init()
public var data: StateDataProtocol = StateData() as StateDataProtocol
public var node: CandidateNode = .init(name: "")
public var isASCIIMode = false
public var isVerticalCandidateWindow = false
init(_ data: StateData = .init(), type: StateType = .ofEmpty) {
init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty) {
self.data = data
self.type = type
isVerticalTyping = ctlInputMethod.isVerticalTyping
isVerticalTyping = SessionCtl.isVerticalTyping
}
init(_ data: StateData = .init(), type: StateType = .ofEmpty, node: CandidateNode) {
init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty, node: CandidateNode) {
self.data = data
self.type = type
self.node = node
@ -105,14 +68,14 @@ extension IMEState {
public static func ofAbortion() -> IMEState { .init(type: .ofAbortion) }
public static func ofCommitting(textToCommit: String) -> IMEState {
var result = IMEState(type: .ofCommitting)
result.data.textToCommit = textToCommit
result.textToCommit = textToCommit
ChineseConverter.ensureCurrencyNumerals(target: &result.data.textToCommit)
return result
}
public static func ofAssociates(candidates: [(String, String)]) -> IMEState {
var result = IMEState(type: .ofAssociates)
result.data.candidates = candidates
result.candidates = candidates
return result
}
@ -120,10 +83,10 @@ extension IMEState {
var result = IMEState(type: .ofNotEmpty)
// displayTextSegments
result.data.displayTextSegments = displayTextSegments.map {
if !ctlInputMethod.isVerticalTyping { return $0 }
if !SessionCtl.isVerticalTyping { return $0 }
guard PrefMgr.shared.hardenVerticalPunctuations else { return $0 }
var neta = $0
ChineseConverter.hardenVerticalPunctuations(target: &neta, convert: ctlInputMethod.isVerticalTyping)
ChineseConverter.hardenVerticalPunctuations(target: &neta, convert: SessionCtl.isVerticalTyping)
return neta
}
@ -133,7 +96,7 @@ extension IMEState {
}
public static func ofInputting(displayTextSegments: [String], cursor: Int) -> IMEState {
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofInputting
return result
}
@ -143,7 +106,7 @@ extension IMEState {
)
-> IMEState
{
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofMarking
result.data.marker = marker
result.data.markedReadings = markedReadings
@ -154,7 +117,7 @@ extension IMEState {
public static func ofCandidates(candidates: [(String, String)], displayTextSegments: [String], cursor: Int)
-> IMEState
{
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofCandidates
result.data.candidates = candidates
return result
@ -172,35 +135,44 @@ extension IMEState {
extension IMEState {
public var isFilterable: Bool { data.isFilterable }
public var isMarkedLengthValid: Bool { data.isMarkedLengthValid }
public var candidates: [(String, String)] { data.candidates }
public var displayedText: String { data.displayedText }
public var cursor: Int { data.cursor }
public var displayedTextConverted: String { data.displayedTextConverted }
public var displayTextSegments: [String] { data.displayTextSegments }
public var markedRange: Range<Int> { data.markedRange }
public var convertedToInputting: IMEState {
public var u16MarkedRange: Range<Int> { data.u16MarkedRange }
public var u16Cursor: Int { data.u16Cursor }
public var cursor: Int {
get { data.cursor }
set { data.cursor = newValue }
}
public var marker: Int {
get { data.marker }
set { data.marker = newValue }
}
public var convertedToInputting: IMEStateProtocol {
if type == .ofInputting { return self }
var result = IMEState.ofInputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor)
var result = Self.ofInputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor)
result.tooltip = data.tooltipBackupForInputting
result.isVerticalTyping = isVerticalTyping
return result
}
public var candidates: [(String, String)] {
get { data.candidates }
set { data.candidates = newValue }
}
public var textToCommit: String {
get {
data.textToCommit
}
set {
data.textToCommit = newValue
}
get { data.textToCommit }
set { data.textToCommit = newValue }
}
public var tooltip: String {
get {
data.tooltip
}
set {
data.tooltip = newValue
}
get { data.tooltip }
set { data.tooltip = newValue }
}
public var attributedString: NSAttributedString {
@ -231,11 +203,7 @@ extension IMEState {
}
public var tooltipBackupForInputting: String {
get {
data.tooltipBackupForInputting
}
set {
data.tooltipBackupForInputting = newValue
}
get { data.tooltipBackupForInputting }
set { data.tooltipBackupForInputting = newValue }
}
}

View File

@ -6,9 +6,11 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Shared
import Tekkon
import TooltipUI
public struct StateData {
public struct StateData: StateDataProtocol {
private static var minCandidateLength: Int {
PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2
}
@ -17,8 +19,8 @@ public struct StateData {
Self.minCandidateLength...PrefMgr.shared.maxCandidateLength
}
var displayedText: String = ""
var displayedTextConverted: String {
public var displayedText: String = ""
public var displayedTextConverted: String {
///
var result = ChineseConverter.kanjiConversionIfRequired(displayedText)
if result.utf16.count != displayedText.utf16.count
@ -31,19 +33,19 @@ public struct StateData {
// MARK: Cursor & Marker & Range for UTF8
var cursor: Int = 0 {
public var cursor: Int = 0 {
didSet {
cursor = min(max(cursor, 0), displayedText.count)
}
}
var marker: Int = 0 {
public var marker: Int = 0 {
didSet {
marker = min(max(marker, 0), displayedText.count)
}
}
var markedRange: Range<Int> {
public var markedRange: Range<Int> {
min(cursor, marker)..<max(cursor, marker)
}
@ -52,58 +54,58 @@ public struct StateData {
/// IMK UTF8 emoji
/// Swift.utf16NSString.length()
///
var u16Cursor: Int {
public var u16Cursor: Int {
displayedText.charComponents[0..<cursor].joined().utf16.count
}
var u16Marker: Int {
public var u16Marker: Int {
displayedText.charComponents[0..<marker].joined().utf16.count
}
var u16MarkedRange: Range<Int> {
public var u16MarkedRange: Range<Int> {
min(u16Cursor, u16Marker)..<max(u16Cursor, u16Marker)
}
// MARK: Other data for non-empty states.
var isVerticalTyping = false
var markedTargetExists: Bool {
public var isVerticalTyping = false
public var markedTargetExists: Bool {
let pair = userPhraseKVPair
return LMMgr.checkIfUserPhraseExist(
userPhrase: pair.1, mode: IMEApp.currentInputMode, key: pair.0
)
}
var displayTextSegments = [String]() {
public var displayTextSegments = [String]() {
didSet {
displayedText = displayTextSegments.joined()
}
}
var reading: String = ""
var markedReadings = [String]()
var candidates = [(String, String)]()
var textToCommit: String = ""
var tooltip: String = ""
var tooltipBackupForInputting: String = ""
var attributedStringPlaceholder: NSAttributedString = .init(
public var reading: String = ""
public var markedReadings = [String]()
public var candidates = [(String, String)]()
public var textToCommit: String = ""
public var tooltip: String = ""
public var tooltipBackupForInputting: String = ""
public var attributedStringPlaceholder: NSAttributedString = .init(
string: " ",
attributes: [
.underlineStyle: NSUnderlineStyle.single.rawValue,
.markedClauseSegment: 0,
]
)
var isFilterable: Bool {
public var isFilterable: Bool {
markedTargetExists ? isMarkedLengthValid : false
}
var isMarkedLengthValid: Bool {
public var isMarkedLengthValid: Bool {
Self.allowedMarkLengthRange.contains(markedRange.count)
}
var tooltipColorState: ctlTooltip.ColorStates = .normal
public var tooltipColorState: TooltipColorState = .normal
var attributedStringNormal: NSAttributedString {
public var attributedStringNormal: NSAttributedString {
///
/// JIS
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
@ -121,7 +123,7 @@ public struct StateData {
return attributedString
}
var attributedStringMarking: NSAttributedString {
public var attributedStringMarking: NSAttributedString {
///
/// JIS
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
@ -160,7 +162,7 @@ public struct StateData {
// MARK: - IMEState
extension StateData {
var chkIfUserPhraseExists: Bool {
public var doesUserPhraseExist: Bool {
let text = displayedText.charComponents[markedRange].joined()
let joined = markedReadings.joined(separator: "-")
return LMMgr.checkIfUserPhraseExist(
@ -168,7 +170,7 @@ extension StateData {
)
}
var readingThreadForDisplay: String {
public var readingThreadForDisplay: String {
var arrOutput = [String]()
for neta in markedReadings {
var neta = neta
@ -192,27 +194,27 @@ extension StateData {
return arrOutput.joined(separator: "\u{A0}")
}
var userPhraseKVPair: (String, String) {
public var userPhraseKVPair: (String, String) {
let key = markedReadings.joined(separator: "-")
let value = displayedText.charComponents[markedRange].joined()
return (key, value)
}
var userPhraseDumped: String {
public var userPhraseDumped: String {
let pair = userPhraseKVPair
let nerfedScore = ctlInputMethod.areWeNerfing && markedTargetExists ? " -114.514" : ""
let nerfedScore = SessionCtl.areWeNerfing && markedTargetExists ? " -114.514" : ""
return "\(pair.1) \(pair.0)\(nerfedScore)"
}
var userPhraseDumpedConverted: String {
public var userPhraseDumpedConverted: String {
let pair = userPhraseKVPair
let text = ChineseConverter.crossConvert(pair.1) ?? ""
let nerfedScore = ctlInputMethod.areWeNerfing && markedTargetExists ? " -114.514" : ""
let text = ChineseConverter.crossConvert(pair.1)
let nerfedScore = SessionCtl.areWeNerfing && markedTargetExists ? " -114.514" : ""
let convertedMark = "#𝙃𝙪𝙢𝙖𝙣𝘾𝙝𝙚𝙘𝙠𝙍𝙚𝙦𝙪𝙞𝙧𝙚𝙙"
return "\(text) \(pair.0)\(nerfedScore)\t\(convertedMark)"
}
mutating func updateTooltipForMarking() {
public mutating func updateTooltipForMarking() {
var tooltipForMarking: String {
let pair = userPhraseKVPair
if PrefMgr.shared.phraseReplacementEnabled {

View File

@ -20,7 +20,7 @@ import Tekkon
/// KeyHandler
public protocol KeyHandlerDelegate {
var clientBundleIdentifier: String { get }
func ctlCandidate() -> ctlCandidateProtocol
func candidateController() -> CtlCandidateProtocol
func candidateSelectionCalledByKeyHandler(at index: Int)
func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool)
-> Bool
@ -30,7 +30,7 @@ public protocol KeyHandlerDelegate {
/// KeyHandler 調
public class KeyHandler {
/// (ctlInputMethod)便
/// (SessionCtl)便
public var delegate: KeyHandlerDelegate?
public var prefs: PrefMgrProtocol

View File

@ -26,7 +26,7 @@ extension KeyHandler {
stateCallback: @escaping (IMEStateProtocol) -> Void,
errorCallback: @escaping (String) -> Void
) -> Bool {
guard var ctlCandidate = delegate?.ctlCandidate() else {
guard var ctlCandidate = delegate?.candidateController() else {
errorCallback("06661F6E")
return true
}

View File

@ -145,7 +145,7 @@ extension KeyHandler {
stateCallback(candidateState)
}
}
// ctlInputMethod IMK
// SessionCtl IMK
return true
}

View File

@ -400,7 +400,7 @@ extension KeyHandler {
// MARK: - (Still Nothing)
/// ctlInputMethod
/// SessionCtl
///
/// F1-F12
/// 便

View File

@ -114,7 +114,6 @@ extension KeyHandler {
func buildAssociatePhraseState(
withPair pair: Megrez.Compositor.KeyValuePaired
) -> IMEState {
//  Xcode
IMEState.ofAssociates(
candidates: buildAssociatePhraseArray(withPair: pair))
}
@ -127,7 +126,7 @@ extension KeyHandler {
/// - input:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleMarkingState(
_ state: IMEStateProtocol,
input: InputSignalProtocol,
@ -236,7 +235,7 @@ extension KeyHandler {
/// - isTypingVertical:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handlePunctuation(
_ customPunctuation: String,
state: IMEStateProtocol,
@ -286,7 +285,7 @@ extension KeyHandler {
/// - Parameters:
/// - state:
/// - stateCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleEnter(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void
@ -304,7 +303,7 @@ extension KeyHandler {
/// - Parameters:
/// - state:
/// - stateCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleCtrlCommandEnter(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void
@ -332,7 +331,7 @@ extension KeyHandler {
/// - Parameters:
/// - state:
/// - stateCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleCtrlOptionCommandEnter(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void
@ -370,7 +369,7 @@ extension KeyHandler {
/// - input:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleBackSpace(
state: IMEStateProtocol,
input: InputSignalProtocol,
@ -432,7 +431,7 @@ extension KeyHandler {
/// - input:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleDelete(
state: IMEStateProtocol,
input: InputSignalProtocol,
@ -476,7 +475,7 @@ extension KeyHandler {
/// - state:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleClockKey(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void,
@ -497,7 +496,7 @@ extension KeyHandler {
/// - state:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleHome(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void,
@ -529,7 +528,7 @@ extension KeyHandler {
/// - state:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleEnd(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void,
@ -560,7 +559,7 @@ extension KeyHandler {
/// - Parameters:
/// - state:
/// - stateCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleEsc(
state: IMEStateProtocol,
stateCallback: @escaping (IMEStateProtocol) -> Void
@ -592,7 +591,7 @@ extension KeyHandler {
/// - input:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleForward(
state: IMEStateProtocol,
input: InputSignalProtocol,
@ -661,7 +660,7 @@ extension KeyHandler {
/// - input:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleBackward(
state: IMEStateProtocol,
input: InputSignalProtocol,
@ -730,7 +729,7 @@ extension KeyHandler {
/// - reverseModifier:
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
/// - Returns: SessionCtl IMK
func handleInlineCandidateRotation(
state: IMEStateProtocol,
reverseModifier: Bool,

View File

@ -8,7 +8,7 @@
import BookmarkManager
import LangModelAssembly
import Megrez
import NotifierUI
import Shared
/// 使
@ -98,7 +98,7 @@ public enum LMMgr {
}
if !Self.lmCHT.isLanguageModelLoaded {
showFinishNotification = true
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Loading CHT Core Dict...", comment: "")
)
group.enter()
@ -109,7 +109,7 @@ public enum LMMgr {
}
if !Self.lmCHS.isLanguageModelLoaded {
showFinishNotification = true
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Loading CHS Core Dict...", comment: "")
)
group.enter()
@ -120,7 +120,7 @@ public enum LMMgr {
}
group.notify(queue: DispatchQueue.main) {
if showFinishNotification {
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Core Dict loading complete.", comment: "")
)
}
@ -162,7 +162,7 @@ public enum LMMgr {
case .imeModeCHS:
if !Self.lmCHS.isLanguageModelLoaded {
showFinishNotification = true
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Loading CHS Core Dict...", comment: "")
)
group.enter()
@ -174,7 +174,7 @@ public enum LMMgr {
case .imeModeCHT:
if !Self.lmCHT.isLanguageModelLoaded {
showFinishNotification = true
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Loading CHT Core Dict...", comment: "")
)
group.enter()
@ -187,7 +187,7 @@ public enum LMMgr {
}
group.notify(queue: DispatchQueue.main) {
if showFinishNotification {
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Core Dict loading complete.", comment: "")
)
}
@ -244,15 +244,11 @@ public enum LMMgr {
mode: Shared.InputMode,
key unigramKey: String
) -> Bool {
let unigrams: [Megrez.Unigram] =
(mode == .imeModeCHT)
? Self.lmCHT.unigramsFor(key: unigramKey) : Self.lmCHS.unigramsFor(key: unigramKey)
for unigram in unigrams {
if unigram.value == userPhrase {
return true
}
switch mode {
case .imeModeCHS: return lmCHS.hasKeyValuePairFor(key: unigramKey, value: userPhrase)
case .imeModeCHT: return lmCHT.hasKeyValuePairFor(key: unigramKey, value: userPhrase)
case .imeModeNULL: return false
}
return false
}
public static func setPhraseReplacementEnabled(_ state: Bool) {

View File

@ -8,7 +8,7 @@
import Shared
// MARK: Auto parameter fix procedures, executed everytime on ctlInputMethod.activateServer().
// MARK: Auto parameter fix procedures, executed everytime on SessionCtl.activateServer().
extension PrefMgr {
public func fixOddPreferences() {

View File

@ -9,9 +9,11 @@
// requirements defined in MIT License.
import IMKUtils
import PopupCompositionBuffer
import Shared
import ShiftKeyUpChecker
import Tekkon
import TooltipUI
import Voltaire
///
///
@ -21,24 +23,24 @@ import Tekkon
/// 調
/// - Remark: IMKServer
/// IMKInputController
@objc(ctlInputMethod) // ObjC IMK ObjC
class ctlInputMethod: IMKInputController {
@objc(SessionCtl) // ObjC IMK ObjC
class SessionCtl: IMKInputController {
///
static var areWeNerfing = false
///
static var ctlCandidateCurrent: ctlCandidateProtocol =
PrefMgr.shared.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
static var ctlCandidateCurrent: CtlCandidateProtocol =
PrefMgr.shared.useIMKCandidateWindow ? CtlCandidateIMK(.horizontal) : CtlCandidateUniversal(.horizontal)
///
static var tooltipInstance = ctlTooltip()
static var tooltipInstance = TooltipUI()
///
static var popupCompositionBuffer = ctlPopupCompositionBuffer()
static var popupCompositionBuffer = PopupCompositionBuffer()
// MARK: -
/// ctlInputMethod
/// SessionCtl
var isASCIIMode = false {
didSet {
resetKeyHandler()
@ -75,8 +77,46 @@ class ctlInputMethod: IMKInputController {
return result
}
// MARK: -
/// InputMode
/// IME UserPrefs
var inputMode: Shared.InputMode = IMEApp.currentInputMode {
willSet {
/// Prefs IME
IMEApp.currentInputMode = newValue
PrefMgr.shared.mostRecentInputMode = IMEApp.currentInputMode.rawValue
}
didSet {
///
keyHandler.currentLM = LMMgr.currentLM() //
keyHandler.currentUOM = LMMgr.currentUOM()
///
keyHandler.ensureKeyboardParser()
///
syncBaseLMPrefs()
}
}
///
///
/// inputClient IMKServer IMKTextInput
/// - Remark: IMKInputController client()
/// - Parameters:
/// - server: IMKServer
/// - delegate:
/// - inputClient:
override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
super.init(server: server, delegate: delegate, client: inputClient)
keyHandler.delegate = self
syncBaseLMPrefs()
//
resetKeyHandler()
activateServer(inputClient)
}
}
// MARK: -
extension SessionCtl {
///
func setKeyLayout() {
guard let client = client() else { return }
@ -101,28 +141,11 @@ class ctlInputMethod: IMKInputController {
}
handle(state: isSecureMode ? IMEState.ofAbortion() : IMEState.ofEmpty())
}
}
// MARK: - IMKInputController
///
///
/// inputClient IMKServer IMKTextInput
/// - Remark: IMKInputController client()
/// - Parameters:
/// - server: IMKServer
/// - delegate:
/// - inputClient:
override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
super.init(server: server, delegate: delegate, client: inputClient)
keyHandler.delegate = self
syncBaseLMPrefs()
//
resetKeyHandler()
activateServer(inputClient)
}
// MARK: - IMKStateSetting
// MARK: - IMKStateSetting
extension SessionCtl {
///
/// - Parameter sender: 使
override func activateServer(_ sender: Any!) {
@ -192,25 +215,6 @@ class ctlInputMethod: IMKInputController {
}
}
/// InputMode
/// IME UserPrefs
var inputMode: Shared.InputMode = IMEApp.currentInputMode {
willSet {
/// Prefs IME
IMEApp.currentInputMode = newValue
PrefMgr.shared.mostRecentInputMode = IMEApp.currentInputMode.rawValue
}
didSet {
///
keyHandler.currentLM = LMMgr.currentLM() //
keyHandler.currentUOM = LMMgr.currentUOM()
///
keyHandler.ensureKeyboardParser()
///
syncBaseLMPrefs()
}
}
///
func syncBaseLMPrefs() {
LMMgr.currentLM().isPhraseReplacementEnabled = PrefMgr.shared.phraseReplacementEnabled
@ -219,9 +223,13 @@ class ctlInputMethod: IMKInputController {
LMMgr.currentLM().isSCPCEnabled = PrefMgr.shared.useSCPCTypingMode
LMMgr.currentLM().deltaOfCalendarYears = PrefMgr.shared.deltaOfCalendarYears
}
}
// MARK: - IMKServerInput
// MARK: - IMKServerInput
// handle(_ event:) SessionCtl_HandleEvent.swift
extension SessionCtl {
///
///
///
@ -237,103 +245,6 @@ class ctlInputMethod: IMKInputController {
return Int(events.rawValue)
}
/// NSEvent
/// - Parameters:
/// - event: nil
/// - sender: 使
/// - Returns: `true` IMK`false`
@objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
_ = sender //
// MARK:
//
state.isASCIIMode = isASCIIMode
state.isVerticalTyping = isVerticalTyping
// NSEvent nilApple InputMethodKit
// client()
guard let event = event, sender is IMKTextInput else {
resetKeyHandler()
return false
}
// Shift macOS 10.15 macOS
let shouldUseShiftToggleHandle: Bool = {
switch PrefMgr.shared.shiftKeyAccommodationBehavior {
case 0: return false
case 1: return Shared.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
case 2: return true
default: return false
}
}()
/// event event var Shift
if #available(macOS 10.15, *) {
if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode {
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
NotifierController.notify(
message: isASCIIMode.toggled()
? NSLocalizedString("Alphanumerical Input Mode", comment: "")
: NSLocalizedString("Chinese Input Mode", comment: "")
)
}
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = false
}
return false
}
}
// MARK:
// Shift
if isASCIIMode { return false }
/// flags使 KeyHandler
/// flags
/// event.type == .flagsChanged return false
/// NSInternalInconsistencyException
if event.type == .flagsChanged { return false }
///
guard client() != nil else { return false }
var eventToDeal = event
//
if event.isUp || event.isDown || event.isLeft || event.isRight {
eventToDeal = event.reinitiate(charactersIgnoringModifiers: isVerticalTyping ? "Vertical" : "Horizontal") ?? event
}
// 使 NSEvent Emacs NSEvent NSEvent
if eventToDeal.isEmacsKey {
let verticalProcessing =
(state.isCandidateContainer)
? state.isVerticalCandidateWindow : state.isVerticalTyping
eventToDeal = eventToDeal.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
}
//
Self.areWeNerfing = eventToDeal.modifierFlags.contains([.shift, .command])
// IMK IMK
if let result = imkCandidatesEventHandler(event: eventToDeal) {
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result
}
return result
}
/// NSEvent commonEventHandler
/// IMK 便
let result = commonEventHandler(eventToDeal)
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result
}
return result
}
/// App Ctrl+Enter / Shift+Enter
/// handle(event:) Event
/// commitComposition
@ -344,13 +255,13 @@ class ctlInputMethod: IMKInputController {
// super.commitComposition(sender) //
}
///
/// InputMethodKit
/// - Parameter sender: 使
/// - Returns: nil
override func composedString(_ sender: Any!) -> Any! {
_ = sender //
guard state.hasComposition else { return "" }
return state.displayedText
return state.displayedTextConverted
}
///
@ -360,121 +271,4 @@ class ctlInputMethod: IMKInputController {
resetKeyHandler()
super.inputControllerWillClose()
}
// MARK: - IMKCandidates
/// IMK
/// - Parameter sender: 使
/// - Returns: IMK
override func candidates(_ sender: Any!) -> [Any]! {
_ = sender //
var arrResult = [String]()
// 便 IMEState
func handleIMKCandidatesPrepared(_ candidates: [(String, String)], prefix: String = "") {
for theCandidate in candidates {
let theConverted = ChineseConverter.kanjiConversionIfRequired(theCandidate.1)
var result = (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)\u{1A}(\(theCandidate.1))"
if arrResult.contains(result) {
let reading: String =
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: theCandidate.0))
: theCandidate.0
result = "\(result)\u{17}(\(reading))"
}
arrResult.append(prefix + result)
}
}
if state.type == .ofAssociates {
handleIMKCandidatesPrepared(state.candidates, prefix: "")
} else if state.type == .ofSymbolTable {
// / JIS 使
arrResult = state.candidates.map(\.1)
} else if state.type == .ofCandidates {
guard !state.candidates.isEmpty else { return .init() }
if state.candidates[0].0.contains("_punctuation") {
arrResult = state.candidates.map(\.1) //
} else {
handleIMKCandidatesPrepared(state.candidates)
}
}
return arrResult
}
/// IMK
/// - Parameter _:
override open func candidateSelectionChanged(_: NSAttributedString!) {
//
// IMKServer.commitCompositionWithReply() commitComposition()
// keyHandler
//
//
// ctlCandidateIMK identifier
// NSNotFound NSLog identifier
// console ips
// candidateSelected() identifier NSNotFound
// IMK 西
}
/// IMK
/// - Parameter candidateString:
override open func candidateSelected(_ candidateString: NSAttributedString!) {
let candidateString: String = candidateString?.string ?? ""
if state.type == .ofAssociates {
if !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter {
handle(state: IMEState.ofAbortion())
return
}
}
var indexDeducted = 0
// 便 IMEState
func handleIMKCandidatesSelected(_ candidates: [(String, String)], prefix: String = "") {
for (i, neta) in candidates.enumerated() {
let theConverted = ChineseConverter.kanjiConversionIfRequired(neta.1)
let netaShown = (neta.1 == theConverted) ? neta.1 : "\(theConverted)\u{1A}(\(neta.1))"
let reading: String =
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: neta.0)) : neta.0
let netaShownWithPronunciation = "\(netaShown)\u{17}(\(reading))"
if candidateString == prefix + netaShownWithPronunciation {
indexDeducted = i
break
}
if candidateString == prefix + netaShown {
indexDeducted = i
break
}
}
}
// / JIS 使
func handleSymbolCandidatesSelected(_ candidates: [(String, String)]) {
for (i, neta) in candidates.enumerated() {
if candidateString == neta.1 {
indexDeducted = i
break
}
}
}
if state.type == .ofAssociates {
handleIMKCandidatesSelected(state.candidates, prefix: "")
} else if state.type == .ofSymbolTable {
handleSymbolCandidatesSelected(state.candidates)
} else if state.type == .ofCandidates {
guard !state.candidates.isEmpty else { return }
if state.candidates[0].0.contains("_punctuation") {
handleSymbolCandidatesSelected(state.candidates) //
} else {
handleIMKCandidatesSelected(state.candidates)
}
}
candidateSelected(at: indexDeducted)
}
}

View File

@ -12,31 +12,29 @@ import Shared
// MARK: - KeyHandler Delegate
extension ctlInputMethod: KeyHandlerDelegate {
extension SessionCtl: KeyHandlerDelegate {
var clientBundleIdentifier: String {
guard let client = client() else { return "" }
return client.bundleIdentifier() ?? ""
}
func ctlCandidate() -> ctlCandidateProtocol { ctlInputMethod.ctlCandidateCurrent }
func candidateController() -> CtlCandidateProtocol { Self.ctlCandidateCurrent }
func candidateSelectionCalledByKeyHandler(at index: Int) {
candidateSelected(at: index)
candidatePairSelected(at: index)
}
func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool)
-> Bool
{
guard state.type == .ofMarking else { return false }
let refInputModeReversed: Shared.InputMode =
(inputMode == .imeModeCHT) ? .imeModeCHS : .imeModeCHT
if !LMMgr.writeUserPhrase(
state.data.userPhraseDumped, inputMode: inputMode,
areWeDuplicating: state.data.chkIfUserPhraseExists,
areWeDuplicating: state.data.doesUserPhraseExist,
areWeDeleting: addToFilter
)
|| !LMMgr.writeUserPhrase(
state.data.userPhraseDumpedConverted, inputMode: refInputModeReversed,
state.data.userPhraseDumpedConverted, inputMode: inputMode.reversed,
areWeDuplicating: false,
areWeDeleting: addToFilter
)
@ -49,48 +47,27 @@ extension ctlInputMethod: KeyHandlerDelegate {
// MARK: - Candidate Controller Delegate
extension ctlInputMethod: ctlCandidateDelegate {
var isAssociatedPhrasesState: Bool { state.type == .ofAssociates }
/// handle() IMK
/// handle()
/// IMK commonEventHandler()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
@discardableResult func sharedEventHandler(_ event: NSEvent) -> Bool {
commonEventHandler(event)
extension SessionCtl: CtlCandidateDelegate {
func buzz() {
IMEApp.buzz()
}
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int {
_ = controller //
if state.isCandidateContainer {
return state.candidates.count
}
return 0
func kanjiConversionIfRequired(_ target: String) -> String {
ChineseConverter.kanjiConversionIfRequired(target)
}
///
/// - Parameter controller:
/// - Returns:
func candidatesForController(_ controller: ctlCandidateProtocol) -> [(String, String)] {
_ = controller //
if state.isCandidateContainer {
return state.candidates
}
return .init()
func candidatePairs() -> [(String, String)] {
state.isCandidateContainer ? state.candidates : []
}
func ctlCandidate(_ controller: ctlCandidateProtocol, candidateAtIndex index: Int)
-> (String, String)
{
_ = controller //
if state.isCandidateContainer {
func candidatePairAt(_ index: Int) -> (String, String) {
if state.isCandidateContainer, state.candidates.count > index {
return state.candidates[index]
}
return ("", "")
}
func candidateSelected(at index: Int) {
func candidatePairSelected(at index: Int) {
if state.type == .ofSymbolTable, (0..<state.node.members.count).contains(index) {
let node = state.node.members[index]
if !node.members.isEmpty {

View File

@ -10,17 +10,18 @@
import NSAttributedTextView
import Shared
import Voltaire
// MARK: - Tooltip Display and Candidate Display Methods
extension ctlInputMethod {
extension SessionCtl {
// App 使
// App App
// 使 20
var attributedStringSecured: (NSAttributedString, NSRange) {
PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
? (state.data.attributedStringPlaceholder, NSRange(location: 0, length: 0))
: (state.attributedString, NSRange(state.data.u16MarkedRange))
: (state.attributedString, NSRange(state.u16MarkedRange))
}
func lineHeightRect(zeroCursor: Bool = false) -> NSRect {
@ -28,14 +29,10 @@ extension ctlInputMethod {
guard let client = client() else {
return lineHeightRect
}
var u16Cursor: Int = {
// iMessage cursor == 0
if clientBundleIdentifier == "com.apple.MobileSMS" { return state.data.u16Cursor }
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
return state.data.u16Marker //
}()
u16Cursor = max(min(state.data.displayedTextConverted.utf16.count, u16Cursor), 0)
var u16Cursor: Int = state.u16MarkedRange.lowerBound
u16Cursor = max(min(state.displayedTextConverted.utf16.count, u16Cursor), 0)
if zeroCursor { u16Cursor = 0 }
// iMessage lineHeightRect
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, u16Cursor >= 0 {
client.attributes(
forCharacterIndex: u16Cursor, lineHeightRectangle: &lineHeightRect
@ -49,7 +46,7 @@ extension ctlInputMethod {
guard client() != nil else { return }
let lineHeightRect = lineHeightRect()
var finalOrigin: NSPoint = lineHeightRect.origin
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
let delta: Double = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
if isVerticalTyping {
finalOrigin = NSPoint(
x: lineHeightRect.origin.x + lineHeightRect.size.width + 5, y: lineHeightRect.origin.y
@ -61,14 +58,14 @@ extension ctlInputMethod {
}()
// NSAttributedTextView
do {
ctlInputMethod.tooltipInstance.hide()
ctlInputMethod.tooltipInstance = .init()
Self.tooltipInstance.hide()
Self.tooltipInstance = .init()
if state.type == .ofMarking {
ctlInputMethod.tooltipInstance.setColor(state: state.data.tooltipColorState)
Self.tooltipInstance.setColor(state: state.data.tooltipColorState)
}
}
//
ctlInputMethod.tooltipInstance.show(
Self.tooltipInstance.show(
tooltip: tooltip, at: finalOrigin,
bottomOutOfScreenAdjustmentHeight: delta, direction: tooltipContentDirection
)
@ -83,7 +80,7 @@ extension ctlInputMethod {
}
if isVerticalTyping { return true }
// IMK
guard ctlInputMethod.ctlCandidateCurrent is ctlCandidateUniversal else { return false }
guard Self.ctlCandidateCurrent is CtlCandidateUniversal else { return false }
// 使
//
// 使
@ -96,7 +93,7 @@ extension ctlInputMethod {
state.isVerticalCandidateWindow = (isCandidateWindowVertical || !PrefMgr.shared.useHorizontalCandidateList)
ctlInputMethod.ctlCandidateCurrent.delegate = nil
Self.ctlCandidateCurrent.delegate = nil
/// currentLayout
/// ctlCandidate() SymbolTable
@ -109,26 +106,26 @@ extension ctlInputMethod {
? CandidateLayout.vertical
: CandidateLayout.horizontal)
ctlInputMethod.ctlCandidateCurrent =
Self.ctlCandidateCurrent =
PrefMgr.shared.useIMKCandidateWindow
? ctlCandidateIMK.init(candidateLayout) : ctlCandidateUniversal.init(candidateLayout)
? CtlCandidateIMK(candidateLayout) : CtlCandidateUniversal(candidateLayout)
// set the attributes for the candidate panel (which uses NSAttributedString)
let textSize = PrefMgr.shared.candidateListTextSize
let minimumKeyLabelSize: Double = 10
let keyLabelSize = max(textSize / 2, minimumKeyLabelSize)
func labelFont(name: String?, size: CGFloat) -> NSFont {
func labelFont(name: String?, size: Double) -> NSFont {
if let name = name {
return NSFont(name: name, size: size) ?? NSFont.systemFont(ofSize: size)
}
return NSFont.systemFont(ofSize: size)
}
ctlInputMethod.ctlCandidateCurrent.keyLabelFont = labelFont(
Self.ctlCandidateCurrent.keyLabelFont = labelFont(
name: PrefMgr.shared.candidateKeyLabelFontName, size: keyLabelSize
)
ctlInputMethod.ctlCandidateCurrent.candidateFont = ctlInputMethod.candidateFont(
Self.ctlCandidateCurrent.candidateFont = Self.candidateFont(
name: PrefMgr.shared.candidateTextFontName, size: textSize
)
@ -136,33 +133,46 @@ extension ctlInputMethod {
let keyLabels =
candidateKeys.count > 4 ? Array(candidateKeys) : Array(CandidateKey.defaultKeys)
let keyLabelSuffix = state.type == .ofAssociates ? "^" : ""
ctlInputMethod.ctlCandidateCurrent.keyLabels = keyLabels.map {
Self.ctlCandidateCurrent.keyLabels = keyLabels.map {
CandidateKeyLabel(key: String($0), displayedText: String($0) + keyLabelSuffix)
}
ctlInputMethod.ctlCandidateCurrent.delegate = self
ctlInputMethod.ctlCandidateCurrent.reloadData()
Self.ctlCandidateCurrent.delegate = self
Self.ctlCandidateCurrent.showPageButtons = PrefMgr.shared.showPageButtonsInCandidateWindow
Self.ctlCandidateCurrent.useLangIdentifier = PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier
Self.ctlCandidateCurrent.locale = {
switch inputMode {
case .imeModeCHS: return "zh-Hans"
case .imeModeCHT:
if !PrefMgr.shared.shiftJISShinjitaiOutputEnabled, !PrefMgr.shared.chineseConversionEnabled {
return "zh-Hant"
}
return "ja"
default: return ""
}
}()
Self.ctlCandidateCurrent.reloadData()
if #available(macOS 10.14, *) {
// Spotlight IMK
if let ctlCandidateCurrent = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK {
if let ctlCandidateCurrent = Self.ctlCandidateCurrent as? CtlCandidateIMK {
while ctlCandidateCurrent.windowLevel() <= client.windowLevel() {
ctlCandidateCurrent.setWindowLevel(UInt64(max(0, client.windowLevel() + 1000)))
}
}
}
ctlInputMethod.ctlCandidateCurrent.visible = true
Self.ctlCandidateCurrent.visible = true
if isVerticalTyping {
ctlInputMethod.ctlCandidateCurrent.set(
Self.ctlCandidateCurrent.set(
windowTopLeftPoint: NSPoint(
x: lineHeightRect().origin.x + lineHeightRect().size.width + 4.0, y: lineHeightRect().origin.y - 4.0
),
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
)
} else {
ctlInputMethod.ctlCandidateCurrent.set(
Self.ctlCandidateCurrent.set(
windowTopLeftPoint: NSPoint(x: lineHeightRect().origin.x, y: lineHeightRect().origin.y - 4.0),
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
)
@ -178,7 +188,7 @@ extension ctlInputMethod {
/// **REASON**: IMKCandidates has bug that it does not respect font attributes attached to the
/// results generated from `candidiates() -> [Any]!` function. IMKCandidates is plagued with
/// bugs which are not dealt in the recent decade, regardless Radar complaints from input method developers.
/// 1) Remove the usage of ".languageIdentifier" from ctlCandidateUniversal.swift (already done).
/// 1) Make sure the usage of ".languageIdentifier" is disabled in the Dev Zone of the vChewing Preferences.
/// 2) Run "make update" in the project folder to download the latest git-submodule of dictionary file.
/// 3) Compile the target "vChewingInstaller", run it. It will install the input method into
/// "~/Library/Input Methods/" folder. Remember to ENABLE BOTH "vChewing-CHS"
@ -188,7 +198,7 @@ extension ctlInputMethod {
/// 5) Do NOT enable either KangXi conversion mode nor JIS conversion mode. They are disabled by default.
/// 6) Expecting the glyph differences of the candidate "" between PingFang SC and PingFang TC when rendering
/// the candidate window in different "vChewing-CHS" and "vChewing-CHT" input modes.
static func candidateFont(name: String? = nil, size: CGFloat) -> NSFont {
static func candidateFont(name: String? = nil, size: Double) -> NSFont {
let finalReturnFont: NSFont =
{
switch IMEApp.currentInputMode {

View File

@ -0,0 +1,237 @@
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import InputMethodKit
import NotifierUI
import Shared
// MARK: - Facade
extension SessionCtl {
/// NSEvent
/// - Parameters:
/// - event: nil
/// - sender: 使
/// - Returns: `true` IMK`false`
@objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
_ = sender //
// MARK:
//
state.isASCIIMode = isASCIIMode
state.isVerticalTyping = isVerticalTyping
// NSEvent nilApple InputMethodKit
// client()
guard let event = event, sender is IMKTextInput else {
resetKeyHandler()
return false
}
// Shift macOS 10.15 macOS
let shouldUseShiftToggleHandle: Bool = {
switch PrefMgr.shared.shiftKeyAccommodationBehavior {
case 0: return false
case 1: return Shared.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
case 2: return true
default: return false
}
}()
/// event event var Shift
if #available(macOS 10.15, *) {
if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode {
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
let status = NSLocalizedString("NotificationSwitchShift", comment: "")
Notifier.notify(
message: isASCIIMode.toggled()
? NSLocalizedString("Alphanumerical Input Mode", comment: "") + "\n" + status
: NSLocalizedString("Chinese Input Mode", comment: "") + "\n" + status
)
}
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = false
}
return false
}
}
// MARK:
// Shift
if isASCIIMode { return false }
/// flags使 KeyHandler
/// flags
/// event.type == .flagsChanged return false
/// NSInternalInconsistencyException
if event.type == .flagsChanged { return false }
///
guard client() != nil else { return false }
var eventToDeal = event
//
if event.isUp || event.isDown || event.isLeft || event.isRight {
eventToDeal = event.reinitiate(charactersIgnoringModifiers: isVerticalTyping ? "Vertical" : "Horizontal") ?? event
}
// 使 NSEvent Emacs NSEvent NSEvent
if eventToDeal.isEmacsKey {
let verticalProcessing = (state.isCandidateContainer) ? state.isVerticalCandidateWindow : state.isVerticalTyping
eventToDeal = eventToDeal.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
}
//
Self.areWeNerfing = eventToDeal.modifierFlags.contains([.shift, .command])
// IMK IMK
if let result = imkCandidatesEventPreHandler(event: eventToDeal) {
if shouldUseShiftToggleHandle { rencentKeyHandledByKeyHandlerEtc = result }
return result
}
/// NSEvent commonEventHandler
/// IMK 便
let result = commonEventHandler(eventToDeal)
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result
}
return result
}
}
// MARK: - Private functions
extension SessionCtl {
/// handle() IMK
/// handle()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
private func commonEventHandler(_ event: NSEvent) -> Bool {
//
// KeyHandler
if !event.charCode.isPrintable { return false }
/// 調
/// result bool IMK
/// keyHandler.handleCandidate()
let result = keyHandler.handle(input: event, state: state) { newState in
self.handle(state: newState)
} errorCallback: { errorString in
vCLog(errorString)
IMEApp.buzz()
}
return result
}
/// handle() IMK
/// handle()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
private func imkCandidatesEventPreHandler(event eventToDeal: NSEvent) -> Bool? {
// IMK IMK
// interpretKeyEvents()
// - imkCandidates.interpretKeyEvents()
// - delegate SessionCtl KeyHandler
if let imkCandidates = Self.ctlCandidateCurrent as? CtlCandidateIMK, imkCandidates.visible {
let event: NSEvent = CtlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
// Shift+Enter delegate keyHandler
// Shift Flags
if event.isShiftHold, event.isEnter {
guard let newEvent = event.reinitiate(modifierFlags: []) else {
NSSound.beep()
return true
}
return imkCandidatesEventSubHandler(event: newEvent)
}
//
if let newChar = CtlCandidateIMK.defaultIMKSelectionKey[event.keyCode],
event.isShiftHold, state.type == .ofAssociates,
let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
{
if #available(macOS 10.14, *) {
imkCandidates.handleKeyboardEvent(newEvent)
} else {
imkCandidates.interpretKeyEvents([newEvent])
}
return true
}
return imkCandidatesEventSubHandler(event: event)
}
return nil
}
private func imkCandidatesEventSubHandler(event: NSEvent) -> Bool {
let eventArray = [event]
guard let imkC = Self.ctlCandidateCurrent as? CtlCandidateIMK else { return false }
if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) {
return commonEventHandler(event)
} else if event.isSymbolMenuPhysicalKey {
//
switch imkC.currentLayout {
case .horizontal: _ = event.isShiftHold ? imkC.moveUp(self) : imkC.moveDown(self)
case .vertical: _ = event.isShiftHold ? imkC.moveLeft(self) : imkC.moveRight(self)
}
return true
} else if event.isSpace {
switch PrefMgr.shared.specifyShiftSpaceKeyBehavior {
case true: _ = event.isShiftHold ? imkC.highlightNextCandidate() : imkC.showNextPage()
case false: _ = event.isShiftHold ? imkC.showNextPage() : imkC.highlightNextCandidate()
}
return true
} else if event.isTab {
switch PrefMgr.shared.specifyShiftTabKeyBehavior {
case true: _ = event.isShiftHold ? imkC.showPreviousPage() : imkC.showNextPage()
case false: _ = event.isShiftHold ? imkC.highlightPreviousCandidate() : imkC.highlightNextCandidate()
}
return true
} else {
if let newChar = CtlCandidateIMK.defaultIMKSelectionKey[event.keyCode] {
/// KeyCode NSEvent Character
/// IMK
let newEvent = event.reinitiate(characters: newChar)
if let newEvent = newEvent {
if PrefMgr.shared.useSCPCTypingMode, state.type == .ofAssociates {
// input.isShiftHold Self.handle()
return event.isShiftHold ? true : commonEventHandler(event)
} else {
if #available(macOS 10.14, *) {
imkC.handleKeyboardEvent(newEvent)
} else {
imkC.interpretKeyEvents([newEvent])
}
return true
}
}
}
if PrefMgr.shared.useSCPCTypingMode, !event.isReservedKey {
return commonEventHandler(event)
}
if state.type == .ofAssociates,
!event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward,
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
!event.isEnter || !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter
{
return commonEventHandler(event)
}
imkC.interpretKeyEvents(eventArray)
return true
}
}
}

View File

@ -8,9 +8,12 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import PopupCompositionBuffer
import Shared
// MARK: - 調 (State Handling)
extension ctlInputMethod {
extension SessionCtl {
/// 調
///
///
@ -21,9 +24,9 @@ extension ctlInputMethod {
state = newState
switch state.type {
case .ofDeactivated:
ctlInputMethod.ctlCandidateCurrent.delegate = nil
ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipInstance.hide()
Self.ctlCandidateCurrent.delegate = nil
Self.ctlCandidateCurrent.visible = false
Self.tooltipInstance.hide()
if previous.hasComposition {
commit(text: previous.displayedText)
}
@ -36,29 +39,29 @@ extension ctlInputMethod {
state = IMEState.ofEmpty()
previous = state
}
ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipInstance.hide()
Self.ctlCandidateCurrent.visible = false
Self.tooltipInstance.hide()
// .Abortion
if previous.hasComposition, state.type != .ofAbortion {
commit(text: previous.displayedText)
}
//
ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipInstance.hide()
Self.ctlCandidateCurrent.visible = false
Self.tooltipInstance.hide()
clearInlineDisplay()
//
keyHandler.clear()
case .ofCommitting:
ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipInstance.hide()
Self.ctlCandidateCurrent.visible = false
Self.tooltipInstance.hide()
let textToCommit = state.textToCommit
if !textToCommit.isEmpty { commit(text: textToCommit) }
clearInlineDisplay()
//
keyHandler.clear()
case .ofInputting:
ctlInputMethod.ctlCandidateCurrent.visible = false
ctlInputMethod.tooltipInstance.hide()
Self.ctlCandidateCurrent.visible = false
Self.tooltipInstance.hide()
let textToCommit = state.textToCommit
if !textToCommit.isEmpty { commit(text: textToCommit) }
setInlineDisplayWithCursor()
@ -66,27 +69,27 @@ extension ctlInputMethod {
show(tooltip: state.tooltip)
}
case .ofMarking:
ctlInputMethod.ctlCandidateCurrent.visible = false
Self.ctlCandidateCurrent.visible = false
setInlineDisplayWithCursor()
if state.tooltip.isEmpty {
ctlInputMethod.tooltipInstance.hide()
Self.tooltipInstance.hide()
} else {
show(tooltip: state.tooltip)
}
case .ofCandidates, .ofAssociates, .ofSymbolTable:
ctlInputMethod.tooltipInstance.hide()
Self.tooltipInstance.hide()
setInlineDisplayWithCursor()
showCandidates()
default: break
}
//
if state.hasComposition, PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) {
ctlInputMethod.popupCompositionBuffer.isTypingDirectionVertical = isVerticalTyping
ctlInputMethod.popupCompositionBuffer.show(
Self.popupCompositionBuffer.isTypingDirectionVertical = isVerticalTyping
Self.popupCompositionBuffer.show(
state: state, at: lineHeightRect(zeroCursor: true).origin
)
} else {
ctlInputMethod.popupCompositionBuffer.hide()
Self.popupCompositionBuffer.hide()
}
}

View File

@ -0,0 +1,129 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Foundation
import Tekkon
// MARK: - IMKCandidates
extension SessionCtl {
/// IMK
/// - Parameter sender: 使
/// - Returns: IMK
override func candidates(_ sender: Any!) -> [Any]! {
_ = sender //
var arrResult = [String]()
// 便 IMEState
func handleIMKCandidatesPrepared(_ candidates: [(String, String)], prefix: String = "") {
for theCandidate in candidates {
let theConverted = ChineseConverter.kanjiConversionIfRequired(theCandidate.1)
var result = (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)\u{1A}(\(theCandidate.1))"
if arrResult.contains(result) {
let reading: String =
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: theCandidate.0))
: theCandidate.0
result = "\(result)\u{17}(\(reading))"
}
arrResult.append(prefix + result)
}
}
if state.type == .ofAssociates {
handleIMKCandidatesPrepared(state.candidates, prefix: "")
} else if state.type == .ofSymbolTable {
// / JIS 使
arrResult = state.candidates.map(\.1)
} else if state.type == .ofCandidates {
guard !state.candidates.isEmpty else { return .init() }
if state.candidates[0].0.contains("_punctuation") {
arrResult = state.candidates.map(\.1) //
} else {
handleIMKCandidatesPrepared(state.candidates)
}
}
return arrResult
}
/// IMK
/// - Parameter _:
override open func candidateSelectionChanged(_: NSAttributedString!) {
//
// IMKServer.commitCompositionWithReply() commitComposition()
// keyHandler
//
//
// ctlCandidateIMK identifier
// NSNotFound NSLog identifier
// console ips
// candidateSelected() identifier NSNotFound
// IMK 西
}
/// IMK
/// - Parameter candidateString:
override open func candidateSelected(_ candidateString: NSAttributedString!) {
let candidateString: String = candidateString?.string ?? ""
if state.type == .ofAssociates {
if !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter {
handle(state: IMEState.ofAbortion())
return
}
}
var indexDeducted = 0
// 便 IMEState
func handleIMKCandidatesSelected(_ candidates: [(String, String)], prefix: String = "") {
for (i, neta) in candidates.enumerated() {
let theConverted = ChineseConverter.kanjiConversionIfRequired(neta.1)
let netaShown = (neta.1 == theConverted) ? neta.1 : "\(theConverted)\u{1A}(\(neta.1))"
let reading: String =
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: neta.0)) : neta.0
let netaShownWithPronunciation = "\(netaShown)\u{17}(\(reading))"
if candidateString == prefix + netaShownWithPronunciation {
indexDeducted = i
break
}
if candidateString == prefix + netaShown {
indexDeducted = i
break
}
}
}
// / JIS 使
func handleSymbolCandidatesSelected(_ candidates: [(String, String)]) {
for (i, neta) in candidates.enumerated() {
if candidateString == neta.1 {
indexDeducted = i
break
}
}
}
if state.type == .ofAssociates {
handleIMKCandidatesSelected(state.candidates, prefix: "")
} else if state.type == .ofSymbolTable {
handleSymbolCandidatesSelected(state.candidates)
} else if state.type == .ofCandidates {
guard !state.candidates.isEmpty else { return }
if state.candidates[0].0.contains("_punctuation") {
handleSymbolCandidatesSelected(state.candidates) //
} else {
handleIMKCandidatesSelected(state.candidates)
}
}
candidatePairSelected(at: indexDeducted)
}
}

View File

@ -8,6 +8,7 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import NotifierUI
import Preferences
extension Bool {
@ -20,7 +21,7 @@ extension Bool {
//
extension ctlInputMethod {
extension SessionCtl {
override func menu() -> NSMenu! {
let optionKeyPressed = NSEvent.modifierFlags.contains(.option)
@ -191,7 +192,7 @@ extension ctlInputMethod {
// MARK: - IME Menu Items
extension ctlInputMethod {
extension SessionCtl {
@objc override func showPreferences(_: Any?) {
if #unavailable(macOS 10.15) {
showLegacyPreferences()
@ -223,7 +224,7 @@ extension ctlInputMethod {
@objc func toggleSCPCTypingMode(_: Any? = nil) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
+ (PrefMgr.shared.useSCPCTypingMode.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -233,7 +234,7 @@ extension ctlInputMethod {
@objc func toggleChineseConverter(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
+ (PrefMgr.shared.chineseConversionEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -243,7 +244,7 @@ extension ctlInputMethod {
@objc func toggleShiftJISShinjitaiOutput(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
+ (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -253,7 +254,7 @@ extension ctlInputMethod {
@objc func toggleCurrencyNumerals(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
+ (PrefMgr.shared.currencyNumeralsEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -263,7 +264,7 @@ extension ctlInputMethod {
@objc func toggleHalfWidthPunctuation(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
+ (PrefMgr.shared.halfWidthPunctuationEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -273,7 +274,7 @@ extension ctlInputMethod {
@objc func toggleCNS11643Enabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
+ (PrefMgr.shared.cns11643Enabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -283,7 +284,7 @@ extension ctlInputMethod {
@objc func toggleSymbolEnabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
+ (PrefMgr.shared.symbolInputEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -293,7 +294,7 @@ extension ctlInputMethod {
@objc func toggleAssociatedPhrasesEnabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
+ (PrefMgr.shared.associatedPhrasesEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
@ -303,7 +304,7 @@ extension ctlInputMethod {
@objc func togglePhraseReplacement(_: Any?) {
resetKeyHandler()
NotifierController.notify(
Notifier.notify(
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
+ (PrefMgr.shared.phraseReplacementEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")

View File

@ -6,12 +6,19 @@
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
import CandidateWindow
import Shared
/// IMKCandidates bridging header Swift Package
public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
public var showPageButtons: Bool = false
public var locale: String = ""
public var useLangIdentifier: Bool = false
public var currentLayout: CandidateLayout = .horizontal
public static let defaultIMKSelectionKey: [UInt16: String] = [
18: "1", 19: "2", 20: "3", 21: "4", 23: "5", 22: "6", 26: "7", 28: "8", 25: "9",
]
public weak var delegate: ctlCandidateDelegate? {
public weak var delegate: CtlCandidateDelegate? {
didSet {
reloadData()
}
@ -40,26 +47,15 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
ofSize: 14, weight: .medium
)
public var candidateFont = NSFont.systemFont(ofSize: PrefMgr.shared.candidateListTextSize) {
public var candidateFont = NSFont.systemFont(ofSize: 16) {
didSet {
if #available(macOS 10.14, *) { setFontSize(candidateFont.pointSize) }
var attributes = attributes()
// FB11300759: Set "NSAttributedString.Key.font" doesn't work.
attributes?[NSAttributedString.Key.font] = candidateFont
if PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier {
switch IMEApp.currentInputMode {
case .imeModeCHS:
if #available(macOS 12.0, *) {
attributes?[NSAttributedString.Key.languageIdentifier] = "zh-Hans" as AnyObject
}
case .imeModeCHT:
if #available(macOS 12.0, *) {
attributes?[NSAttributedString.Key.languageIdentifier] =
(PrefMgr.shared.shiftJISShinjitaiOutputEnabled || PrefMgr.shared.chineseConversionEnabled)
? "ja" as AnyObject : "zh-Hant" as AnyObject
}
default:
break
if #available(macOS 12.0, *) {
if useLangIdentifier {
attributes?[NSAttributedString.Key.languageIdentifier] = locale as AnyObject
}
}
setAttributes(attributes)
@ -119,7 +115,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
private var pageCount: Int {
guard let delegate = delegate else { return 0 }
let totalCount = delegate.candidateCountForController(self)
let totalCount = delegate.candidatePairs().count
let keyLabelCount = keyLabels.count
return totalCount / keyLabelCount + ((totalCount % keyLabelCount) != 0 ? 1 : 0)
}
@ -151,7 +147,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
public func candidateIndexAtKeyLabelIndex(_ index: Int) -> Int {
guard let delegate = delegate else { return Int.max }
let result = currentPageIndex * keyLabels.count + index
return result < delegate.candidateCountForController(self) ? result : Int.max
return result < delegate.candidatePairs().count ? result : Int.max
}
public var selectedCandidateIndex: Int {
@ -159,17 +155,17 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
set { selectCandidate(withIdentifier: newValue) }
}
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat) {
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: Double) {
DispatchQueue.main.async {
self.doSet(windowTopLeftPoint: windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: height)
}
}
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: Double) {
guard var screenFrame = NSScreen.main?.visibleFrame else { return }
var adjustedPoint = windowTopLeftPoint
let windowSize = candidateFrame().size
var delta = heightDelta
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for frame in NSScreen.screens.map(\.visibleFrame).filter({ $0.contains(windowTopLeftPoint) }) {
screenFrame = frame
break
@ -185,74 +181,6 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
setCandidateFrameTopLeft(adjustedPoint)
}
override public func interpretKeyEvents(_ eventArray: [NSEvent]) {
//
// Objective-C nil
guard !eventArray.isEmpty else { return }
let event = eventArray[0]
guard let delegate = delegate else { return }
if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) {
_ = delegate.sharedEventHandler(event)
} else if event.isSymbolMenuPhysicalKey {
//
switch currentLayout {
case .horizontal: event.isShiftHold ? moveUp(self) : moveDown(self)
case .vertical: event.isShiftHold ? moveLeft(self) : moveRight(self)
}
} else if event.isSpace {
switch PrefMgr.shared.specifyShiftSpaceKeyBehavior {
case true: _ = event.isShiftHold ? highlightNextCandidate() : showNextPage()
case false: _ = event.isShiftHold ? showNextPage() : highlightNextCandidate()
}
} else if event.isTab {
switch PrefMgr.shared.specifyShiftTabKeyBehavior {
case true: _ = event.isShiftHold ? showPreviousPage() : showNextPage()
case false: _ = event.isShiftHold ? highlightPreviousCandidate() : highlightNextCandidate()
}
} else {
if let newChar = Self.defaultIMKSelectionKey[event.keyCode] {
/// KeyCode NSEvent Character
/// IMK
let newEvent = event.reinitiate(characters: newChar)
if let newEvent = newEvent {
if PrefMgr.shared.useSCPCTypingMode, delegate.isAssociatedPhrasesState {
// input.isShiftHold ctlInputMethod.handle()
if !event.isShiftHold {
_ = delegate.sharedEventHandler(event)
return
}
} else {
if #available(macOS 10.14, *) {
handleKeyboardEvent(newEvent)
} else {
super.interpretKeyEvents([newEvent])
}
return
}
}
}
if PrefMgr.shared.useSCPCTypingMode, !event.isReservedKey {
_ = delegate.sharedEventHandler(event)
return
}
if delegate.isAssociatedPhrasesState,
!event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward,
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
!event.isEnter || !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter
{
_ = delegate.sharedEventHandler(event)
return
}
super.interpretKeyEvents(eventArray)
}
}
public func superInterpretKeyEvents(_ eventArray: [NSEvent]) {
super.interpretKeyEvents(eventArray)
}
}
// MARK: - Generate TISInputSource Object
@ -277,7 +205,7 @@ var currentTISInputSource: TISInputSource? {
// MARK: - Translating NumPad KeyCodes to Default IMK Candidate Selection KeyCodes.
extension ctlCandidateIMK {
extension CtlCandidateIMK {
public static func replaceNumPadKeyCodes(target event: NSEvent) -> NSEvent? {
let mapNumPadKeyCodeTranslation: [UInt16: UInt16] = [
83: 18, 84: 19, 85: 20, 86: 21, 87: 23, 88: 22, 89: 26, 91: 28, 92: 25,

View File

@ -1,175 +0,0 @@
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
public enum CandidateLayout {
case horizontal
case vertical
}
public class CandidateKeyLabel: NSObject {
public private(set) var key: String
public private(set) var displayedText: String
public init(key: String, displayedText: String) {
self.key = key
self.displayedText = displayedText
super.init()
}
}
public protocol ctlCandidateDelegate: AnyObject {
var isAssociatedPhrasesState: Bool { get }
func sharedEventHandler(_ event: NSEvent) -> Bool
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int
func candidatesForController(_ controller: ctlCandidateProtocol) -> [(String, String)]
func ctlCandidate(_ controller: ctlCandidateProtocol, candidateAtIndex index: Int)
-> (String, String)
func candidateSelected(at index: Int)
}
public protocol ctlCandidateProtocol {
var currentLayout: CandidateLayout { get set }
var delegate: ctlCandidateDelegate? { get set }
var selectedCandidateIndex: Int { get set }
var visible: Bool { get set }
var windowTopLeftPoint: NSPoint { get set }
var keyLabels: [CandidateKeyLabel] { get set }
var keyLabelFont: NSFont { get set }
var candidateFont: NSFont { get set }
var tooltip: String { get set }
init(_ layout: CandidateLayout)
func reloadData()
func showNextPage() -> Bool
func showPreviousPage() -> Bool
func highlightNextCandidate() -> Bool
func highlightPreviousCandidate() -> Bool
func candidateIndexAtKeyLabelIndex(_: Int) -> Int
func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat)
}
public class ctlCandidate: NSWindowController, ctlCandidateProtocol {
public var currentLayout: CandidateLayout = .horizontal
public weak var delegate: ctlCandidateDelegate? {
didSet {
reloadData()
}
}
public var selectedCandidateIndex: Int = .max
public var visible = false {
didSet {
NSObject.cancelPreviousPerformRequests(withTarget: self)
if visible {
window?.perform(#selector(NSWindow.orderFront(_:)), with: self, afterDelay: 0.0)
} else {
window?.perform(#selector(NSWindow.orderOut(_:)), with: self, afterDelay: 0.0)
}
}
}
public var windowTopLeftPoint: NSPoint {
get {
guard let frameRect = window?.frame else {
return NSPoint.zero
}
return NSPoint(x: frameRect.minX, y: frameRect.maxY)
}
set {
DispatchQueue.main.async {
self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0)
}
}
}
public required init(_: CandidateLayout = .horizontal) {
super.init(window: .init())
visible = false
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public var keyLabels: [CandidateKeyLabel] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
.map {
CandidateKeyLabel(key: $0, displayedText: $0)
}
public var keyLabelFont = NSFont.monospacedDigitSystemFont(
ofSize: 14, weight: .medium
)
public var candidateFont = NSFont.systemFont(ofSize: 18)
public var tooltip: String = ""
public func reloadData() {}
@discardableResult public func showNextPage() -> Bool {
false
}
@discardableResult public func showPreviousPage() -> Bool {
false
}
@discardableResult public func highlightNextCandidate() -> Bool {
false
}
@discardableResult public func highlightPreviousCandidate() -> Bool {
false
}
public func candidateIndexAtKeyLabelIndex(_: Int) -> Int {
Int.max
}
/// Sets the location of the candidate window.
///
/// Please note that the method has side effects that modifies
/// `windowTopLeftPoint` to make the candidate window to stay in at least
/// in a screen.
///
/// - Parameters:
/// - windowTopLeftPoint: The given location.
/// - height: The height that helps the window not to be out of the bottom
/// of a screen.
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat) {
DispatchQueue.main.async {
self.doSet(
windowTopLeftPoint: windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: height
)
}
}
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
guard let window = window else { return }
let windowSize = window.frame.size
var adjustedPoint = windowTopLeftPoint
var delta = heightDelta
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for frame in NSScreen.screens.map(\.visibleFrame).filter({ $0.contains(windowTopLeftPoint) }) {
screenFrame = frame
break
}
if delta > screenFrame.size.height / 2.0 { delta = 0.0 }
if adjustedPoint.y < screenFrame.minY + windowSize.height {
adjustedPoint.y = windowTopLeftPoint.y + windowSize.height + delta
}
adjustedPoint.y = min(adjustedPoint.y, screenFrame.maxY - 1.0)
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width - 1.0)
window.setFrameTopLeftPoint(adjustedPoint)
}
}

View File

@ -1,226 +0,0 @@
// (c) 2021 and onwards Weizhong Yang (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
private protocol NotifierWindowDelegate: AnyObject {
func windowDidBecomeClicked(_ window: NotifierWindow)
}
private class NotifierWindow: NSWindow {
weak var clickDelegate: NotifierWindowDelegate?
override func mouseDown(with _: NSEvent) {
clickDelegate?.windowDidBecomeClicked(self)
}
}
private let kWindowWidth: CGFloat = 213.0
private let kWindowHeight: CGFloat = 60.0
public class NotifierController: NSWindowController, NotifierWindowDelegate {
static var message: String = "" {
didSet {
if !Self.message.isEmpty {
NotifierController.initiateWithNoStay(message: message)
Self.message = ""
}
}
}
private var messageTextField: NSTextField
private var message: String = "" {
didSet {
let paraStyle = NSMutableParagraphStyle()
paraStyle.setParagraphStyle(NSParagraphStyle.default)
paraStyle.alignment = .center
let attr: [NSAttributedString.Key: AnyObject] = [
.foregroundColor: foregroundColor,
.font: NSFont.boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular)),
.paragraphStyle: paraStyle,
]
let attrString = NSAttributedString(string: message, attributes: attr)
messageTextField.attributedStringValue = attrString
let width = window?.frame.width ?? kWindowWidth
let rect = attrString.boundingRect(
with: NSSize(width: width, height: 1600), options: .usesLineFragmentOrigin
)
let height = rect.height
let x = messageTextField.frame.origin.x
let y = ((window?.frame.height ?? kWindowHeight) - height) / 2
let newFrame = NSRect(x: x, y: y, width: width, height: height)
messageTextField.frame = newFrame
}
}
private var shouldStay = false
private var backgroundColor: NSColor = .textBackgroundColor {
didSet {
window?.backgroundColor = backgroundColor
}
}
private var foregroundColor: NSColor = .controlTextColor {
didSet {
messageTextField.textColor = foregroundColor
}
}
private var waitTimer: Timer?
private var fadeTimer: Timer?
private static var instanceCount = 0
private static var lastLocation = NSPoint.zero
private static func initiateWithNoStay(message: String) {
let controller = NotifierController()
controller.message = message
controller.show()
}
public static func notify(message: String) {
Self.message = message
}
public static func notify(message: String, stay: Bool) {
let controller = NotifierController()
controller.message = message
controller.shouldStay = stay
controller.show()
}
private static func increaseInstanceCount() {
instanceCount += 1
}
private static func decreaseInstanceCount() {
instanceCount -= 1
if instanceCount < 0 {
instanceCount = 0
}
}
private init() {
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
let contentRect = NSRect(x: 0, y: 0, width: kWindowWidth, height: kWindowHeight)
var windowRect = contentRect
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
windowRect.origin.y = screenRect.maxY - windowRect.height - 10
let styleMask: NSWindow.StyleMask = [.fullSizeContentView, .titled]
let transparentVisualEffect = NSVisualEffectView()
transparentVisualEffect.blendingMode = .behindWindow
transparentVisualEffect.state = .active
let panel = NotifierWindow(
contentRect: windowRect, styleMask: styleMask, backing: .buffered, defer: false
)
panel.contentView = transparentVisualEffect
panel.isMovableByWindowBackground = true
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel))
panel.hasShadow = true
panel.backgroundColor = backgroundColor
panel.title = ""
panel.titlebarAppearsTransparent = true
panel.titleVisibility = .hidden
panel.showsToolbarButton = false
panel.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
panel.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
panel.standardWindowButton(NSWindow.ButtonType.closeButton)?.isHidden = true
panel.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
messageTextField = NSTextField()
messageTextField.frame = contentRect
messageTextField.isEditable = false
messageTextField.isSelectable = false
messageTextField.isBezeled = false
messageTextField.textColor = foregroundColor
messageTextField.drawsBackground = false
messageTextField.font = .boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular))
panel.contentView?.addSubview(messageTextField)
super.init(window: panel)
panel.clickDelegate = self
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func show() {
func setStartLocation() {
if Self.instanceCount == 0 {
return
}
let lastLocation = Self.lastLocation
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
var windowRect = window?.frame ?? NSRect.seniorTheBeast
windowRect.origin.x = lastLocation.x
windowRect.origin.y = lastLocation.y - 10 - windowRect.height
if windowRect.origin.y < screenRect.minY {
return
}
window?.setFrame(windowRect, display: true)
}
func moveIn() {
let afterRect = window?.frame ?? NSRect.seniorTheBeast
Self.lastLocation = afterRect.origin
var beforeRect = afterRect
beforeRect.origin.y += 10
window?.setFrame(beforeRect, display: true)
window?.orderFront(self)
window?.setFrame(afterRect, display: true, animate: true)
}
setStartLocation()
moveIn()
Self.increaseInstanceCount()
waitTimer = Timer.scheduledTimer(
timeInterval: shouldStay ? 5 : 1, target: self, selector: #selector(fadeOut),
userInfo: nil,
repeats: false
)
}
@objc private func doFadeOut(_: Timer) {
let opacity = window?.alphaValue ?? 0
if opacity <= 0 {
close()
} else {
window?.alphaValue = opacity - 0.2
}
}
@objc private func fadeOut() {
waitTimer?.invalidate()
waitTimer = nil
Self.decreaseInstanceCount()
fadeTimer = Timer.scheduledTimer(
timeInterval: 0.01, target: self, selector: #selector(doFadeOut(_:)), userInfo: nil,
repeats: true
)
}
override public func close() {
waitTimer?.invalidate()
waitTimer = nil
fadeTimer?.invalidate()
fadeTimer = nil
super.close()
}
fileprivate func windowDidBecomeClicked(_: NotifierWindow) {
fadeOut()
}
}

View File

@ -19,7 +19,7 @@ struct suiPrefPaneDevZone: View {
@State private var selShiftKeyAccommodationBehavior: Int = UserDefaults.standard.integer(
forKey: UserDef.kShiftKeyAccommodationBehavior.rawValue)
private let contentMaxHeight: Double = 432
private let contentMaxHeight: Double = 440
private let contentWidth: Double = {
switch PrefMgr.shared.appleLanguages[0] {
case "ja":

View File

@ -37,7 +37,7 @@ struct suiPrefPaneDictionary: View {
private static let dlgOpenPath = NSOpenPanel()
private let contentMaxHeight: Double = 432
private let contentMaxHeight: Double = 440
private let contentWidth: Double = {
switch PrefMgr.shared.appleLanguages[0] {
case "ja":

View File

@ -48,7 +48,7 @@ struct suiPrefPaneExperience: View {
@State private var selAlwaysShowTooltipTextsHorizontally = UserDefaults.standard.bool(
forKey: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue)
private let contentMaxHeight: Double = 432
private let contentMaxHeight: Double = 440
private let contentWidth: Double = {
switch PrefMgr.shared.appleLanguages[0] {
case "ja":

View File

@ -39,7 +39,7 @@ struct suiPrefPaneGeneral: View {
forKey: UserDef.kCheckUpdateAutomatically.rawValue)
@State private var selEnableDebugMode = UserDefaults.standard.bool(forKey: UserDef.kIsDebugModeEnabled.rawValue)
private let contentMaxHeight: Double = 432
private let contentMaxHeight: Double = 440
private let contentWidth: Double = {
switch PrefMgr.shared.appleLanguages[0] {
case "ja":
@ -60,7 +60,7 @@ struct suiPrefPaneGeneral: View {
Picker(
"",
selection: $selCandidateUIFontSize.onChange {
PrefMgr.shared.candidateListTextSize = CGFloat(selCandidateUIFontSize)
PrefMgr.shared.candidateListTextSize = Double(selCandidateUIFontSize)
}
) {
Group {

View File

@ -34,7 +34,7 @@ struct suiPrefPaneKeyboard: View {
@State private var selUsingHotKeyCurrencyNumerals = UserDefaults.standard.bool(
forKey: UserDef.kUsingHotKeyCurrencyNumerals.rawValue)
private let contentMaxHeight: Double = 432
private let contentMaxHeight: Double = 440
private let contentWidth: Double = {
switch PrefMgr.shared.appleLanguages[0] {
case "ja":

View File

@ -53,7 +53,7 @@ extension ctlClientListMgr {
alert.addButton(withTitle: NSLocalizedString("Just Select", comment: "") + "")
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
let maxFloat = CGFloat(Float.greatestFiniteMagnitude)
let maxFloat = Double(Float.greatestFiniteMagnitude)
let scrollview = NSScrollView(frame: NSRect(x: 0, y: 0, width: 370, height: 380))
let contentSize = scrollview.contentSize
scrollview.borderType = .noBorder

View File

@ -12,7 +12,7 @@ import BookmarkManager
import IMKUtils
import Shared
private let kWindowTitleHeight: CGFloat = 78
private let kWindowTitleHeight: Double = 78
extension NSToolbarItem.Identifier {
fileprivate static let ofGeneral = NSToolbarItem.Identifier(rawValue: "tabGeneral")

View File

@ -1,76 +0,0 @@
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import InputMethodKit
import Shared
extension ctlInputMethod {
/// handle() IMK
/// handle()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
func commonEventHandler(_ event: NSEvent) -> Bool {
//
// KeyHandler
if !event.charCode.isPrintable { return false }
/// 調
/// result bool IMK
/// keyHandler.handleCandidate()
let result = keyHandler.handle(input: event, state: state) { newState in
self.handle(state: newState)
} errorCallback: { errorString in
vCLog(errorString)
IMEApp.buzz()
}
return result
}
/// handle() IMK
/// handle()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
func imkCandidatesEventHandler(event eventToDeal: NSEvent) -> Bool? {
// IMK IMK
// interpretKeyEvents()
// - super.interpretKeyEvents()
// - delegate ctlInputMethod KeyHandler
if let imkCandidates = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, imkCandidates.visible {
let event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
// Shift+Enter delegate keyHandler
// Shift Flags
if event.isShiftHold, event.isEnter {
guard let newEvent = event.reinitiate(modifierFlags: []) else {
NSSound.beep()
return true
}
imkCandidates.interpretKeyEvents([newEvent])
return true
}
//
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode],
event.isShiftHold, isAssociatedPhrasesState,
let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
{
if #available(macOS 10.14, *) {
imkCandidates.handleKeyboardEvent(newEvent)
} else {
imkCandidates.superInterpretKeyEvents([newEvent])
}
}
imkCandidates.interpretKeyEvents([event])
return true
}
return nil
}
}

View File

@ -38,6 +38,7 @@
"Force KangXi Writing" = "Force KangXi Writing";
"NotificationSwitchON" = "✔ ON";
"NotificationSwitchOFF" = "✘ OFF";
"NotificationSwitchShift" = "↺ Switched";
"Edit User Phrases…" = "Edit User Phrases…";
"Reload User Phrases" = "Reload User Phrases";
"Unable to create the user phrase file." = "Unable to create the user phrase file.";

View File

@ -92,13 +92,13 @@
<key>InputMethodConnectionName</key>
<string>org_atelierInmu_inputmethod_vChewing_Connection</string>
<key>InputMethodServerControllerClass</key>
<string>ctlInputMethod</string>
<string>SessionCtl</string>
<key>InputMethodServerDelegateClass</key>
<string>ctlInputMethod</string>
<string>SessionCtl</string>
<key>InputMethodServerPreferencesWindowControllerClass</key>
<string>ctlPrefWindow</string>
<key>InputMethodSessionController</key>
<string>ctlInputMethod</string>
<string>SessionCtl</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSHasLocalizedDisplayName</key>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,74 @@
{
"images" : [
{
"filename" : "icon_1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"filename" : "icon_16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "icon_32.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "icon_32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "icon_64.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "icon_128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "icon_256.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "icon_256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "icon_512.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "icon_512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "icon_1024.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 KiB

View File

@ -1,31 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,0.176229,0.510845)">
<g id="v" transform="matrix(-0.0111111,-1.36072e-18,1.36072e-18,-0.0111111,13.8235,12.9891)">
<g id="Shadow" transform="matrix(-1.02102,-1.25039e-16,1.28682e-16,-1.05077,1169.98,1160.72)">
<path d="M1322.21,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1318.78L1322.21,1318.78L1322.21,34Z" style="fill-opacity:0.63;"/>
</g>
<g transform="matrix(-1.01166,-1.23893e-16,1.27502e-16,-1.04113,1259.98,1250.4)">
<g id="Outline">
<path d="M1334.45,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1330.67L1334.45,1330.67L1334.45,34Z" style="fill:rgb(11,46,99);"/>
</g>
</g>
<g id="Core" transform="matrix(-0.861782,-1.05538e-16,1.08613e-16,-0.886889,1169.98,1155.15)">
<path d="M1357.66,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1353.23L1357.66,1353.23L1357.66,34Z" style="fill:url(#_Radial1);"/>
</g>
</g>
<g id="TextElement" transform="matrix(0.0115939,0,0,0.0115939,0.253417,-0.559324)">
<g id="TextShadow" transform="matrix(76.3556,0,0,67.9081,-21039.4,-60964.1)">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-opacity:0.8;fill-rule:nonzero;"/>
</g>
<g id="Text" transform="matrix(64.7661,0,0,60.0776,-17811.9,-53913.5)">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill:rgb(16,42,103);fill-rule:nonzero;"/>
<g id="CHS">
<path d="M16,3.774C16,1.691 14.309,0 12.226,0L3.774,0C1.691,0 0,1.691 0,3.774L0,12.226C0,14.309 1.691,16 3.774,16L12.226,16C14.309,16 16,14.309 16,12.226L16,3.774Z" style="fill:white;"/>
<path d="M16,8.465L6.413,8.465L5,16L12.226,16C14.309,16 16,14.309 16,12.226L16,8.465Z" style="fill:rgb(64,134,191);"/>
<path d="M16,3.774C16,1.691 14.309,0 12.226,0L8,0L6.413,8.465L16,8.465L16,3.774Z" style="fill:rgb(83,191,64);"/>
<path d="M0,8.465L6.413,8.465L8,0L3.774,0C1.691,0 0,1.691 0,3.774L0,8.465Z" style="fill:rgb(255,200,0);"/>
<path d="M5,16L6.413,8.465L0,8.465L0,12.226C0,14.309 1.691,16 3.774,16L5,16Z" style="fill:rgb(255,81,0);"/>
</g>
<g transform="matrix(0.750892,0,0,0.696534,-206.162,-625.152)">
<g id="TextElement">
<g id="Text">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-rule:nonzero;"/>
<path d="M284.778,904.241C284.724,904.294 284.67,904.346 284.617,904.396C284.276,904.716 283.97,904.996 283.728,905.099C282.618,905.49 282.228,905.851 281.992,906.261C281.825,906.553 281.713,906.932 281.654,907.566C281.654,907.566 281.654,907.566 281.654,907.567C281.556,908.615 281.894,909.276 282.311,909.689C282.896,910.267 283.87,910.448 284.86,910.038C284.869,910.035 284.878,910.031 284.886,910.027C285.757,909.644 287.442,909.454 288.588,909.474C287.986,911.198 287.016,912.905 286.117,914.07L286.074,914.124L286.059,914.116C285.548,913.847 284.584,913.265 284.059,913.039C283.4,912.733 282.843,912.726 282.507,912.818C282.043,912.945 281.729,913.235 281.532,913.608C281.373,913.91 281.272,914.304 281.364,914.809C281.428,915.161 281.649,915.72 282.216,916.41C282.221,916.415 282.225,916.42 282.229,916.426C282.773,917.069 283.92,918.172 284.316,918.766C284.662,919.286 284.931,919.641 285.162,919.857C285.543,920.213 285.918,920.356 286.296,920.381C286.638,920.404 287.015,920.329 287.445,920.055C287.718,919.881 288.063,919.577 288.527,919.122C291.374,916.347 292.893,911.795 293.545,910.525C294.21,909.912 294.469,909.418 294.535,908.97C294.599,908.546 294.551,908.044 294.168,907.388C294.167,907.385 294.166,907.383 294.164,907.381C293.743,906.668 292.496,905.798 291.905,905.404C291.562,905.166 291.169,904.89 290.628,904.796C290.799,904.665 290.946,904.57 291.058,904.522C291.066,904.519 291.075,904.515 291.084,904.511C291.842,904.17 292.303,903.842 292.532,903.581C292.868,903.197 292.985,902.795 292.996,902.416C293.008,901.978 292.881,901.462 292.375,900.978C291.787,900.388 291.376,899.813 290.872,899.44C290.291,898.984 289.768,898.886 289.113,898.995C288.786,899.049 288.391,899.194 287.839,899.354C287.054,899.572 281.545,900.25 280.629,900.081C280.627,900.08 280.624,900.08 280.622,900.079C279.567,899.892 278.866,899.878 278.491,899.959C277.855,900.096 277.527,900.466 277.349,900.813C277.141,901.216 277.043,901.752 277.342,902.409C277.502,902.763 277.932,903.318 278.675,904.011C278.681,904.017 278.687,904.023 278.694,904.028C279.185,904.47 279.55,904.697 279.903,904.816C280.419,904.992 280.955,904.968 281.987,904.68C281.988,904.679 281.989,904.679 281.991,904.679C282.653,904.492 283.705,904.342 284.778,904.241ZM279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill:white;"/>
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-rule:nonzero;"/>
<path d="M287.346,902.94C286.511,904.121 284.91,905.864 284.062,906.19C283.738,906.304 283.507,906.389 283.338,906.475C283.119,906.588 282.988,906.709 282.898,906.865C282.795,907.046 282.751,907.288 282.714,907.681C282.714,907.681 282.714,907.681 282.714,907.681C282.661,908.249 282.805,908.619 283.031,908.842C283.362,909.169 283.919,909.198 284.478,908.966C284.48,908.965 284.482,908.965 284.484,908.964C285.747,908.408 288.527,908.207 289.589,908.409C289.59,908.409 289.591,908.409 289.593,908.409C289.689,908.426 289.768,908.447 289.831,908.474C289.876,908.494 289.911,908.511 289.927,908.544C289.941,908.575 289.939,908.612 289.936,908.655C289.93,908.74 289.907,908.838 289.874,908.951C289.874,908.953 289.874,908.954 289.874,908.955C289.286,911.101 288.059,913.349 286.935,914.806C286.762,915.028 286.63,915.194 286.515,915.309C286.438,915.386 286.378,915.438 286.311,915.453C286.247,915.468 286.183,915.446 286.1,915.412C285.967,915.358 285.807,915.268 285.598,915.151C285.596,915.15 285.594,915.149 285.592,915.148C285.094,914.886 284.153,914.312 283.653,914.101C283.338,913.953 283.072,913.896 282.886,913.911C282.675,913.929 282.535,914.031 282.458,914.175C282.392,914.301 282.367,914.483 282.443,914.721C282.515,914.947 282.693,915.258 283.014,915.648C283.015,915.649 283.015,915.65 283.016,915.652C283.583,916.321 284.769,917.478 285.181,918.096C285.462,918.518 285.672,918.813 285.859,918.989C286.03,919.148 286.193,919.224 286.362,919.235C286.524,919.246 286.699,919.196 286.902,919.067C287.133,918.919 287.419,918.655 287.812,918.271C289.971,916.167 291.321,912.995 292.106,911.125C292.302,910.658 292.462,910.274 292.59,910.014C292.654,909.884 292.699,909.79 292.743,909.751C292.994,909.53 293.178,909.361 293.296,909.207C293.402,909.066 293.462,908.93 293.484,908.788C293.516,908.574 293.459,908.33 293.266,907.999C293.266,907.999 293.266,907.998 293.266,907.998C292.911,907.398 291.83,906.703 291.337,906.375C290.952,906.108 290.475,905.736 289.588,906.03C289.228,906.138 288.939,906.122 288.569,906.107C288.312,906.096 288.018,906.085 287.647,906.104C288.707,905 290.107,903.691 290.668,903.453C290.67,903.453 290.672,903.452 290.674,903.451C291.118,903.251 291.432,903.079 291.623,902.921C291.84,902.741 291.926,902.554 291.931,902.381C291.935,902.209 291.861,902.02 291.661,901.83C291.106,901.275 290.732,900.723 290.257,900.377C289.933,900.12 289.641,900.069 289.276,900.13C288.976,900.18 288.617,900.318 288.111,900.464C287.288,900.695 281.423,901.392 280.45,901.213C280.449,901.213 280.449,901.213 280.448,901.213C279.582,901.059 279.009,901.018 278.7,901.085C278.473,901.134 278.344,901.246 278.281,901.37C278.211,901.505 278.198,901.684 278.299,901.904C278.425,902.182 278.787,902.597 279.373,903.143C279.374,903.144 279.375,903.145 279.376,903.146C279.724,903.459 279.974,903.636 280.223,903.721C280.595,903.848 280.977,903.775 281.72,903.568C281.72,903.568 281.72,903.568 281.721,903.568C282.903,903.234 285.268,903.004 286.913,902.953L287.346,902.94ZM279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z"/>
</g>
</g>
</g>
<defs>
<radialGradient id="_Radial1" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1087.57,-3794.91,3905.47,-1056.78,1725.88,3633.33)"><stop offset="0" style="stop-color:rgb(218,240,255);stop-opacity:1"/><stop offset="0.28" style="stop-color:rgb(200,225,246);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(193,219,243);stop-opacity:1"/><stop offset="0.73" style="stop-color:rgb(127,167,220);stop-opacity:1"/><stop offset="0.87" style="stop-color:rgb(14,87,170);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(9,53,104);stop-opacity:1"/></radialGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="CHT">
<path d="M16,3.774C16,1.691 14.309,0 12.226,0L3.774,0C1.691,0 0,1.691 0,3.774L0,12.226C0,14.309 1.691,16 3.774,16L12.226,16C14.309,16 16,14.309 16,12.226L16,3.774Z" style="fill:white;"/>
<path d="M16,8.465L6.413,8.465L5,16L12.226,16C14.309,16 16,14.309 16,12.226L16,8.465Z" style="fill:rgb(255,81,0);"/>
<path d="M16,3.774C16,1.691 14.309,0 12.226,0L8,0L6.413,8.465L16,8.465L16,3.774Z" style="fill:rgb(255,200,0);"/>
<path d="M0,8.465L6.413,8.465L8,0L3.774,0C1.691,0 0,1.691 0,3.774L0,8.465Z" style="fill:rgb(83,191,64);"/>
<path d="M5,16L6.413,8.465L0,8.465L0,12.226C0,14.309 1.691,16 3.774,16L5,16Z" style="fill:rgb(64,134,191);"/>
</g>
<g transform="matrix(0.750892,0,0,0.696534,-206.162,-625.152)">
<g id="TextElement">
<g id="Text">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-rule:nonzero;"/>
<path d="M284.778,904.241C284.724,904.294 284.67,904.346 284.617,904.396C284.276,904.716 283.97,904.996 283.728,905.099C282.618,905.49 282.228,905.851 281.992,906.261C281.825,906.553 281.713,906.932 281.654,907.566C281.654,907.566 281.654,907.566 281.654,907.567C281.556,908.615 281.894,909.276 282.311,909.689C282.896,910.267 283.87,910.448 284.86,910.038C284.869,910.035 284.878,910.031 284.886,910.027C285.757,909.644 287.442,909.454 288.588,909.474C287.986,911.198 287.016,912.905 286.117,914.07L286.074,914.124L286.059,914.116C285.548,913.847 284.584,913.265 284.059,913.039C283.4,912.733 282.843,912.726 282.507,912.818C282.043,912.945 281.729,913.235 281.532,913.608C281.373,913.91 281.272,914.304 281.364,914.809C281.428,915.161 281.649,915.72 282.216,916.41C282.221,916.415 282.225,916.42 282.229,916.426C282.773,917.069 283.92,918.172 284.316,918.766C284.662,919.286 284.931,919.641 285.162,919.857C285.543,920.213 285.918,920.356 286.296,920.381C286.638,920.404 287.015,920.329 287.445,920.055C287.718,919.881 288.063,919.577 288.527,919.122C291.374,916.347 292.893,911.795 293.545,910.525C294.21,909.912 294.469,909.418 294.535,908.97C294.599,908.546 294.551,908.044 294.168,907.388C294.167,907.385 294.166,907.383 294.164,907.381C293.743,906.668 292.496,905.798 291.905,905.404C291.562,905.166 291.169,904.89 290.628,904.796C290.799,904.665 290.946,904.57 291.058,904.522C291.066,904.519 291.075,904.515 291.084,904.511C291.842,904.17 292.303,903.842 292.532,903.581C292.868,903.197 292.985,902.795 292.996,902.416C293.008,901.978 292.881,901.462 292.375,900.978C291.787,900.388 291.376,899.813 290.872,899.44C290.291,898.984 289.768,898.886 289.113,898.995C288.786,899.049 288.391,899.194 287.839,899.354C287.054,899.572 281.545,900.25 280.629,900.081C280.627,900.08 280.624,900.08 280.622,900.079C279.567,899.892 278.866,899.878 278.491,899.959C277.855,900.096 277.527,900.466 277.349,900.813C277.141,901.216 277.043,901.752 277.342,902.409C277.502,902.763 277.932,903.318 278.675,904.011C278.681,904.017 278.687,904.023 278.694,904.028C279.185,904.47 279.55,904.697 279.903,904.816C280.419,904.992 280.955,904.968 281.987,904.68C281.988,904.679 281.989,904.679 281.991,904.679C282.653,904.492 283.705,904.342 284.778,904.241ZM279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill:white;"/>
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-rule:nonzero;"/>
<path d="M287.346,902.94C286.511,904.121 284.91,905.864 284.062,906.19C283.738,906.304 283.507,906.389 283.338,906.475C283.119,906.588 282.988,906.709 282.898,906.865C282.795,907.046 282.751,907.288 282.714,907.681C282.714,907.681 282.714,907.681 282.714,907.681C282.661,908.249 282.805,908.619 283.031,908.842C283.362,909.169 283.919,909.198 284.478,908.966C284.48,908.965 284.482,908.965 284.484,908.964C285.747,908.408 288.527,908.207 289.589,908.409C289.59,908.409 289.591,908.409 289.593,908.409C289.689,908.426 289.768,908.447 289.831,908.474C289.876,908.494 289.911,908.511 289.927,908.544C289.941,908.575 289.939,908.612 289.936,908.655C289.93,908.74 289.907,908.838 289.874,908.951C289.874,908.953 289.874,908.954 289.874,908.955C289.286,911.101 288.059,913.349 286.935,914.806C286.762,915.028 286.63,915.194 286.515,915.309C286.438,915.386 286.378,915.438 286.311,915.453C286.247,915.468 286.183,915.446 286.1,915.412C285.967,915.358 285.807,915.268 285.598,915.151C285.596,915.15 285.594,915.149 285.592,915.148C285.094,914.886 284.153,914.312 283.653,914.101C283.338,913.953 283.072,913.896 282.886,913.911C282.675,913.929 282.535,914.031 282.458,914.175C282.392,914.301 282.367,914.483 282.443,914.721C282.515,914.947 282.693,915.258 283.014,915.648C283.015,915.649 283.015,915.65 283.016,915.652C283.583,916.321 284.769,917.478 285.181,918.096C285.462,918.518 285.672,918.813 285.859,918.989C286.03,919.148 286.193,919.224 286.362,919.235C286.524,919.246 286.699,919.196 286.902,919.067C287.133,918.919 287.419,918.655 287.812,918.271C289.971,916.167 291.321,912.995 292.106,911.125C292.302,910.658 292.462,910.274 292.59,910.014C292.654,909.884 292.699,909.79 292.743,909.751C292.994,909.53 293.178,909.361 293.296,909.207C293.402,909.066 293.462,908.93 293.484,908.788C293.516,908.574 293.459,908.33 293.266,907.999C293.266,907.999 293.266,907.998 293.266,907.998C292.911,907.398 291.83,906.703 291.337,906.375C290.952,906.108 290.475,905.736 289.588,906.03C289.228,906.138 288.939,906.122 288.569,906.107C288.312,906.096 288.018,906.085 287.647,906.104C288.707,905 290.107,903.691 290.668,903.453C290.67,903.453 290.672,903.452 290.674,903.451C291.118,903.251 291.432,903.079 291.623,902.921C291.84,902.741 291.926,902.554 291.931,902.381C291.935,902.209 291.861,902.02 291.661,901.83C291.106,901.275 290.732,900.723 290.257,900.377C289.933,900.12 289.641,900.069 289.276,900.13C288.976,900.18 288.617,900.318 288.111,900.464C287.288,900.695 281.423,901.392 280.45,901.213C280.449,901.213 280.449,901.213 280.448,901.213C279.582,901.059 279.009,901.018 278.7,901.085C278.473,901.134 278.344,901.246 278.281,901.37C278.211,901.505 278.198,901.684 278.299,901.904C278.425,902.182 278.787,902.597 279.373,903.143C279.374,903.144 279.375,903.145 279.376,903.146C279.724,903.459 279.974,903.636 280.223,903.721C280.595,903.848 280.977,903.775 281.72,903.568C281.72,903.568 281.72,903.568 281.721,903.568C282.903,903.234 285.268,903.004 286.913,902.953L287.346,902.94ZM279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Pixelmator Pro 3.0 -->
<svg width="1024" height="1024" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="NewIMELogo-CHT-">
<g id="CHT">
<path id="-" fill="#ffffff" fill-rule="evenodd" stroke="none" d="M -122 1178.28125 L 1254 1178.28125 L 1254 -191 L -122 -191 Z"/>
<path id="path1" fill="#ff8346" fill-rule="evenodd" stroke="none" d="M 1024 536.989563 L 429 537 L 338 1024 L 1024 1024 Z"/>
<path id="path2" fill="#f9ce29" fill-rule="evenodd" stroke="none" d="M 1024 0 L 530 0 L 429 537 L 1024 537 Z"/>
<path id="path3" fill="#4ec03b" fill-rule="evenodd" stroke="none" d="M 0 537 L 429.517975 536.989624 L 530 0 C 530 0 -3e-06 0 -3e-06 0 Z"/>
<path id="path4" fill="#3d7db3" fill-rule="evenodd" stroke="none" d="M 338 1024 L 429.518005 536.989563 L 0 536.989563 L 0 1024 Z"/>
</g>
</g>
<g id="NewIMELogo-CHT--">
<g id="g1">
<g id="TextElement">
<g id="Text">
<path id="path5" fill="#002833" stroke="none" d="M 290.875397 291.867126 C 321.331543 317.292175 329.453491 316.350464 373.107788 305.049438 C 419.806641 292.80896 513.205505 284.333191 578.178711 282.449646 C 611.680603 280.566162 614.726379 284.333191 604.573914 297.515442 C 571.072021 341.77771 505.083557 407.697876 470.566437 419.938477 C 429.959076 433.122925 427.928589 435.00647 424.882843 465.142395 C 420.821869 505.635437 450.262756 512.227661 479.703644 500.926636 C 530.464661 480.208191 642.13678 472.676392 684.775818 480.208191 C 708.125244 483.97522 710.155701 493.3927 704.06427 513.169434 C 680.714844 592.271973 631.984314 675.143677 587.315918 728.821167 C 558.890259 762.724121 556.859802 761.78241 522.342712 743.88916 C 503.05307 734.47168 466.506683 713.753174 447.217041 706.221436 C 412.699921 691.153381 396.457214 703.396118 434.02005 745.772705 C 456.354248 770.25592 503.05307 812.634644 519.296997 835.234375 C 553.814087 883.263672 557.875061 884.205383 606.60437 839.943176 C 725.38324 732.588196 780.2052 547.07019 799.493652 531.062622 C 824.873535 510.344177 831.980225 503.751892 817.766846 481.149963 C 804.569885 460.433655 763.961304 436.889893 745.688049 425.588989 C 732.489929 417.11322 716.247192 404.87262 685.791016 414.290161 C 655.334961 422.763733 637.060547 412.406677 579.194031 419.938477 C 621.833069 376.620178 694.927063 311.641663 721.323364 301.282471 C 761.930786 284.333191 773.098511 273.973877 756.854614 259.847717 C 735.535645 240.070984 721.323364 220.296448 703.049011 208.053711 C 682.7453 192.985718 666.501404 202.403198 627.92334 212.76239 C 595.436707 221.238159 362.955353 246.663208 324.377258 240.070984 C 233.008865 225.005127 229.963135 239.129211 290.875397 291.867126 Z"/>
<path id="path6" fill="#ffffff" fill-rule="evenodd" stroke="none" d="M 495.127747 339.496216 C 493.018585 341.4151 490.910645 343.298584 488.840851 345.109131 C 475.525909 356.699707 463.577728 366.840088 454.128326 370.571716 C 410.787384 384.733337 395.558746 397.809509 386.344086 412.658691 C 379.823639 423.234558 375.45047 436.962891 373.145905 459.925232 C 373.145905 459.925232 373.145905 459.925232 373.145905 459.96283 C 369.319702 497.920166 382.517853 521.861816 398.799896 536.821472 C 421.641693 557.756592 459.672852 564.311279 498.328369 549.462158 C 498.679901 549.351563 499.031403 549.207886 499.343628 549.062012 C 533.353149 535.189941 599.146179 528.308105 643.894409 529.033203 C 620.387695 591.476135 582.512573 653.304382 547.4104 695.499634 L 545.731445 697.456055 L 545.145203 697.166504 C 525.192993 687.421753 487.552734 666.342957 467.052429 658.15686 C 441.320984 647.07251 419.571869 646.820435 406.452362 650.151917 C 388.335266 654.752319 376.07486 665.255371 368.383087 678.764771 C 362.173645 689.703247 358.230652 703.975342 361.823334 722.266479 C 364.322113 735.015503 372.9505 755.260864 395.090424 780.252686 C 395.285858 780.433899 395.441956 780.615173 395.598083 780.834045 C 416.839539 804.121338 461.625854 844.072754 477.088104 865.587036 C 490.59726 884.422058 501.101227 897.279297 510.120453 905.102966 C 524.99762 917.997803 539.639954 923.17749 554.39917 924.081604 C 567.753479 924.915039 582.474487 922.19812 599.26416 912.274353 C 609.923035 905.971741 623.394104 894.962524 641.51239 878.481934 C 752.676819 777.971191 811.98877 613.098755 837.447327 567.101135 C 863.412292 544.897095 873.525391 527.006104 876.102844 510.777466 C 878.601624 495.422119 876.727234 477.239258 861.772644 453.478882 C 861.733337 453.370544 861.694031 453.297546 861.616577 453.224609 C 845.178406 427.401733 796.487244 395.888489 773.410645 381.61853 C 760.01825 372.999084 744.672852 363.00238 723.548157 359.597961 C 730.225891 354.851624 735.96582 351.411804 740.338989 349.671997 C 740.651184 349.56366 741.002686 349.419983 741.354187 349.274048 C 770.951172 336.923035 788.951538 325.042847 797.893311 315.589966 C 811.012817 301.682556 815.580261 287.12085 816.010437 273.394714 C 816.478699 257.530884 811.520447 238.8396 791.762512 221.311096 C 768.802795 199.940491 752.755432 179.113708 733.076172 165.604248 C 710.389282 149.088257 689.968811 145.537903 664.393494 149.486145 C 651.625488 151.442627 636.201355 156.692993 614.647705 162.48938 C 583.996155 170.385925 368.890717 194.942139 333.123627 188.820801 C 333.046143 188.7854 332.928192 188.7854 332.850739 188.747864 C 291.655884 181.976501 264.284821 181.468079 249.64241 184.401611 C 224.809448 189.364624 212.002136 202.765747 205.051514 215.333435 C 196.929565 229.930542 193.103333 249.344727 204.778641 273.140503 C 211.026199 285.962463 227.815857 306.064148 256.826599 331.164185 C 257.06134 331.383057 257.296082 331.599731 257.568939 331.780945 C 276.740631 347.788513 290.992157 356.012268 304.776611 360.320801 C 324.924194 366.696472 345.852295 365.827637 386.148651 355.395447 C 386.187988 355.360107 386.227325 355.360107 386.304779 355.360107 C 412.154175 348.586548 453.229858 343.15271 495.127747 339.496216 Z M 290.875397 291.867126 C 321.331543 317.292175 329.453491 316.350464 373.107788 305.049438 C 419.806641 292.80896 513.205505 284.333191 578.178711 282.449646 C 611.680603 280.566162 614.726379 284.333191 604.573914 297.515442 C 571.072021 341.77771 505.083557 407.697876 470.566437 419.938477 C 429.959076 433.122925 427.928589 435.00647 424.882843 465.142395 C 420.821869 505.635437 450.262756 512.227661 479.703644 500.926636 C 530.464661 480.208191 642.13678 472.676392 684.775818 480.208191 C 708.125244 483.97522 710.155701 493.3927 704.06427 513.169434 C 680.714844 592.271973 631.984314 675.143677 587.315918 728.821167 C 558.890259 762.724121 556.859802 761.78241 522.342712 743.88916 C 503.05307 734.47168 466.506683 713.753174 447.217041 706.221436 C 412.699921 691.153381 396.457214 703.396118 434.02005 745.772705 C 456.354248 770.25592 503.05307 812.634644 519.296997 835.234375 C 553.814087 883.263672 557.875061 884.205383 606.60437 839.943176 C 725.38324 732.588196 780.2052 547.07019 799.493652 531.062622 C 824.873535 510.344177 831.980225 503.751892 817.766846 481.149963 C 804.569885 460.433655 763.961304 436.889893 745.688049 425.588989 C 732.489929 417.11322 716.247192 404.87262 685.791016 414.290161 C 655.334961 422.763733 637.060547 412.406677 579.194031 419.938477 C 621.833069 376.620178 694.927063 311.641663 721.323364 301.282471 C 761.930786 284.333191 773.098511 273.973877 756.854614 259.847717 C 735.535645 240.070984 721.323364 220.296448 703.049011 208.053711 C 682.7453 192.985718 666.501404 202.403198 627.92334 212.76239 C 595.436707 221.238159 362.955353 246.663208 324.377258 240.070984 C 233.008865 225.005127 229.963135 239.129211 290.875397 291.867126 Z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Pixelmator Pro 3.0 -->
<svg width="1024" height="1024" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="NewIMELogo-CHT-">
<g id="CHT">
<path id="-" fill="#ffffff" fill-rule="evenodd" stroke="none" d="M 0 1019 L 1024 1019 L 1024 0 L 0 0 Z"/>
<path id="path1" fill="#ff8346" fill-rule="evenodd" stroke="none" d="M 1024 541.759705 L 410.431976 541.759705 L 320 1024 L 1024 1024 Z"/>
<path id="path2" fill="#f9ce29" fill-rule="evenodd" stroke="none" d="M 1024 0 L 508.359161 0 L 406.06897 541.759705 L 1024 541.759705 Z"/>
<path id="path3" fill="#4ec03b" fill-rule="evenodd" stroke="none" d="M 0 541.759705 L 410.431976 541.759705 L 512 0 C 512 0 0 0 0 0 Z"/>
<path id="path4" fill="#3d7db3" fill-rule="evenodd" stroke="none" d="M 320 1024 L 410.431976 541.759705 L -0 541.759705 L -0 1024 Z"/>
</g>
<g id="g1">
<g id="TextElement">
<g id="Text">
<path id="path5" fill="#002833" stroke="none" d="M 239.846634 241.067261 C 277.331116 272.359619 287.327362 271.200562 341.055725 257.291626 C 398.53125 242.226379 513.483704 231.794678 593.450745 229.476501 C 634.683838 227.158386 638.432434 231.794678 625.937134 248.018982 C 584.704041 302.495605 503.487457 383.628174 461.004852 398.693481 C 411.02655 414.920532 408.527496 417.238708 404.7789 454.329102 C 399.780762 504.166687 436.015717 512.280212 472.250641 498.371277 C 534.725769 472.871643 672.168335 463.601746 724.647156 472.871643 C 753.384888 477.507935 755.883972 489.098694 748.38678 513.43927 C 719.649048 610.796265 659.672974 712.792236 604.696533 778.856812 C 569.711121 820.583557 567.212097 819.4245 524.729492 797.402039 C 500.988403 785.811279 456.008209 760.311646 432.26712 751.041748 C 389.784515 732.49646 369.793488 747.564453 416.024689 799.720215 C 443.512909 829.853455 500.988403 882.011841 520.980896 909.826965 C 563.463501 968.93988 568.461609 970.098938 628.436157 915.622375 C 774.625488 783.493164 842.098694 555.16333 865.838318 535.461731 C 897.075134 509.962036 905.821838 501.848511 888.32843 474.030701 C 872.085999 448.533752 822.106201 419.556824 799.616089 405.647949 C 783.372192 395.216248 763.381165 380.15094 725.896667 391.741699 C 688.412231 402.170715 665.920654 389.423584 594.700317 398.693481 C 647.179138 345.378662 737.140991 265.405151 769.628784 252.655334 C 819.607117 231.794678 833.35199 219.0448 813.359497 201.658691 C 787.120789 177.318115 769.628784 152.980225 747.137268 137.912231 C 722.148071 119.367004 702.155579 130.957764 654.674866 143.707581 C 614.691345 154.139282 328.560425 185.431641 281.079712 177.318115 C 168.626297 158.775574 164.877701 176.158997 239.846634 241.067261 Z"/>
<path id="path6" fill="#ffffff" fill-rule="evenodd" stroke="none" d="M 491.234131 299.687683 C 488.638275 302.049377 486.043884 304.367493 483.496429 306.595886 C 467.108795 320.861206 452.403351 333.341675 440.773315 337.934448 C 387.430634 355.364136 368.687683 371.457886 357.346558 389.733765 C 349.321411 402.750244 343.939056 419.646606 341.102661 447.907959 C 341.102661 447.907959 341.102661 447.907959 341.102661 447.954224 C 336.393463 494.670959 352.63736 524.137573 372.676788 542.5495 C 400.789764 568.315796 447.597351 576.383057 495.17337 558.107239 C 495.606018 557.971191 496.038666 557.794312 496.422913 557.614746 C 538.280762 540.541504 619.256836 532.071533 674.331543 532.963989 C 645.400208 609.816772 598.784729 685.913086 555.582031 737.845703 L 553.515625 740.253601 L 552.794067 739.897217 C 528.237549 727.903687 481.911041 701.960571 456.679901 691.885315 C 425.010437 678.243042 398.24231 677.932861 382.095215 682.033142 C 359.797241 687.69519 344.70752 700.621948 335.240723 717.248901 C 327.598328 730.71167 322.745422 748.277344 327.167175 770.789551 C 330.242584 786.480591 340.862152 811.39801 368.111298 842.157104 C 368.351837 842.380188 368.543945 842.603271 368.736084 842.872681 C 394.879425 871.533936 450.001068 920.704895 469.031494 947.184082 C 485.658173 970.365601 498.586121 986.189941 509.686707 995.819031 C 527.99707 1011.689636 546.018433 1018.064575 564.183594 1019.177368 C 580.619629 1020.203125 598.737793 1016.859253 619.402039 1004.645386 C 632.52063 996.888306 649.100403 983.338501 671.399841 963.054688 C 808.21759 839.349182 881.216919 636.429199 912.550537 579.816772 C 944.507446 552.488708 956.954346 530.468994 960.126587 510.495361 C 963.202026 491.596436 960.895081 469.217529 942.489441 439.973999 C 942.44104 439.840637 942.392639 439.750854 942.297302 439.661072 C 922.065735 407.879028 862.138123 369.093506 833.736206 351.530518 C 817.253235 340.921936 798.366577 328.618347 772.366943 324.428223 C 780.585693 318.586609 787.650208 314.352966 793.032593 312.21167 C 793.416809 312.078369 793.849487 311.901489 794.282104 311.721924 C 830.709167 296.52063 852.863403 281.898865 863.868713 270.264587 C 880.015808 253.147766 885.637207 235.225647 886.166687 218.33197 C 886.743042 198.807251 880.640564 175.802612 856.32312 154.229065 C 828.064941 127.926758 808.314392 102.293762 784.09375 85.666748 C 756.171387 65.339355 731.038513 60.969727 699.561218 65.829102 C 683.846741 68.237061 664.86322 74.699036 638.335632 81.833069 C 600.610657 91.55188 335.865479 121.774963 291.844452 114.240967 C 291.749115 114.197388 291.603912 114.197388 291.508606 114.151184 C 240.807251 105.817261 207.119766 105.191467 189.098358 108.802002 C 158.534714 114.910278 142.771851 131.403992 134.217255 146.871948 C 124.221001 164.837585 119.511795 188.731995 133.881409 218.019104 C 141.570709 233.799927 162.234909 258.540466 197.940414 289.432861 C 198.229324 289.702209 198.51825 289.968872 198.854095 290.191956 C 222.449997 309.893555 239.990356 320.015076 256.955841 325.317932 C 281.752869 333.164856 307.510529 332.095581 357.106049 319.25592 C 357.154449 319.212402 357.20285 319.212402 357.298187 319.212402 C 389.112823 310.875732 439.667511 304.187927 491.234131 299.687683 Z M 239.846634 241.067261 C 277.331116 272.359619 287.327362 271.200562 341.055725 257.291626 C 398.53125 242.226379 513.483704 231.794678 593.450745 229.476501 C 634.683838 227.158386 638.432434 231.794678 625.937134 248.018982 C 584.704041 302.495605 503.487457 383.628174 461.004852 398.693481 C 411.02655 414.920532 408.527496 417.238708 404.7789 454.329102 C 399.780762 504.166687 436.015717 512.280212 472.250641 498.371277 C 534.725769 472.871643 672.168335 463.601746 724.647156 472.871643 C 753.384888 477.507935 755.883972 489.098694 748.38678 513.43927 C 719.649048 610.796265 659.672974 712.792236 604.696533 778.856812 C 569.711121 820.583557 567.212097 819.4245 524.729492 797.402039 C 500.988403 785.811279 456.008209 760.311646 432.26712 751.041748 C 389.784515 732.49646 369.793488 747.564453 416.024689 799.720215 C 443.512909 829.853455 500.988403 882.011841 520.980896 909.826965 C 563.463501 968.93988 568.461609 970.098938 628.436157 915.622375 C 774.625488 783.493164 842.098694 555.16333 865.838318 535.461731 C 897.075134 509.962036 905.821838 501.848511 888.32843 474.030701 C 872.085999 448.533752 822.106201 419.556824 799.616089 405.647949 C 783.372192 395.216248 763.381165 380.15094 725.896667 391.741699 C 688.412231 402.170715 665.920654 389.423584 594.700317 398.693481 C 647.179138 345.378662 737.140991 265.405151 769.628784 252.655334 C 819.607117 231.794678 833.35199 219.0448 813.359497 201.658691 C 787.120789 177.318115 769.628784 152.980225 747.137268 137.912231 C 722.148071 119.367004 702.155579 130.957764 654.674866 143.707581 C 614.691345 154.139282 328.560425 185.431641 281.079712 177.318115 C 168.626297 158.775574 164.877701 176.158997 239.846634 241.067261 Z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,0.176229,0.510845)">
<g id="v" transform="matrix(-0.0111111,-1.36072e-18,1.36072e-18,-0.0111111,13.8235,12.9891)">
<g id="Shadow" transform="matrix(-1.02102,-1.25039e-16,1.28682e-16,-1.05077,1169.98,1160.72)">
<path d="M1322.21,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1318.78L1322.21,1318.78L1322.21,34Z" style="fill-opacity:0.63;"/>
</g>
<g transform="matrix(-1.01166,-1.23893e-16,1.27502e-16,-1.04113,1259.98,1250.4)">
<g id="Outline">
<path d="M1334.45,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1330.67L1334.45,1330.67L1334.45,34Z" style="fill:rgb(11,46,99);"/>
</g>
</g>
<g id="Core" transform="matrix(-0.861782,-1.05538e-16,1.08613e-16,-0.886889,1169.98,1155.15)">
<path d="M1357.66,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1353.23L1357.66,1353.23L1357.66,34Z" style="fill:url(#_Radial1);"/>
<path d="M1409.88,1403.97L1409.88,-16.739L452.612,-16.739C173.989,-16.739 -52.217,203.063 -52.217,473.799C-52.217,473.799 -52.217,1403.97 -52.217,1403.97L1409.88,1403.97ZM1357.66,34L452.612,34C202.809,34 0,231.067 0,473.799L0,1353.23L1357.66,1353.23L1357.66,34Z" style="fill:white;"/>
</g>
</g>
<g id="TextElement" transform="matrix(0.0115939,0,0,0.0115939,0.253417,-0.559324)">
<g id="TextShadow" transform="matrix(76.3556,0,0,67.9081,-21039.4,-60964.1)">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill-opacity:0.8;fill-rule:nonzero;"/>
</g>
<g id="Text" transform="matrix(64.7661,0,0,60.0776,-17811.9,-53913.5)">
<path d="M279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill:rgb(16,42,103);fill-rule:nonzero;"/>
<path d="M284.778,904.241C284.724,904.294 284.67,904.346 284.617,904.396C284.276,904.716 283.97,904.996 283.728,905.099C282.618,905.49 282.228,905.851 281.992,906.261C281.825,906.553 281.713,906.932 281.654,907.566L281.654,907.567C281.556,908.615 281.894,909.276 282.311,909.689C282.896,910.267 283.87,910.448 284.86,910.038C284.869,910.035 284.878,910.031 284.886,910.027C285.757,909.644 287.442,909.454 288.588,909.474C287.986,911.198 287.016,912.905 286.117,914.07L286.074,914.124L286.059,914.116C285.548,913.847 284.584,913.265 284.059,913.039C283.4,912.733 282.843,912.726 282.507,912.818C282.043,912.945 281.729,913.235 281.532,913.608C281.373,913.91 281.272,914.304 281.364,914.809C281.428,915.161 281.649,915.72 282.216,916.41C282.221,916.415 282.225,916.42 282.229,916.426C282.773,917.069 283.92,918.172 284.316,918.766C284.662,919.286 284.931,919.641 285.162,919.857C285.543,920.213 285.918,920.356 286.296,920.381C286.638,920.404 287.015,920.329 287.445,920.055C287.718,919.881 288.063,919.577 288.527,919.122C291.374,916.347 292.893,911.795 293.545,910.525C294.21,909.912 294.469,909.418 294.535,908.97C294.599,908.546 294.551,908.044 294.168,907.388C294.167,907.385 294.166,907.383 294.164,907.381C293.743,906.668 292.496,905.798 291.905,905.404C291.562,905.166 291.169,904.89 290.628,904.796C290.799,904.665 290.946,904.57 291.058,904.522C291.066,904.519 291.075,904.515 291.084,904.511C291.842,904.17 292.303,903.842 292.532,903.581C292.868,903.197 292.985,902.795 292.996,902.416C293.008,901.978 292.881,901.462 292.375,900.978C291.787,900.388 291.376,899.813 290.872,899.44C290.291,898.984 289.768,898.886 289.113,898.995C288.786,899.049 288.391,899.194 287.839,899.354C287.054,899.572 281.545,900.25 280.629,900.081C280.627,900.08 280.624,900.08 280.622,900.079C279.567,899.892 278.866,899.878 278.491,899.959C277.855,900.096 277.527,900.466 277.349,900.813C277.141,901.216 277.043,901.752 277.342,902.409C277.502,902.763 277.932,903.318 278.675,904.011C278.681,904.017 278.687,904.023 278.694,904.028C279.185,904.47 279.55,904.697 279.903,904.816C280.419,904.992 280.955,904.968 281.987,904.68C281.988,904.679 281.989,904.679 281.991,904.679C282.653,904.492 283.705,904.342 284.778,904.241ZM279.547,902.926C280.327,903.628 280.535,903.602 281.653,903.29C282.849,902.952 285.241,902.718 286.905,902.666C287.763,902.614 287.841,902.718 287.581,903.082C286.723,904.304 285.033,906.124 284.149,906.462C283.109,906.826 283.057,906.878 282.979,907.71C282.875,908.828 283.629,909.01 284.383,908.698C285.683,908.126 288.543,907.918 289.635,908.126C290.233,908.23 290.285,908.49 290.129,909.036C289.531,911.22 288.283,913.508 287.139,914.99C286.411,915.926 286.359,915.9 285.475,915.406C284.981,915.146 284.045,914.574 283.551,914.366C282.667,913.95 282.251,914.288 283.213,915.458C283.785,916.134 284.981,917.304 285.397,917.928C286.281,919.254 286.385,919.28 287.633,918.058C290.675,915.094 292.079,909.972 292.573,909.53C293.223,908.958 293.405,908.776 293.041,908.152C292.703,907.58 291.663,906.93 291.195,906.618C290.857,906.384 290.441,906.046 289.661,906.306C288.881,906.54 288.413,906.254 286.931,906.462C288.023,905.266 289.895,903.472 290.571,903.186C291.611,902.718 291.897,902.432 291.481,902.042C290.935,901.496 290.571,900.95 290.103,900.612C289.583,900.196 289.167,900.456 288.179,900.742C287.347,900.976 281.393,901.678 280.405,901.496C278.065,901.08 277.987,901.47 279.547,902.926Z" style="fill:white;"/>
</g>
</g>
</g>
<defs>
<radialGradient id="_Radial1" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1087.57,-3794.91,3905.47,-1056.78,1725.88,3633.33)"><stop offset="0" style="stop-color:rgb(218,240,255);stop-opacity:1"/><stop offset="0.28" style="stop-color:rgb(200,225,246);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(193,219,243);stop-opacity:1"/><stop offset="0.73" style="stop-color:rgb(127,167,220);stop-opacity:1"/><stop offset="0.87" style="stop-color:rgb(14,87,170);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(9,53,104);stop-opacity:1"/></radialGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 8.5 KiB

Some files were not shown because too many files have changed in this diff Show More