Full Code of DevToys-app/DevToysMac for AI

main 38d416083872 cached
282 files
22.5 MB
260.8k tokens
1 requests
Download .txt
Showing preview only (960K chars total). Download the full file or copy to clipboard to get everything.
Repository: DevToys-app/DevToysMac
Branch: main
Commit: 38d416083872
Files: 282
Total size: 22.5 MB

Directory structure:
gitextract_01cekmvj/

├── .gitignore
├── CoreUtil/
│   ├── CoreUtil/
│   │   ├── Class/
│   │   │   ├── Action.swift
│   │   │   ├── Delta.swift
│   │   │   ├── NS+OnAwake.swift
│   │   │   ├── NSColorView.swift
│   │   │   ├── NSViewController+ChainObject.swift
│   │   │   ├── NSViewController+StateObject.swift
│   │   │   ├── Observable.swift
│   │   │   ├── PipeOperator.swift
│   │   │   ├── Query.swift
│   │   │   ├── Reachability+Publisher.swift
│   │   │   ├── Reachability.swift
│   │   │   ├── RestorableData.swift
│   │   │   ├── RestorableState.swift
│   │   │   ├── Terminal.swift
│   │   │   ├── ViewPlaceholder.swift
│   │   │   └── Zip3Sequence.swift
│   │   ├── CoreUtil.h
│   │   ├── ExceptionHanlder/
│   │   │   ├── ExceptionHandler.swift
│   │   │   ├── ExceptionHanlder.h
│   │   │   └── ExceptionHanlder.m
│   │   ├── Export.swift
│   │   ├── Extensions/
│   │   │   ├── Combine/
│   │   │   │   ├── Combine+ObjectBag.swift
│   │   │   │   ├── Combine+Peek.swift
│   │   │   │   ├── NSControl+Combine.swift
│   │   │   │   └── NSTextField+Combine.swift
│   │   │   ├── CoreGraphics/
│   │   │   │   ├── Ex+CGPoint.swift
│   │   │   │   ├── Ex+CGRect.swift
│   │   │   │   └── Ex+CGSize.swift
│   │   │   ├── Swift/
│   │   │   │   ├── Ex+Array.swift
│   │   │   │   ├── Ex+Clamp.swift
│   │   │   │   ├── Ex+Localize.swift
│   │   │   │   ├── Ex+Number.swift
│   │   │   │   └── Ex+OptionSet.swift
│   │   │   └── UI/
│   │   │       ├── Ex+CALayer.swift
│   │   │       ├── Ex+Image.swift
│   │   │       ├── Ex+NSColor.swift
│   │   │       ├── Ex+NSControl.swift
│   │   │       ├── Ex+NSEdgeInsets.swift
│   │   │       ├── Ex+NSEvent.swift
│   │   │       ├── Ex+NSMenuItem.swift
│   │   │       ├── Ex+NSPopover.swift
│   │   │       ├── Ex+NSTableView.swift
│   │   │       └── Ex+UI.swift
│   │   ├── HotKey/
│   │   │   ├── HotKey.swift
│   │   │   ├── Key.swift
│   │   │   └── NSEvent+HotKey.swift
│   │   └── Info.plist
│   └── CoreUtil.xcodeproj/
│       ├── project.pbxproj
│       └── project.xcworkspace/
│           ├── contents.xcworkspacedata
│           └── xcshareddata/
│               └── IDEWorkspaceChecks.plist
├── DevToys/
│   ├── DevToys/
│   │   ├── App/
│   │   │   ├── AppViewController.swift
│   │   │   └── AppWindowController.swift
│   │   ├── AppDelegate.swift
│   │   ├── Body/
│   │   │   ├── BodyViewController.swift
│   │   │   ├── Coder/
│   │   │   │   ├── Base64DecoderView+.swift
│   │   │   │   ├── HTMLDecoderView+.swift
│   │   │   │   ├── JWTDecoderView+.swift
│   │   │   │   └── URLDecoderView+.swift
│   │   │   ├── Convert/
│   │   │   │   ├── DateConverterView+.swift
│   │   │   │   ├── JSONYamlConverterView+.swift
│   │   │   │   └── NumberBaseConverterView+.swift
│   │   │   ├── Format/
│   │   │   │   ├── JSONFormatterView+.swift
│   │   │   │   ├── SQLFormatterView+.swift
│   │   │   │   └── XMLFormatterView+.swift
│   │   │   ├── Generator/
│   │   │   │   ├── ChecksumGeneratorView+.swift
│   │   │   │   ├── HashGeneratorView+.swift
│   │   │   │   ├── LoremIpsumGeneratorView+.swift
│   │   │   │   ├── QRCodeGeneratorView+.swift
│   │   │   │   └── UUIDGeneratorView+.swift
│   │   │   ├── Graphic/
│   │   │   │   ├── Icon Generator/
│   │   │   │   │   ├── Generators/
│   │   │   │   │   │   ├── AndroidIconGenerator.swift
│   │   │   │   │   │   ├── IOSIconGenerator.swift
│   │   │   │   │   │   ├── IcnsGenerator.swift
│   │   │   │   │   │   ├── IcoGenerator.swift
│   │   │   │   │   │   ├── IconFolderGenerator.swift
│   │   │   │   │   │   ├── IconGenerator+Model.swift
│   │   │   │   │   │   ├── IconsetGenerator.swift
│   │   │   │   │   │   ├── IosIconGenerator.swift
│   │   │   │   │   │   └── PngIconGenerator.swift
│   │   │   │   │   ├── Icon Templete/
│   │   │   │   │   │   ├── IconImageManager.swift
│   │   │   │   │   │   ├── IconSet.swift
│   │   │   │   │   │   ├── IconTemplete+.swift
│   │   │   │   │   │   └── IconTemplete.swift
│   │   │   │   │   └── IconGeneratorView+.swift
│   │   │   │   ├── Image Converter/
│   │   │   │   │   ├── Exporters/
│   │   │   │   │   │   ├── DefaultImageExporter.swift
│   │   │   │   │   │   ├── HeicImageExporter.swift
│   │   │   │   │   │   ├── WebpImageExporter.swift
│   │   │   │   │   │   └── cwebp
│   │   │   │   │   ├── ImageConverter.swift
│   │   │   │   │   └── ImageConverterView+.swift
│   │   │   │   ├── Image Optimizer/
│   │   │   │   │   ├── ImageOptimaizerView.swift
│   │   │   │   │   ├── ImageOptimizer.swift
│   │   │   │   │   ├── jpegoptim
│   │   │   │   │   └── optipng
│   │   │   │   ├── PDFGeneratorView+.swift
│   │   │   │   └── QRCodeReaderView+.swift
│   │   │   ├── HomeView+.swift
│   │   │   ├── Media/
│   │   │   │   ├── Audio Converter/
│   │   │   │   │   ├── AudioConverter.swift
│   │   │   │   │   ├── AudioConverterView+.swift
│   │   │   │   │   └── AudioFileScanner.swift
│   │   │   │   ├── Color Picker/
│   │   │   │   │   ├── Color.swift
│   │   │   │   │   ├── ColorPickerView+.swift
│   │   │   │   │   ├── Components/
│   │   │   │   │   │   ├── BoxHSBColorPicker.swift
│   │   │   │   │   │   ├── BrightnessBarView.swift
│   │   │   │   │   │   ├── CircleBarsHSBColorPicker.swift
│   │   │   │   │   │   ├── CircleBoxHSBColorPicker.swift
│   │   │   │   │   │   ├── CircleHueBarView.swift
│   │   │   │   │   │   ├── ColorBoxView.swift
│   │   │   │   │   │   ├── ColorPickerHandleLayer.swift
│   │   │   │   │   │   ├── ColorSampleView.swift
│   │   │   │   │   │   ├── HueBarView.swift
│   │   │   │   │   │   ├── OpacityBarView.swift
│   │   │   │   │   │   └── SaturationBarView.swift
│   │   │   │   │   ├── Pixel Picker/
│   │   │   │   │   │   ├── ACOverlayController.swift
│   │   │   │   │   │   ├── ACOverlayController.xib
│   │   │   │   │   │   ├── ACOverlayPanel.swift
│   │   │   │   │   │   ├── ACOverlayPreview.swift
│   │   │   │   │   │   ├── ACOverlayWrapper.swift
│   │   │   │   │   │   ├── ACPixelPicker.swift
│   │   │   │   │   │   └── Utils/
│   │   │   │   │   │       ├── Ex+CGImage.swift
│   │   │   │   │   │       ├── Ex+NSBezierPath.swift
│   │   │   │   │   │       ├── Ex+NSColor.swift
│   │   │   │   │   │       ├── ShowAndHideCursor.h
│   │   │   │   │   │       ├── ShowAndHideCursor.m
│   │   │   │   │   │       ├── ShowAndHideCursor.swift
│   │   │   │   │   │       └── Util+PixelPicker.swift
│   │   │   │   │   └── R+ColorPicker.swift
│   │   │   │   └── Movie to Gif/
│   │   │   │       ├── GifConverter.swift
│   │   │   │       └── GifConverterView+.swift
│   │   │   ├── SettingView+.swift
│   │   │   ├── Text/
│   │   │   │   ├── HyphenationRemoverView+.swift
│   │   │   │   ├── JSON Search/
│   │   │   │   │   ├── JSONNormalSearchView.swift
│   │   │   │   │   └── JSONSearchView+.swift
│   │   │   │   ├── RegexTesterView+.swift
│   │   │   │   ├── TextDiffView+.swift
│   │   │   │   └── TextInspectorView+.swift
│   │   │   └── Utils/
│   │   │       ├── CameraViewController.swift
│   │   │       ├── FileConflictAvoider.swift
│   │   │       ├── Identifier.swift
│   │   │       ├── ImageDropper.swift
│   │   │       ├── Slugify.swift
│   │   │       └── ffmpeg/
│   │   │           ├── FFMpegExecutor.swift
│   │   │           ├── FFProgressReport.swift
│   │   │           ├── FFTask.swift
│   │   │           ├── FFThumnailGenerator.swift
│   │   │           ├── FFTime.swift
│   │   │           └── ffmpeg
│   │   ├── Bridging-Header.h
│   │   ├── Component/
│   │   │   ├── Area.swift
│   │   │   ├── Button.swift
│   │   │   ├── CodeTextView.swift
│   │   │   ├── ControlBackgroundLayer.swift
│   │   │   ├── ControlContainer.swift
│   │   │   ├── DatePicker.swift
│   │   │   ├── DragImageView.swift
│   │   │   ├── EmptyImageTableView.swift
│   │   │   ├── FileDrop.swift
│   │   │   ├── ImageDropView.swift
│   │   │   ├── NumberField.swift
│   │   │   ├── Page.swift
│   │   │   ├── PopupButton.swift
│   │   │   ├── RegexTextView.swift
│   │   │   ├── Section.swift
│   │   │   ├── SectionButton+.swift
│   │   │   ├── SectionButton.swift
│   │   │   ├── TagCloudView.swift
│   │   │   ├── TextField.swift
│   │   │   ├── TextFieldSection.swift
│   │   │   ├── TextView.swift
│   │   │   ├── TextViewSection.swift
│   │   │   └── Toast.swift
│   │   ├── DevToys.entitlements
│   │   ├── Info.plist
│   │   ├── Model/
│   │   │   ├── AppModel.swift
│   │   │   ├── Settings.swift
│   │   │   ├── Tool+Default.swift
│   │   │   ├── ToolCategory+Default.swift
│   │   │   └── ToolManager+.swift
│   │   ├── Resource/
│   │   │   ├── Assets.xcassets/
│   │   │   │   ├── AccentColor.colorset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── Contents.json
│   │   │   │   ├── applewatch.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── carplay.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── check.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── clear.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── convert.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── copy.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── drop.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── error.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── export.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── format.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── hyphen.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── ipad.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── ipaddress.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── iphone.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── mac.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── network.status.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── number.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── open.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── paramators.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── paste.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── pulldown.indicator.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── search.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── settings.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── sidebar.disclosure.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── spacing.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── speed.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── spuit.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── stepper.down.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── stepper.up.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── text.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── tool/
│   │   │   │   │   ├── Contents.json
│   │   │   │   │   ├── api.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── audio.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── base64.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── color.blindness.simulator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── color.picker.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── date.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── encoder.decoder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── gif.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── graphic.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── hash.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── home.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── html.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── icon.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── image.compressor.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── image.converter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.search.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── jwt.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── lorem.ipsum.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── markdown.preview.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── media.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── network.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── number.base.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── pdf.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── qr.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── regex.tester.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── settings.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── sql.formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.diff.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.inspector.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── url.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── uuid.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   └── xml.formatter.imageset/
│   │   │   │   │       └── Contents.json
│   │   │   │   └── transparent_background.imageset/
│   │   │   │       └── Contents.json
│   │   │   ├── Base.lproj/
│   │   │   │   └── Main.storyboard
│   │   │   ├── R.swift
│   │   │   ├── de.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── en.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── es.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── ja.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── pt-BR.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   └── zh-Hans.lproj/
│   │   │       ├── Localizable.strings
│   │   │       └── Main.strings
│   │   └── Sidebar/
│   │       ├── SearchCell.swift
│   │       ├── SidebarView+.swift
│   │       ├── ToolCategoryCell.swift
│   │       ├── ToolMenuCell.swift
│   │       └── View/
│   │           └── Separator.swift
│   └── DevToys.xcodeproj/
│       ├── project.pbxproj
│       ├── project.xcworkspace/
│       │   ├── contents.xcworkspacedata
│       │   └── xcshareddata/
│       │       └── IDEWorkspaceChecks.plist
│       └── xcshareddata/
│           └── xcschemes/
│               └── DevToys.xcscheme
├── DevToys.xcworkspace/
│   ├── contents.xcworkspacedata
│   └── xcshareddata/
│       ├── IDEWorkspaceChecks.plist
│       └── swiftpm/
│           └── Package.resolved
├── LICENSE
├── README.md
├── Release Checklist.md
└── docs/
    ├── index.html
    └── sparkle/
        └── appcast.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Mac
.DS_Store

# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm

.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build/

# Accio dependency management
Dependencies/
.accio/

# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/


================================================
FILE: CoreUtil/CoreUtil/Class/Action.swift
================================================
//
//  Action.swift
//  CoreUtil
//
//  Created by yuki on 2022/01/16.
//  Copyright © 2022 yuki. All rights reserved.
//

public struct Action {
    public let title: String
    public let action: () -> ()
    
    public init(title: String, action: @escaping () -> ()) {
        self.title = title
        self.action = action
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Delta.swift
================================================
//
//  Delta.swift
//  CoreUtil
//
//  Created by yuki on 2020/05/14.
//  Copyright © 2020 yuki. All rights reserved.
//

public enum Delta<Value> {
    case to(Value)
    case by(Value)
}

extension Delta {
    @inlinable public func map<T>(_ tranceform: (Value) throws -> T) rethrows -> Delta<T> {
        switch self {
        case .to(let value): return .to(try tranceform(value))
        case .by(let value): return .by(try tranceform(value))
        }
    }
    
    @inlinable public func reduce(_ initialValue: Value, _ tranceform: (Value, Value) throws -> Value) rethrows -> Value {
        switch self {
        case .to(let value): return value
        case .by(let value): return try tranceform(initialValue, value)
        }
    }
    
    @inlinable public func takeValue() -> Value {
        switch self {
        case .to(let value): return value
        case .by(let value): return value
        }
    }
    
    @inlinable public func apply(_ initialValue: inout Value, _ tranceform: (Value, Value) throws -> Value) rethrows {
        initialValue = try reduce(initialValue, tranceform)
    }
}

extension Delta where Value: AdditiveArithmetic {
    @inlinable public func reduce(_ initialValue: Value) -> Value {
        reduce(initialValue, +)
    }
    @inlinable public func apply(_ initialValue: inout Value) {
        apply(&initialValue, +)
    }
    
    @inlinable public static func += (_ initialValue: inout Value, delta: Delta<Value>) {
        delta.apply(&initialValue)
    }
}

extension Delta where Value: RangeReplaceableCollection {
    @inlinable public func reduce(_ initialValue: Value) -> Value {
        reduce(initialValue, +)
    }
    @inlinable public func apply(_ initialValue: inout Value) {
        apply(&initialValue, +)
    }
    
    @inlinable public static func += (_ initialValue: inout Value, delta: Delta<Value>) {
        delta.apply(&initialValue)
    }
}

extension Delta: Encodable where Value: Encodable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .by(let value): try container.encode(["by": value])
        case .to(let value): try container.encode(["to": value])
        }
    }
}

extension Delta: Decodable where Value: Decodable {
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let content = try container.decode([String: Value].self)
        
        guard let (key, value) = content.first else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Empty container")
        }
        
        switch key {
        case "by": self = .by(value)
        case "to": self = .to(value)
        default: throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unkown key '\(key)'")
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/NS+OnAwake.swift
================================================
//
//  NSLoadView.swift
//  CoreUtil
//
//  Created by yuki on 2020/08/31.
//  Copyright © 2020 yuki. All rights reserved.
//

import Cocoa

open class NSLoadView: NSView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadTextView: NSTextView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadTableRowView: NSTableRowView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}


open class NSLoadVisualEffectView: NSVisualEffectView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}


open class NSLoadImageView: NSImageView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadStackView: NSStackView {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadTextField: NSTextField {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadTokenField: NSTokenField {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadSearchField: NSSearchField {

    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadScrollView: NSScrollView {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadTableView: NSTableView {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadSplitView: NSSplitView {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadControl: NSControl {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadButton: NSButton {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class NSLoadCollectionView: NSCollectionView {
    open func onAwake() {}

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
}

open class CALoadLayer: CALayer {

    open func onAwake() {}
    
    public override init() {
        super.init()
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
    public override init(layer: Any) {
        super.init(layer: layer)
        onAwake()
    }
}

open class CALoadShapeLayer: CAShapeLayer {

    open func onAwake() {}

    public override init() {
        super.init()
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
    public override init(layer: Any) {
        super.init(layer: layer)
        onAwake()
    }
}

open class CALoadTextLayer: CATextLayer {

    open func onAwake() {}

    public override init() {
        super.init()
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
    public override init(layer: Any) {
        super.init(layer: layer)
        onAwake()
    }
}

open class CALoadGradientLayer: CAGradientLayer {

    open func onAwake() {}

    public override init() {
        super.init()
        onAwake()
    }
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        onAwake()
    }
    public override init(layer: Any) {
        super.init(layer: layer)
        onAwake()
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/NSColorView.swift
================================================
//
//  NSColorView.swift
//  CoreUtil
//
//  Created by yuki on 2021/10/05.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa

open class NSColorView: NSLoadView {
    open var borderWidth: CGFloat = 1 { didSet { setNeedsDisplay(bounds) } }
    open var borderColor: NSColor? { didSet { setNeedsDisplay(bounds) } }
    open var backgroundColor: NSColor? { didSet { setNeedsDisplay(bounds) } }
    
    open override func draw(_ dirtyRect: NSRect) {
        if let backgroundColor = self.backgroundColor {
            backgroundColor.setFill()
            dirtyRect.fill()
        }
        if let borderColor = self.borderColor {
            borderColor.setStroke()
            let path = NSBezierPath(rect: dirtyRect)
            path.lineWidth = borderWidth
            path.stroke()
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/NSViewController+ChainObject.swift
================================================
//
//  NSViewController.swift
//  CoreUtil
//
//  Created by yuki on 2021/07/19.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa

private var chainObjectKey = 0
private var chainObjectFlagKey = 0

extension NSViewController {
    public var isChainObjectLoaded: Bool {
        get { objc_getAssociatedObject(self, &chainObjectFlagKey) as? Bool ?? false }
        set { objc_setAssociatedObject(self, &chainObjectFlagKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
    }
    
    public var chainObject: Any? {
        get { objc_getAssociatedObject(self, &chainObjectKey) }
        set {
            guard let chainObject = newValue else { return }
            if self.isChainObjectLoaded { return }; self.isChainObjectLoaded = true
            objc_setAssociatedObject(self, &chainObjectKey, chainObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            Self.activateObjectChain
            for child in children { child.chainObject = chainObject }
            self.chainObjectDidLoad()
        }
    }
    
    @objc open func chainObjectDidLoad() {}
    
    static let activateObjectChain: () = method_exchangeImplementations(
        class_getInstanceMethod(NSViewController.self, #selector(addChild))!,
        class_getInstanceMethod(NSViewController.self, #selector(chain_addChild))!
    )
    
    @objc private dynamic func chain_addChild(_ childViewController: NSViewController) {
        childViewController.chainObject = chainObject
        self.chain_addChild(childViewController)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/NSViewController+StateObject.swift
================================================
//
//  NSViewController+StateObject.swift
//  CoreUtil
//
//  Created by yuki on 2021/06/24.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa
import Combine

public struct StateChannel<Value> {
    let rawValue: String
    
    public init(_ rawValue: String) {
        self.rawValue = rawValue
    }
}

extension NSViewController {
    public func getState<Value>(for channel: StateChannel<Value?>) -> Value? {
        getState(for: channel).flatMap{ $0 }
    }
    public func getState<Value>(for channel: StateChannel<Value>) -> Value? {
        publisher(for: channel.rawValue).value as? Value
    }

    public func setState<Value>(_ value: Value?, for channel: StateChannel<Value>) {
        Self.activateStateObject()
        _setState(value, for: channel.rawValue)
    }
    
    public func getStatePublisher<Value>(for channel: StateChannel<Value>) -> AnyPublisher<Value?, Never> {
        publisher(for: channel.rawValue).map{ $0 as? Value }.eraseToAnyPublisher()
    }
    public func getStatePublisher<Value>(for channel: StateChannel<Value>) -> AnyPublisher<Value?, Never> where Value: AnyObject {
        publisher(for: channel.rawValue).map{ $0 as? Value }.removeDuplicates(by: ===).eraseToAnyPublisher()
    }
    public func getStatePublisher<Value>(for channel: StateChannel<Value?>) -> AnyPublisher<Value?, Never> where Value: AnyObject {
        publisher(for: channel.rawValue).map{ $0 as? Value }.removeDuplicates(by: ===).eraseToAnyPublisher()
    }
    
    public func linkState<Value>(for channel: StateChannel<Value>, to viewController: NSViewController) {
        getStatePublisher(for: channel).sink{ viewController.setState($0, for: channel) }.store(in: &self.objectBag)
    }
}

extension NSViewController {
    private static func activateStateObject() {
        enum __ {
            static let __: () = method_exchangeImplementations(
                class_getInstanceMethod(NSViewController.self, #selector(addChild))!,
                class_getInstanceMethod(NSViewController.self, #selector(_addChild))!
            )
        }
        __.__
    }
    
    private func _setState(_ value: Any?, for channel: String) {
        publisher(for: channel).send(value)
        
        for child in children {
            child._setState(value, for: channel)
        }
    }
    
    private static var envContainerKey = 0
    
    private var envContainer: [String: CurrentValueSubject<Any?, Never>] {
        get { objc_getAssociatedObject(self, &Self.envContainerKey) as? [String: CurrentValueSubject<Any?, Never>] ?? [:] }
        set { objc_setAssociatedObject(self, &Self.envContainerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
    }
    
    private func publisher(for channel: String) -> CurrentValueSubject<Any?, Never> {
        return envContainer[channel] ?? CurrentValueSubject(nil) => { envContainer[channel] = $0 }
    }
    
    @objc private dynamic func _addChild(_ childViewController: NSViewController) {
        for channel in envContainer.keys {
            guard let value = publisher(for: channel).value else { continue }
            
            childViewController._setState(value, for: channel)
        }
                
        self._addChild(childViewController)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Observable.swift
================================================
//
//  Property.swift
//  CoreUtil
//
//  Created by yuki on 2020/07/06.
//  Copyright © 2020 yuki. All rights reserved.
//

import Combine

/// Publishedの10倍軽いPropertyWrapper
@propertyWrapper
public struct Observable<Value> {

    public struct Publisher: Combine.Publisher {
        public typealias Output = Value
        public typealias Failure = Never
        
        @usableFromInline let subject: CurrentValueSubject<Value, Never>
        
        @inlinable init(_ value: Value) { self.subject = CurrentValueSubject(value) }
        
        @inlinable public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {
            self.subject.receive(subscriber: subscriber)
        }
    }
    
    public let projectedValue: Publisher
    
    @inlinable public var wrappedValue: Value {
        @inlinable get { projectedValue.subject.value }
        @inlinable set { projectedValue.subject.send(newValue) }
    }
    @inlinable public init(wrappedValue value: Value) {
        self.projectedValue = Publisher(value)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/PipeOperator.swift
================================================
//
//  +Functions.swift
//  CoreUtil
//
//  Created by yuki on 2020/10/01.
//  Copyright © 2020 yuki. All rights reserved.
//

precedencegroup PipePrecedence {
    higherThan: NilCoalescingPrecedence
    associativity: left
}

infix operator =>: PipePrecedence
infix operator |>: PipePrecedence
infix operator <=>: PipePrecedence

@discardableResult
@inlinable public func => <T>(lhs: T, rhs: (T) throws -> Void) rethrows -> T {
    try rhs(lhs)
    return lhs
}

@discardableResult
@inlinable public func |> <T, U>(lhs: T, rhs: (T) throws -> U) rethrows -> U {
    try rhs(lhs)
}

@discardableResult
@inlinable public func <=> <T>(lhs: T, rhs: (inout T) throws -> Void) rethrows -> T {
    var lhs = lhs
    try rhs(&lhs)
    return lhs
}


================================================
FILE: CoreUtil/CoreUtil/Class/Query.swift
================================================
//
//  Query.swift
//  CoreUtil
//
//  Created by yuki on 2020/01/13.
//  Copyright © 2020 yuki. All rights reserved.
//

/// 検索時のクエリを表す。検索時の処理を一般化することが目的
///
/// # 大まかな仕様
/// - 空クエリは全てにマッチ
/// - 大文字小文字を考慮せずに検索を行う
/// - 空白文字で区切った文字の全てにマッチするときにマッチする
///
/// # サンプル
/// ```
/// let query = Query("Hello World")
///
/// query.matches(to: "") // true
/// query.matches(to: "Hello whole new world.") // true
/// query.matches(to: "Hello swift.") // false
/// ```
public struct Query {
    
    /// 検索を行う要素
    let components: [String]
    
    /// 文字列で初期化
    public init(_ query: String) {
        self.components = query.components(separatedBy: .whitespaces)
            .map{ $0.lowercased() }
            .filter{ !$0.isEmpty }
    }
    /// 空クエリで初期化
    public init() {
        self.components = []
    }
    
    public var isEmpty: Bool { self.components.isEmpty }
    
    /// マッチ判定を行う。詳細は`Query`のDiscussionを参照。
    public func matches(to contents: String...) -> Bool {
        if self.components.isEmpty { return true }
        
        let contents = contents.map{ $0.lowercased() }
        
        return components.allSatisfy{ component in
            contents.contains{ $0.contains(component) }
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Reachability+Publisher.swift
================================================
//
//  Reachability+Ex.swift
//  CoreUtil
//
//  Created by yuki on 2021/09/14.
//  Copyright © 2021 yuki. All rights reserved.
//

import Foundation
import Combine

extension Reachability {
    public struct Publisher: Combine.Publisher {
        public typealias Output = Reachability
        public typealias Failure = Never
        
        let subject: CurrentValueSubject<Reachability, Never>
        
        init(_ reachability: Reachability) {
            self.subject = CurrentValueSubject(reachability)
            reachability.whenReachable = {[subject] in subject.send($0) }
            reachability.whenUnreachable = {[subject] in subject.send($0) }
            try? reachability.startNotifier()
        }
        
        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {
            self.subject.receive(subscriber: subscriber)
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Reachability.swift
================================================
/*
Copyright (c) 2014, Ashley Mills
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

import SystemConfiguration
import Foundation

public enum ReachabilityError: Error {
    case failedToCreateWithAddress(sockaddr, Int32)
    case failedToCreateWithHostname(String, Int32)
    case unableToSetCallback(Int32)
    case unableToSetDispatchQueue(Int32)
    case unableToGetFlags(Int32)
}

@available(*, unavailable, renamed: "Notification.Name.reachabilityChanged")
public let ReachabilityChangedNotification = NSNotification.Name("ReachabilityChangedNotification")

public extension Notification.Name {
    static let reachabilityChanged = Notification.Name("reachabilityChanged")
}

public class Reachability {

    public typealias NetworkReachable = (Reachability) -> ()
    public typealias NetworkUnreachable = (Reachability) -> ()
    
    public private(set) lazy var publisher = Publisher(self)

    public enum Connection: CustomStringConvertible {
        case unavailable, wifi, cellular
        public var description: String {
            switch self {
            case .cellular: return "Cellular"
            case .wifi: return "WiFi"
            case .unavailable: return "No Connection"
            }
        }
    }

    public var whenReachable: NetworkReachable?
    public var whenUnreachable: NetworkUnreachable?

    /// Set to `false` to force Reachability.connection to .none when on cellular connection (default value `true`)
    public var allowsCellularConnection: Bool

    // The notification center on which "reachability changed" events are being posted
    public var notificationCenter: NotificationCenter = NotificationCenter.default

    public var connection: Connection {
        if flags == nil {
            try? setReachabilityFlags()
        }
        
        switch flags?.connection {
        case .unavailable?, nil: return .unavailable
        case .cellular?: return allowsCellularConnection ? .cellular : .unavailable
        case .wifi?: return .wifi
        }
    }

    fileprivate var isRunningOnDevice: Bool = {
        #if targetEnvironment(simulator)
            return false
        #else
            return true
        #endif
    }()

    fileprivate(set) var notifierRunning = false
    fileprivate let reachabilityRef: SCNetworkReachability
    fileprivate let reachabilitySerialQueue: DispatchQueue
    fileprivate let notificationQueue: DispatchQueue?
    fileprivate(set) var flags: SCNetworkReachabilityFlags? {
        didSet {
            guard flags != oldValue else { return }
            notifyReachabilityChanged()
        }
    }

    required public init(reachabilityRef: SCNetworkReachability,
                         queueQoS: DispatchQoS = .default,
                         targetQueue: DispatchQueue? = nil,
                         notificationQueue: DispatchQueue? = .main) {
        self.allowsCellularConnection = true
        self.reachabilityRef = reachabilityRef
        self.reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability", qos: queueQoS, target: targetQueue)
        self.notificationQueue = notificationQueue
    }

    public convenience init(hostname: String,
                            queueQoS: DispatchQoS = .default,
                            targetQueue: DispatchQueue? = nil,
                            notificationQueue: DispatchQueue? = .main) throws {
        guard let ref = SCNetworkReachabilityCreateWithName(nil, hostname) else {
            throw ReachabilityError.failedToCreateWithHostname(hostname, SCError())
        }
        self.init(reachabilityRef: ref, queueQoS: queueQoS, targetQueue: targetQueue, notificationQueue: notificationQueue)
    }

    public convenience init(queueQoS: DispatchQoS = .default,
                            targetQueue: DispatchQueue? = nil,
                            notificationQueue: DispatchQueue? = .main) throws {
        var zeroAddress = sockaddr()
        zeroAddress.sa_len = UInt8(MemoryLayout<sockaddr>.size)
        zeroAddress.sa_family = sa_family_t(AF_INET)

        guard let ref = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress) else {
            throw ReachabilityError.failedToCreateWithAddress(zeroAddress, SCError())
        }

        self.init(reachabilityRef: ref, queueQoS: queueQoS, targetQueue: targetQueue, notificationQueue: notificationQueue)
    }

    deinit {
        stopNotifier()
    }
}

public extension Reachability {

    // MARK: - *** Notifier methods ***
    func startNotifier() throws {
        guard !notifierRunning else { return }

        let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
            guard let info = info else { return }

            // `weakifiedReachability` is guaranteed to exist by virtue of our
            // retain/release callbacks which we provided to the `SCNetworkReachabilityContext`.
            let weakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info).takeUnretainedValue()

            // The weak `reachability` _may_ no longer exist if the `Reachability`
            // object has since been deallocated but a callback was already in flight.
            weakifiedReachability.reachability?.flags = flags
        }

        let weakifiedReachability = ReachabilityWeakifier(reachability: self)
        let opaqueWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.passUnretained(weakifiedReachability).toOpaque()

        var context = SCNetworkReachabilityContext(
            version: 0,
            info: UnsafeMutableRawPointer(opaqueWeakifiedReachability),
            retain: { (info: UnsafeRawPointer) -> UnsafeRawPointer in
                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)
                _ = unmanagedWeakifiedReachability.retain()
                return UnsafeRawPointer(unmanagedWeakifiedReachability.toOpaque())
            },
            release: { (info: UnsafeRawPointer) -> Void in
                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)
                unmanagedWeakifiedReachability.release()
            },
            copyDescription: { (info: UnsafeRawPointer) -> Unmanaged<CFString> in
                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)
                let weakifiedReachability = unmanagedWeakifiedReachability.takeUnretainedValue()
                let description = weakifiedReachability.reachability?.description ?? "nil"
                return Unmanaged.passRetained(description as CFString)
            }
        )

        if !SCNetworkReachabilitySetCallback(reachabilityRef, callback, &context) {
            stopNotifier()
            throw ReachabilityError.unableToSetCallback(SCError())
        }

        if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) {
            stopNotifier()
            throw ReachabilityError.unableToSetDispatchQueue(SCError())
        }

        // Perform an initial check
        try setReachabilityFlags()

        notifierRunning = true
    }

    func stopNotifier() {
        defer { notifierRunning = false }

        SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
        SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
    }

    var description: String {
        return flags?.description ?? "unavailable flags"
    }
}

fileprivate extension Reachability {

    func setReachabilityFlags() throws {
        try reachabilitySerialQueue.sync { [unowned self] in
            var flags = SCNetworkReachabilityFlags()
            if !SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags) {
                self.stopNotifier()
                throw ReachabilityError.unableToGetFlags(SCError())
            }
            
            self.flags = flags
        }
    }
    

    func notifyReachabilityChanged() {
        let notify = { [weak self] in
            guard let self = self else { return }
            self.connection != .unavailable ? self.whenReachable?(self) : self.whenUnreachable?(self)
            self.notificationCenter.post(name: .reachabilityChanged, object: self)
        }

        // notify on the configured `notificationQueue`, or the caller's (i.e. `reachabilitySerialQueue`)
        notificationQueue?.async(execute: notify) ?? notify()
    }
}

extension SCNetworkReachabilityFlags {

    typealias Connection = Reachability.Connection

    var connection: Connection {
        guard isReachableFlagSet else { return .unavailable }

        // If we're reachable, but not on an iOS device (i.e. simulator), we must be on WiFi
        #if targetEnvironment(simulator)
        return .wifi
        #else
        var connection = Connection.unavailable

        if !isConnectionRequiredFlagSet {
            connection = .wifi
        }

        if isConnectionOnTrafficOrDemandFlagSet {
            if !isInterventionRequiredFlagSet {
                connection = .wifi
            }
        }

        if isOnWWANFlagSet {
            connection = .cellular
        }

        return connection
        #endif
    }

    var isOnWWANFlagSet: Bool {
        #if os(iOS)
        return contains(.isWWAN)
        #else
        return false
        #endif
    }
    var isReachableFlagSet: Bool {
        return contains(.reachable)
    }
    var isConnectionRequiredFlagSet: Bool {
        return contains(.connectionRequired)
    }
    var isInterventionRequiredFlagSet: Bool {
        return contains(.interventionRequired)
    }
    var isConnectionOnTrafficFlagSet: Bool {
        return contains(.connectionOnTraffic)
    }
    var isConnectionOnDemandFlagSet: Bool {
        return contains(.connectionOnDemand)
    }
    var isConnectionOnTrafficOrDemandFlagSet: Bool {
        return !intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty
    }
    var isTransientConnectionFlagSet: Bool {
        return contains(.transientConnection)
    }
    var isLocalAddressFlagSet: Bool {
        return contains(.isLocalAddress)
    }
    var isDirectFlagSet: Bool {
        return contains(.isDirect)
    }
    var isConnectionRequiredAndTransientFlagSet: Bool {
        return intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]
    }

    var description: String {
        let W = isOnWWANFlagSet ? "W" : "-"
        let R = isReachableFlagSet ? "R" : "-"
        let c = isConnectionRequiredFlagSet ? "c" : "-"
        let t = isTransientConnectionFlagSet ? "t" : "-"
        let i = isInterventionRequiredFlagSet ? "i" : "-"
        let C = isConnectionOnTrafficFlagSet ? "C" : "-"
        let D = isConnectionOnDemandFlagSet ? "D" : "-"
        let l = isLocalAddressFlagSet ? "l" : "-"
        let d = isDirectFlagSet ? "d" : "-"

        return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)"
    }
}

/**
 `ReachabilityWeakifier` weakly wraps the `Reachability` class
 in order to break retain cycles when interacting with CoreFoundation.

 CoreFoundation callbacks expect a pair of retain/release whenever an
 opaque `info` parameter is provided. These callbacks exist to guard
 against memory management race conditions when invoking the callbacks.

 #### Race Condition

 If we passed `SCNetworkReachabilitySetCallback` a direct reference to our
 `Reachability` class without also providing corresponding retain/release
 callbacks, then a race condition can lead to crashes when:
 - `Reachability` is deallocated on thread X
 - A `SCNetworkReachability` callback(s) is already in flight on thread Y

 #### Retain Cycle

 If we pass `Reachability` to CoreFoundtion while also providing retain/
 release callbacks, we would create a retain cycle once CoreFoundation
 retains our `Reachability` class. This fixes the crashes and his how
 CoreFoundation expects the API to be used, but doesn't play nicely with
 Swift/ARC. This cycle would only be broken after manually calling
 `stopNotifier()` — `deinit` would never be called.

 #### ReachabilityWeakifier

 By providing both retain/release callbacks and wrapping `Reachability` in
 a weak wrapper, we:
 - interact correctly with CoreFoundation, thereby avoiding a crash.
 See "Memory Management Programming Guide for Core Foundation".
 - don't alter the public API of `Reachability.swift` in any way
 - still allow for automatic stopping of the notifier on `deinit`.
 */
private class ReachabilityWeakifier {
    weak var reachability: Reachability?
    init(reachability: Reachability) {
        self.reachability = reachability
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/RestorableData.swift
================================================
//
//  RestorableData.swift
//  CoreUtil
//
//  Created by yuki on 2022/02/03.
//

import Cocoa

extension FileManager {
    public static let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.noname.app")
}

private let encoder = JSONEncoder()
private let decoder = JSONDecoder()
private let restorableDataURL = FileManager.temporaryDirectoryURL.appendingPathComponent("RestorableData") => {
    try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)
}

@propertyWrapper
public struct RestorableData<Value: Codable> {
    public struct Publisher: Combine.Publisher {
        public typealias Output = Value
        public typealias Failure = Never
        
        let subject: CurrentValueSubject<Value, Never>
        
        init(_ value: Value) { self.subject = CurrentValueSubject(value) }
        
        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {
            self.subject.receive(subscriber: subscriber)
        }
    }
    
    public let projectedValue: Publisher
    public let key: String
    public let fileURL: URL
    
    public var wrappedValue: Value {
        get { projectedValue.subject.value }
        set {
            projectedValue.subject.send(newValue)
            do { try encoder.encode(newValue).write(to: fileURL) } catch {}
        }
    }
    public init(wrappedValue initialValue: Value, _ key: String) {
        self.key = key
        self.fileURL = restorableDataURL.appendingPathComponent(key + ".json")
        
        let wrappedValue: Value
        do {
            wrappedValue = try decoder.decode(Value.self, from: Data(contentsOf: fileURL))
        } catch {
            wrappedValue = initialValue
        }
        
        self.projectedValue = Publisher(wrappedValue)
    }
}

final public class NSImageContainer: Codable {
    static let dataDirectoryURL = FileManager.temporaryDirectoryURL.appendingPathComponent("NSImageContainer") => {
        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)
    }
    
    public let image: NSImage
    public let id: String
    public init(_ image: NSImage) {
        self.image = image
        self.id = UUID().uuidString
    }
    
    public static func wrap(_ image: NSImage) -> NSImageContainer { NSImageContainer(image) }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(id)
        let fileURL = NSImageContainer.dataDirectoryURL.appendingPathComponent(id)
        if !FileManager.default.fileExists(atPath: fileURL.path) {
            try image.tiffRepresentation?.write(to: fileURL)
        }
    }
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let id = try container.decode(String.self)
        let fileURL = NSImageContainer.dataDirectoryURL.appendingPathComponent(id)
        guard let image = NSImage(contentsOf: fileURL) else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "No image"))
        }
        self.image = image
        self.id = id
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/RestorableState.swift
================================================
//
//  RestorableState.swift
//  CoreUtil
//
//  Created by yuki on 2022/02/03.
//

import Foundation

@propertyWrapper
public struct RestorableState<Value: RawRepresentable> {
    public struct Publisher: Combine.Publisher {
        public typealias Output = Value
        public typealias Failure = Never
        
        let subject: CurrentValueSubject<Value, Never>
        
        init(_ value: Value) { self.subject = CurrentValueSubject(value) }
        
        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {
            self.subject.receive(subscriber: subscriber)
        }
    }
    
    public let projectedValue: Publisher
    public let key: String
    
    public var wrappedValue: Value {
        get { projectedValue.subject.value }
        set {
            projectedValue.subject.send(newValue)
            UserDefaults.standard.set(newValue.rawValue, forKey: key)
        }
    }
    public init(wrappedValue initialValue: Value, _ key: String) {
        let wrappedValue: Value
        
        if let rawValue = UserDefaults.standard.object(forKey: key) as? Value.RawValue, let value = Value(rawValue: rawValue) {
            wrappedValue = value
        } else {
            wrappedValue = initialValue
        }
        
        self.projectedValue = Publisher(wrappedValue)
        self.key = key
    }
}

extension String: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}

extension Bool: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}

extension Optional: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}

extension Int: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}

extension CGFloat: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}

extension Double: RawRepresentable {
    public var rawValue: Self { self }
    public init(rawValue: Self) { self = rawValue }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Terminal.swift
================================================
//
//  Terminal.swift
//  CoreUtil
//
//  Created by yuki on 2022/02/11.
//

import Foundation

public enum TerminalError: Error, CustomStringConvertible {
    case nonZeroExit(String)
    
    public var description: String {
        switch self {
        case .nonZeroExit(let string): return string
        }
    }
}

public enum Terminal {
    public struct ExecuteOption: OptionSet {
        public let rawValue: UInt64
        
        public init(rawValue: UInt64) { self.rawValue = rawValue }
        
        public static let standardOutput = ExecuteOption(rawValue: 1 << 0)
        public static let standardError = ExecuteOption(rawValue: 1 << 1)
    }
    
    public static func run(_ executableURL: URL, arguments: [String], queue: DispatchQueue = .global(), options: ExecuteOption = .all) -> Promise<String, Error> {
        let task = Process()
        let outputPipe = Pipe()
        let errorPipe = Pipe()
        
        task.executableURL = executableURL
        task.arguments = arguments
        
        if options.contains(.standardOutput) {
            task.standardOutput = outputPipe
        }
        if options.contains(.standardError) {
            task.standardError = errorPipe
        }
        
        return Promise<String, Error>.tryAsync(on: queue) { resolve, reject in
            try task.run()
            task.waitUntilExit()
            
            if task.terminationStatus != 0 {
                reject(TerminalError.nonZeroExit(errorPipe.readStringToEndOfFile ?? "[binary]"))
            } else {
                resolve(outputPipe.readStringToEndOfFile ?? "[binary]")
            }
        }
    }
}

extension Pipe {
    public var readStringToEndOfFile: String? {
        String(data: self.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/ViewPlaceholder.swift
================================================
//
//  ViewPlaceholder.swift
//  CoreUtil
//
//  Created by yuki on 2021/06/03.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa
import Combine

open class NSPlaceholderView<View: NSView>: NSLoadView {
    public var contentView: View? {
        didSet {
            oldValue?.removeFromSuperview()
            if let contentView = contentView {
                self.addSubview(contentView)
                contentView.translatesAutoresizingMaskIntoConstraints = false
                NSLayoutConstraint.activate([
                    contentView.rightAnchor.constraint(equalTo: self.rightAnchor),
                    contentView.leftAnchor.constraint(equalTo: self.leftAnchor),
                    contentView.topAnchor.constraint(equalTo: self.topAnchor),
                    contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
                ])
            }
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Class/Zip3Sequence.swift
================================================
//
//  Zip3Sequence.swift
//  CoreUtil
//
//  Created by yuki on 2022/01/22.
//  Copyright © 2022 yuki. All rights reserved.
//

public func zip<A: Sequence, B: Sequence, C: Sequence>(_ a: A, _ b: B, _ c: C) -> Zip3Sequence<A, B, C> {
    Zip3Sequence(a, b, c)
}
public func zip<A: Sequence, B: Sequence, C: Sequence, D: Sequence>(_ a: A, _ b: B, _ c: C, _ d: D) -> Zip4Sequence<A, B, C, D> {
    Zip4Sequence(a, b, c, d)
}

public struct Zip3Sequence<A: Sequence, B: Sequence, C: Sequence>: Sequence {
    public typealias Element = (A.Element, B.Element, C.Element)
    
    public let a: A
    public let b: B
    public let c: C
    
    public struct Iterator: IteratorProtocol {
        var a: A.Iterator
        var b: B.Iterator
        var c: C.Iterator
        
        mutating public func next() -> Element? {
            if let a = a.next(), let b = b.next(), let c = c.next() { return (a, b, c) }; return nil
        }
    }
    
    public func makeIterator() -> Iterator { Iterator(a: a.makeIterator(), b: b.makeIterator(), c: c.makeIterator()) }
    
    init(_ a: A, _ b: B, _ c: C) {
        self.a = a
        self.b = b
        self.c = c
    }
}

public struct Zip4Sequence<A: Sequence, B: Sequence, C: Sequence, D: Sequence>: Sequence {
    public typealias Element = (A.Element, B.Element, C.Element, D.Element)
    
    public let a: A
    public let b: B
    public let c: C
    public let d: D
    
    public struct Iterator: IteratorProtocol {
        var a: A.Iterator
        var b: B.Iterator
        var c: C.Iterator
        var d: D.Iterator
        
        mutating public func next() -> Element? {
            if let a = a.next(), let b = b.next(), let c = c.next(), let d = d.next() { return (a, b, c, d) }; return nil
        }
    }
    
    public func makeIterator() -> Iterator { Iterator(a: a.makeIterator(), b: b.makeIterator(), c: c.makeIterator(), d: d.makeIterator()) }
    
    init(_ a: A, _ b: B, _ c: C, _ d: D) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}


================================================
FILE: CoreUtil/CoreUtil/CoreUtil.h
================================================
//
//  CoreUtil.h
//  CoreUtil
//
//  Created by yuki on 2022/01/29.
//

#import <Foundation/Foundation.h>
#import "ExceptionHanlder.h"

//! Project version number for CoreUtil.
FOUNDATION_EXPORT double CoreUtilVersionNumber;

//! Project version string for CoreUtil.
FOUNDATION_EXPORT const unsigned char CoreUtilVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <CoreUtil/PublicHeader.h>


================================================
FILE: CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHandler.swift
================================================
//
//  ExceptionHandler.swift
//  CoreUtil
//
//  Created by yuki on 2021/06/26.
//  Copyright © 2021 yuki. All rights reserved.
//

@inlinable public func objc_try(_ tryBlock: () -> ()) throws {
    var error: NSError?
    _ExceptionHandler.objc_try(tryBlock, objc_catch: {
        error = NSError(domain: "NSException", code: 999, userInfo: $0.userInfo?.reduce(into: [:]) { $0["\($1.key)"] = $1.value })
    }, objc_finally: {})
    if let error = error { throw error }
}

@inlinable public func objc_try<T>(_ tryBlock: () -> T) throws -> T {
    var value: T?
    var error: NSError?
    _ExceptionHandler.objc_try({
        value = tryBlock()
    }, objc_catch: {
        error = NSError(domain: "NSException", code: 999, userInfo: $0.userInfo?.reduce(into: [:]) { $0["\($1.key)"] = $1.value })
    }, objc_finally: {})
    if let error = error { throw error }
    return value!
}

@inlinable public func objc_try(_ tryBlock: () -> (), catch catchBlock: (NSException) -> (), finally finallyBlock: () -> () = {}) {
    _ExceptionHandler.objc_try(tryBlock, objc_catch: catchBlock, objc_finally: finallyBlock)
}

@inlinable public func objc_try<T>(_ tryBlock: () -> T, catch catchBlock: (NSException) -> T, finally finallyBlock: () -> () = {}) -> T {
    var value: T!
    
    _ExceptionHandler.objc_try({
        value = tryBlock()
    }, objc_catch: {
        value = catchBlock($0)
    }, objc_finally: finallyBlock)
    
    return value
}


================================================
FILE: CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.h
================================================
//
//  ExceptionHanlder.h
//  CoreUtil
//
//  Created by yuki on 2021/06/26.
//  Copyright © 2021 yuki. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface _ExceptionHandler : NSObject
+ (void)objc_try: (nonnull __attribute__((noescape)) void(^)(void))objc_try
      objc_catch: (nonnull __attribute__((noescape)) void(^)(NSException* _Nonnull))objc_catch
    objc_finally: (nullable __attribute__((noescape)) void(^)(void))objc_finally;
@end



================================================
FILE: CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.m
================================================
//
//  ExceptionHanlder.m
//  CoreUtil
//
//  Created by yuki on 2021/06/26.
//  Copyright © 2021 yuki. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <ExceptionHanlder.h>

@implementation _ExceptionHandler : NSObject 
+ (void)objc_try: (nonnull __attribute__((noescape)) void(^)(void)) objc_try
      objc_catch: (nonnull __attribute__((noescape)) void(^)(NSException* _Nonnull)) objc_catch
    objc_finally: (nullable __attribute__((noescape)) void(^)(void)) objc_finally {
    @try {
        objc_try();
    } @catch (NSException* exception) {
        objc_catch(exception);
    } @finally {
        if (objc_finally) { objc_finally(); }
    }
}
@end



================================================
FILE: CoreUtil/CoreUtil/Export.swift
================================================
//
//  Export.swift
//  CoreUtil
//
//  Created by yuki on 2022/01/29.
//

@_exported import Promise
@_exported import SnapKit
@_exported import Cocoa
@_exported import Combine


================================================
FILE: CoreUtil/CoreUtil/Extensions/Combine/Combine+ObjectBag.swift
================================================
//
//  NSObject+Combine.swift
//  CoreUtil
//
//  Created by yuki on 2020/05/22.
//  Copyright © 2020 yuki. All rights reserved.
//

import Foundation
import Combine

private var bagKey: UInt8 = 0

extension NSObject {
    public var objectBag: Set<AnyCancellable> {
        get { bagContainer.value } set { bagContainer.value = newValue }
    }
    
    private class BagContainer {
        var value = Set<AnyCancellable>()
    }
    
    private var bagContainer: BagContainer {
        if let container = objc_getAssociatedObject(self, &bagKey) as? BagContainer { return container }
        let container = BagContainer()
        objc_setAssociatedObject(self, &bagKey, container, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return container
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Combine/Combine+Peek.swift
================================================
//
//  Combine+Peek.swift
//  CoreUtil
//
//  Created by yuki on 2022/02/01.
//

import Combine

extension Publisher {
    public func peekError(_ block: @escaping (Failure) -> Void) -> Publishers.MapError<Self, Failure> {
        self.mapError { f -> Failure in block(f); return f }
    }
    public func peek(_ block: @escaping (Output) -> Void) -> Publishers.Map<Self, Output> {
        self.map { block($0); return $0 }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Combine/NSControl+Combine.swift
================================================
//
//  NSButton+Combine.swift
//  CoreUtil
//
//  Created by yuki on 2021/07/23.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa
import Combine

private var actionPublisherKey = 0

extension NSControl {
    
    final public class Publisher: Combine.Publisher {
        public typealias Output = Void
        public typealias Failure = Never
        
        final class Target: NSObject {
            let subject = PassthroughSubject<Void, Never>()
            @objc func action(_ sender: NSControl) { self.subject.send() }
        }
        
        let target: Target
        
        init(control: NSControl) {
            let target = Target()
            control.target = target
            control.action = #selector(Target.action)
            self.target = target
        }
        
        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Failure, S.Input == Output {
            self.target.subject.receive(subscriber: subscriber)
        }
    }
    
    // actionとtargetを設定してpublisherとして出力できるようにします。
    public var actionPublisher: Publisher {
        if let publisher = objc_getAssociatedObject(self, &actionPublisherKey) as? Publisher { return publisher }
        let publisher = Publisher(control: self)
        objc_setAssociatedObject(self, &actionPublisherKey, publisher, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return publisher
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Combine/NSTextField+Combine.swift
================================================
//
//  Combine+TextField.swift
//  CoreUtil
//
//  Created by yuki on 2021/01/03.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa
import Combine

private var delegateKey = 0

extension NSTextField {
    
    public var endEditingStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.endEditingPublisher.map{ $0.stringValue }.eraseToAnyPublisher() }
    public var changeStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.changePublisher.map{ $0.stringValue }.eraseToAnyPublisher() }
    public var beginEditingStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.beginEditingPublisher.map{ $0.stringValue }.eraseToAnyPublisher() }
    
    public var endEditingPublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.endEditingPublisher.eraseToAnyPublisher() }
    public var changePublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.changePublisher.eraseToAnyPublisher() }
    public var beginEditingPublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.beginEditingPublisher.eraseToAnyPublisher() }
    
    final private class PublisherDelegate: NSObject, NSTextFieldDelegate {
        let endEditingPublisher = PassthroughSubject<NSTextField, Never>()
        let changePublisher = PassthroughSubject<NSTextField, Never>()
        let beginEditingPublisher = PassthroughSubject<NSTextField, Never>()
        
        func controlTextDidBeginEditing(_ obj: Notification) {
            guard let textField = obj.object as? NSTextField else { return }
            beginEditingPublisher.send(textField)
        }
        func controlTextDidChange(_ obj: Notification) {
            guard let textField = obj.object as? NSTextField else { return }
            changePublisher.send(textField)
        }
        func controlTextDidEndEditing(_ obj: Notification) {
            guard let textField = obj.object as? NSTextField else { return }
            endEditingPublisher.send(textField)
        }
    }
    
    private var pubilsherDelegate: PublisherDelegate {
        if let delegate = objc_getAssociatedObject(self, &delegateKey) as? PublisherDelegate { return delegate }
        let delegate = PublisherDelegate()
        objc_setAssociatedObject(self, &delegateKey, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        assert(self.delegate == nil, "Publisher delegate is not averable. \(delegate)")
        self.delegate = delegate
        return delegate
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGPoint.swift
================================================
//
//  Ex+CGPoint.swift
//  Topica
//
//  Created by yuki on 2019/10/27.
//  Copyright © 2019 yuki. All rights reserved.
//

import CoreGraphics

@inlinable public func round(_ point: CGPoint) -> CGPoint {
    CGPoint(x: round(point.x), y: round(point.y))
}

@inlinable public func ceil(_ point: CGPoint) -> CGPoint {
    CGPoint(x: ceil(point.x), y: ceil(point.y))
}

@inlinable public func floor(_ point: CGPoint) -> CGPoint {
    CGPoint(x: floor(point.x), y: floor(point.y))
}

@inlinable public func sign(_ point: CGPoint) -> CGPoint {
    CGPoint(x: sign(point.x), y: sign(point.y))
}

@inlinable public func min(_ point0: CGPoint, _ point1: CGPoint) -> CGPoint {
    CGPoint(x: min(point0.x, point1.x), y: min(point0.y, point1.y))
}

@inlinable public func max(_ point0: CGPoint, _ point1: CGPoint) -> CGPoint {
    CGPoint(x: max(point0.x, point1.x), y: max(point0.y, point1.y))
}

@inlinable public func abs(_ point: CGPoint) -> CGFloat {
    sqrt(point.x * point.x + point.y * point.y)
}

@inlinable public func abs2(_ point: CGPoint) -> CGFloat {
    point.x * point.x + point.y * point.y
}

@inlinable public func clamp(_ point: CGPoint, in rect: CGRect) -> CGPoint {
    CGPoint(x: clamp(point.x, into: rect.minX...rect.maxX), y: clamp(point.y, into: rect.minY...rect.maxY))
}

@inlinable public func dot(_ point0: CGPoint, _ point1: CGPoint) -> CGFloat {
    point0.x * point1.x + point0.y * point1.y
}

extension CGPoint {
    public static let infinity = CGSize(width: CGFloat.infinity, height: .infinity)
    
    @inlinable public func convertToSize() -> CGSize {
        CGSize(width: x, height: y)
    }

    @inlinable public var unitVector: CGPoint {
        let absValue = abs(self)
        if absValue == 0 { return .zero }
        return self / absValue
    }
    
    @inlinable public var isFinite: Bool {
        x.isFinite && y.isFinite
    }
}

extension CGPoint {
    @inlinable public func map(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {
        mapX(tranceform).mapY(tranceform)
    }
    @inlinable public func mapX(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {
        CGPoint(x: tranceform(x), y: y)
    }
    @inlinable public func mapY(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {
        CGPoint(x: x, y: tranceform(y))
    }
}

extension CGPoint: ExpressibleByArrayLiteral {
    @inlinable public init(arrayLiteral elements: CGFloat...) {
        assert(elements.count == 2)
        self.init(x: elements[0], y: elements[1])
    }
}

extension CGPoint: Hashable {
    @inlinable public func hash(into hasher: inout Hasher) {
        hasher.combine(x)
        hasher.combine(y)
    }
}

extension CGPoint: AdditiveArithmetic {
    @inlinable public static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
    @inlinable public static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
    }
    @inlinable public static prefix func - (lhs: CGPoint) -> CGPoint {
        CGPoint(x: -lhs.x, y: -lhs.y)
    }
    @inlinable public static func += (lhs: inout CGPoint, rhs: CGPoint) {
        lhs = CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
    @inlinable public static func -= (lhs: inout CGPoint, rhs: CGPoint) {
        lhs = CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
    }
}

extension CGPoint {
    @inlinable public static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
        return CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)
    }
    @inlinable public static func * (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        return CGPoint(x: lhs.x * rhs.x, y: lhs.y * rhs.y)
    }
    @inlinable public static func / (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
        return CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)
    }
    @inlinable public static func / (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        return CGPoint(x: lhs.x / rhs.x, y: lhs.y / rhs.y)
    }
    @inlinable public static func *= (lhs: inout CGPoint, rhs: CGFloat) {
        lhs = CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)
    }
    @inlinable public static func /= (lhs: inout CGPoint, rhs: CGFloat) {
        lhs = CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGRect.swift
================================================
//
//  Ex+CGRect.swift
//  CoreUtil
//
//  Created by yuki on 2020/02/03.
//  Copyright © 2020 yuki. All rights reserved.
//

import Foundation

@inlinable public func round(_ rect: CGRect) -> CGRect {
    CGRect(origin: round(rect.origin), end: round(rect.end))
}

extension CGRect {
    @inlinable public var center: CGPoint {
        @inlinable get { CGPoint(x: midX, y: midY) }
        @inlinable set { self.origin = CGPoint(x: newValue.x - width/2, y: newValue.y - height/2) }
    }

    @inlinable public var end: CGPoint {
        @inlinable get { CGPoint(x: maxX, y: maxY) }
        @inlinable set { self.origin = CGPoint(x: newValue.x - width, y: newValue.y - height) }
    }

    @inlinable public func fattened(by inset: CGFloat) -> CGRect {
        CGRect(origin: self.origin - [inset, inset], size: self.size + [inset, inset]*2)
    }

    @inlinable public func slimmed(by inset: CGFloat) -> CGRect {
        CGRect(origin: self.origin + [inset, inset], size: self.size - [inset, inset]*2)
    }

    @inlinable public func fattened(by edgeInsets: NSEdgeInsets) -> CGRect {
        CGRect(origin: self.origin - [edgeInsets.left, edgeInsets.bottom],
               size: self.size + [edgeInsets.left + edgeInsets.right, edgeInsets.top + edgeInsets.bottom])
    }

    @inlinable public func slimmed(by edgeInsets: NSEdgeInsets) -> CGRect {
        CGRect(origin: self.origin + [edgeInsets.left, edgeInsets.bottom],
               size: self.size - [edgeInsets.left + edgeInsets.right, edgeInsets.top + edgeInsets.bottom])
    }
}

extension CGRect {
    @inlinable public func mapOrigin(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {
        CGRect(origin: tranceform(origin), size: size)
    }
    @inlinable public func mapCenter(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {
        CGRect(center: tranceform(center), size: size)
    }
    @inlinable public func mapEnd(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {
        CGRect(end: tranceform(end), size: size)
    }
    @inlinable public func mapSizePreservingOrigin(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {
        CGRect(origin: origin, size: tranceform(size))
    }
    @inlinable public func mapSizePreservingCenter(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {
        CGRect(center: center, size: tranceform(size))
    }
    @inlinable public func mapSizePreservingEnd(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {
        CGRect(end: end, size: tranceform(size))
    }
}

extension CGRect {
    @inlinable public init(origin: CGPoint) {
        self.init(origin: origin, size: .zero)
    }
    @inlinable public init(size: CGSize) {
        self.init(origin: .zero, size: size)
    }
    @inlinable public init(origin: CGPoint, end: CGPoint) {
        self.init(origin: origin, size: (end - origin).convertToSize())
    }
    @inlinable public init(center: CGPoint, size: CGSize) {
        self.init(origin: center - size.convertToPoint() / 2, size: size)
    }
    @inlinable public init(end: CGPoint, size: CGSize) {
        self.init(origin: end - size.convertToPoint(), size: size)
    }
    @inlinable public init(originX: CGFloat, centerY: CGFloat, size: CGSize) {
        self.init(origin: [originX, centerY - size.height/2], size: size)
    }
    @inlinable public init(centerX: CGFloat, originY: CGFloat, size: CGSize) {
        self.init(origin: [centerX - size.width/2, originY], size: size)
    }
    
    @inlinable public var isFinite: Bool {
        size.isFinite && origin.isFinite
    }
}

extension CGRect {
    @inlinable public static func + (lhs: CGRect, rhs: CGRect) -> CGRect {
        CGRect(origin: lhs.origin + rhs.origin, size: lhs.size + rhs.size)
    }
    @inlinable public static func - (lhs: CGRect, rhs: CGRect) -> CGRect {
        CGRect(origin: lhs.origin - rhs.origin, size: lhs.size - rhs.size)
    }
}

extension CGRect: Hashable {
    @inlinable public func hash(into hasher: inout Hasher) {
        hasher.combine(size)
        hasher.combine(origin)
    }
}

extension Collection where Element == CGRect {
    @inlinable public var enclosingRect: CGRect {
        if self.isEmpty { return .zero }
        
        var minX: CGFloat = .infinity
        var minY: CGFloat = .infinity
        var maxX: CGFloat = -.infinity
        var maxY: CGFloat = -.infinity
        
        for rect in self {
            if minX > rect.origin.x { minX = rect.origin.x }
            if minY > rect.origin.y { minY = rect.origin.y }
            let _maxX = rect.origin.x + rect.size.width
            if maxX < _maxX { maxX = _maxX }
            let _maxY = rect.origin.y + rect.size.height
            if maxY < _maxY { maxY = _maxY }
        }
        
        let rect = CGRect(origin: [minX, minY], end: [maxX, maxY])
        return rect
    }
}

extension FloatingPoint {
    @inlinable public func isFiniteOrZero() -> Self { isFinite ? self : .zero }
}
extension CGPoint {
    @inlinable public func isFiniteOrZero() -> CGPoint { isFinite ? self : .zero }
}
extension CGSize {
    @inlinable public func isFiniteOrZero() -> CGSize { isFinite ? self : .zero }
}
extension CGRect {
    @inlinable public func isFiniteOrZero() -> CGRect { isFinite ? self : .zero }
}



================================================
FILE: CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGSize.swift
================================================
import CoreGraphics


@inlinable public func round(_ size: CGSize) -> CGSize {
    CGSize(width: round(size.width), height: round(size.height))
}

@inlinable public func abs(_ size: CGSize) -> CGSize {
    CGSize(width: abs(size.width), height: abs(size.height))
}

@inlinable public func sign(_ size: CGSize) -> CGSize {
    CGSize(width: sign(size.width), height: sign(size.height))
}

@inlinable public func min(_ size0: CGSize, _ size1: CGSize) -> CGSize {
    CGSize(width: min(size0.width, size1.width), height: min(size0.height, size1.height))
}

@inlinable public func max(_ size0: CGSize, _ size1: CGSize) -> CGSize {
    CGSize(width: max(size0.width, size1.width), height: max(size0.height, size1.height))
}

extension CGSize {
    @inlinable public func convertToPoint() -> CGPoint {
        CGPoint(x: width, y: height)
    }
    
    @inlinable public var minElement: CGFloat {
        min(abs(self.width), abs(self.height))
    }
    @inlinable public var maxElement: CGFloat {
        max(abs(self.width), abs(self.height))
    }
    @inlinable public var isFinite: Bool {
        width.isFinite && height.isFinite
    }
    
    public static let infinity = CGSize(width: CGFloat.infinity, height: .infinity)
}

extension CGSize {
    @inlinable public func mapWidth(_ tranceform: (CGFloat) -> (CGFloat)) -> CGSize {
        CGSize(width: tranceform(width), height: height)
    }
    @inlinable public func mapHeight(_ tranceform: (CGFloat) -> (CGFloat)) -> CGSize {
        CGSize(width: width, height: tranceform(height))
    }
}

extension CGSize: ExpressibleByArrayLiteral {
    public init(arrayLiteral elements: CGFloat...) {
        assert(elements.count == 2)
        self.init(width: elements[0], height: elements[1])
    }
}

extension CGSize: AdditiveArithmetic {
    @inlinable public static func + (lhs: CGSize, rhs: CGSize) -> CGSize {
        CGSize(width: lhs.width + rhs.width, height: lhs.height + rhs.height)
    }
    @inlinable public static func - (lhs: CGSize, rhs: CGSize) -> CGSize {
        CGSize(width: lhs.width - rhs.width, height: lhs.height - rhs.height)
    }
    @inlinable public static prefix func - (lhs: CGSize) -> CGSize {
        CGSize(width: -lhs.width, height: -lhs.height)
    }
}

extension CGSize {
    @inlinable public static func * (lhs: CGSize, rhs: CGFloat) -> CGSize {
        return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
    }
    @inlinable public static func * (lhs: CGSize, rhs: CGSize) -> CGSize {
        return CGSize(width: lhs.width * rhs.width, height: lhs.height * rhs.height)
    }
    @inlinable public static func / (lhs: CGSize, rhs: CGFloat) -> CGSize {
        return CGSize(width: lhs.width / rhs, height: lhs.height / rhs)
    }
    @inlinable public static func / (lhs: CGSize, rhs: CGSize) -> CGSize {
        return CGSize(width: lhs.width / rhs.width, height: lhs.height / rhs.height)
    }
    @inlinable public static func *= (lhs: inout CGSize, rhs: CGFloat) {
        lhs.width *= rhs
        lhs.height *= rhs
    }
    @inlinable public static func /= (lhs: inout CGSize, rhs: CGFloat) {
        lhs.width /= rhs
        lhs.height /= rhs
    }
}

extension CGSize: Hashable {
    @inlinable public func hash(into hasher: inout Hasher) {
        hasher.combine(width)
        hasher.combine(height)
    }
}

extension CGSize {
    /// boundingBoxにアスペクトフィットするのに必要な変換レートを返します。
    @inlinable public func aspectFitRatio(fitInside boundingBox: CGSize) -> CGFloat {
        let mW = boundingBox.width / self.width
        let mH = boundingBox.height / self.height

        if mH > mW {
            return boundingBox.width / self.width
        } else {
            return boundingBox.height / self.height
        }
    }

    /// boundingBoxにアスペクトフィルするのに必要な変換レートを返します。
    @inlinable public func aspectFillRatio(fillInside boundingBox: CGSize) -> CGFloat {
        let mW = boundingBox.width / self.width
        let mH = boundingBox.height / self.height

        if mH < mW {
            return boundingBox.width / self.width
        } else {
            return boundingBox.height / self.height
        }
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Swift/Ex+Array.swift
================================================
//
//  Extensions.swift
//  DANMAKER
//
//  Created by yuki on 2015/06/24.
//  Copyright © 2015 yuki. All rights reserved.
//

extension RandomAccessCollection {
    @inlinable public func at(_ index: Self.Index) -> Element? {
        self.indices.contains(index) ? self[index] : nil
    }
}

extension Sequence {
    @inlinable public func count(where condition: (Element) throws -> Bool) rethrows -> Int {
        try self.lazy.filter(condition).count
    }
    @inlinable public func count(while condition: (Element) throws -> Bool) rethrows -> Int {
        var count = 0
        for element in self {
            if try !condition(element) { return count }
            count += 1
        }
        return count
    }
    
    @inlinable public func firstSome<T>(where condition: (Element) throws -> T?) rethrows -> T? {
        try self.lazy.compactMap(condition).first
    }
    
    @inlinable public func allSome<T>(_ tranceform: (Element) throws -> T?) rethrows -> [T]? {
        var values = [T]()
        for element in self {
            guard let element = try tranceform(element) else { return nil }
            values.append(element)
        }
        return values
    }
}

extension Array {
    public mutating func move(fromIndex: Int, toIndex: Int) {
        assert(indices.contains(fromIndex), "fromIndex '\(fromIndex)' is out of bounds.")
        
        if fromIndex == toIndex { return }
        let removed = self.remove(at: fromIndex)
        
        if fromIndex < toIndex {
            self.insert(removed, at: toIndex - 1)
        } else {
            self.insert(removed, at: toIndex)
        }
    }
    
    public mutating func move<Range: RangeExpression>(fromRange: Range, toIndex: Int) where Range.Bound == Int {
        assert(indices.contains(toIndex), "toIndex '\(toIndex)' is out of bounds.")
        let range = fromRange.relative(to: self)
        
        if range.contains(toIndex) { return }
        
        let removed = self[range]
        self.removeSubrange(range)
        
        if range.upperBound < toIndex + range.count - 1 {
            self.insert(contentsOf: removed, at: toIndex - range.count + 1)
        } else {
            self.insert(contentsOf: removed, at: toIndex)
        }
    }
}

extension Array {
    @discardableResult
    @inlinable public mutating func removeFirst(where condition: (Element) throws -> Bool) rethrows -> Element? {
        for i in 0..<self.count {
            if try condition(self[i]) { return remove(at: i) }
        }
        return nil
    }
}

// MARK: - Equatable Array Extensions
extension Array where Element: Equatable {
    @inlinable @discardableResult public mutating func removeFirst(_ element: Element) -> Element? {
        for index in 0..<count where self[index] == element {
            return remove(at: index)
        }

        return nil
    }
}

extension Sequence where Element: Comparable {
    @inlinable public func max(_ replace: Element) -> Element {  self.max() ?? replace }
    @inlinable public func min(_ replace: Element) -> Element { self.min() ?? replace }
}

extension Dictionary {
    public mutating func arrayAppend<T>(_ value: T, forKey key: Key) where Self.Value == Array<T> {
        if self[key] == nil { self[key] = [] }
        self[key]!.append(value)
    }
    public mutating func arrayAppend<T, S: Sequence>(contentsOf newElements: S, forKey key: Key) where Self.Value == Array<T>, S.Element == T {
        if self[key] == nil { self[key] = [] }
        self[key]!.append(contentsOf: newElements)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Swift/Ex+Clamp.swift
================================================
//
//  Ex+Comparable.swift
//  CoreUtil
//
//  Created by yuki on 2020/04/01.
//  Copyright © 2020 yuki. All rights reserved.
//

public func clamp<Target: Comparable>(_ x: Target, into range: ClosedRange<Target>) -> Target {
    max(range.lowerBound, min(x, range.upperBound))
}

public func clamp<Target: Comparable>(_ x: Target, into range: PartialRangeFrom<Target>) -> Target {
    max(range.lowerBound, x)
}

public func clamp<Target: Comparable>(_ x: Target, into range: PartialRangeThrough<Target>) -> Target {
    min(range.upperBound, x)
}

extension Strideable {
    public func clamped(_ range: Range<Self>) -> Self {
        max(range.lowerBound, min(self, range.upperBound.advanced(by: -1)))
    }
}

extension Comparable {
    public func clamped(_ range: ClosedRange<Self>) -> Self {
        clamp(self, into: range)
    }
    public func clamped(_ range: PartialRangeFrom<Self>) -> Self {
        clamp(self, into: range)
    }
    public func clamped(_ range: PartialRangeThrough<Self>) -> Self {
        clamp(self, into: range)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Swift/Ex+Localize.swift
================================================
//
//  Ex+Localize.swift
//  CoreUtil
//
//  Created by yuki on 2022/02/13.
//

import Foundation

extension String {
    public func localized() -> String {
        NSLocalizedString(self, comment: self)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Swift/Ex+Number.swift
================================================
//
//  Ex+NUmber.swift
//  CoreUtil
//
//  Created by yuki on 2020/06/24.
//  Copyright © 2020 yuki. All rights reserved.
//

/// Returns `1` when the value greater than or equals to `0`. And returns `-1` when the value smaller than `0`
@inlinable public func sign<T: SignedNumeric & Comparable>(_ value: T) -> T {
    if value >= T.zero {
        return 1
    } else {
        return -1
    }
}

extension Double {
    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {
        let multiplier = pow(10, Self(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

extension Float {
    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {
        let multiplier = pow(10, Self(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

extension CGFloat {
    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {
        let multiplier = pow(10, Self(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/Swift/Ex+OptionSet.swift
================================================
//
//  Ex+OptionSet.swift
//  CoreUtil
//
//  Created by yuki on 2020/04/13.
//  Copyright © 2020 yuki. All rights reserved.
//

extension OptionSet where RawValue: FixedWidthInteger {
    public static var all: Self { Self(rawValue: RawValue.max) }
    public static var none: Self { [] }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+CALayer.swift
================================================
//
//  Ex+CALayer.swift
//  CoreUtil
//
//  Created by yuki on 2020/06/23.
//  Copyright © 2020 yuki. All rights reserved.
//

import Cocoa

extension CALayer {
    public static func animationDisabled() -> Self {
        let layer = Self.init()
        layer.areAnimationsEnabled = false
        return layer
    }
}

extension CALayer {
    @objc public var areAnimationsEnabled: Bool {
        get { delegate === CALayerAnimationsDisablingDelegate.shared }
        set { delegate = newValue ? nil : CALayerAnimationsDisablingDelegate.shared }
    }
}

private class CALayerAnimationsDisablingDelegate: NSObject, CALayerDelegate {
    public static let shared = CALayerAnimationsDisablingDelegate()
    let null = NSNull()

    func action(for layer: CALayer, forKey event: String) -> CAAction? { null }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+Image.swift
================================================
//
//  Ex+Image.swift
//  CoreUtil
//
//  Created by yuki on 2020/03/10.
//  Copyright © 2020 yuki. All rights reserved.
//

import Cocoa

extension NSImage {
    public var cgImage: CGImage? {
        var imageRect = CGRect(size: self.size)
        return cgImage(forProposedRect: &imageRect, context: nil, hints: nil)
    }
}


extension CGImage {
    public func convertToGrayscale() -> CGImage {
        let imageRect = CGRect(size: CGSize(width: width, height: height))
        let context = CGContext(
            data: nil, width: self.width, height: self.height,
            bitsPerComponent: 8, bytesPerRow: 0,
            space: CGColorSpaceCreateDeviceGray(), bitmapInfo: CGImageAlphaInfo.none.rawValue
        )!
        context.draw(self, in: imageRect)
        return context.makeImage()!
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSColor.swift
================================================
import Cocoa

// MARK: - Extension for Color
extension NSColor {
    public convenience init(colorSpace: NSColorSpace = .current, hex: Int, alpha: CGFloat = 1.0) {
        let red = CGFloat((hex & 0xff_00_00) >> 16) / 255
        let green = CGFloat((hex & 0x00_ff_00) >> 8) / 255
        let blue = CGFloat((hex & 0x00_00_ff) >> 0) / 255

        self.init(colorSpace: colorSpace, red: red, green: green, blue: blue, alpha: alpha)
    }

    public convenience init(colorSpace: NSColorSpace = .current, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var rgba = [red, green, blue, alpha]
        self.init(colorSpace: colorSpace, components: &rgba, count: rgba.count)
    }
}

extension NSColorSpace {
    public static let current: NSColorSpace = NSScreen.main?.colorSpace ?? NSColorSpace.deviceRGB
}

extension CGColorSpace {
    public static let current: CGColorSpace = NSColorSpace.current.cgColorSpace ?? CGColorSpaceCreateDeviceRGB()
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSControl.swift
================================================
//
//  Ex+NSControl.swift
//  CoreUtil
//
//  Created by yuki on 2021/10/28.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa

extension NSControl {
    public func setTarget(_ target: AnyObject, action: Selector) {
        self.target = target
        self.action = action
    }
    
    public func executeAction() {
        guard let object = (target as? NSObject), let action = self.action else { return NSSound.beep() }
        
        if object.responds(to: action) {
            object.perform(action, with: self)
        }
    }
}



================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSEdgeInsets.swift
================================================
//
//  Ex+NSEdgeInsets.swift
//  CoreUtil
//
//  Created by yuki on 2022/01/29.
//

import Cocoa

extension NSEdgeInsets: Equatable {
    public static let zero = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    
    public static func == (lhs: NSEdgeInsets, rhs: NSEdgeInsets) -> Bool {
        lhs.top == rhs.top && lhs.left == rhs.left && lhs.bottom == rhs.bottom && lhs.right == rhs.right
    }
    
    public static func each(top: CGFloat = 0, left: CGFloat = 0, bottom: CGFloat = 0, right: CGFloat = 0) -> NSEdgeInsets {
        NSEdgeInsets(top: top, left: left, bottom: bottom, right: right)
    }
    
    public init(repeating element: CGFloat) {
        self.init(top: element, left: element, bottom: element, right: element)
    }
    
    public init(x: CGFloat=0, y: CGFloat=0) {
        self.init(top: y, left: x, bottom: y, right: x)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSEvent.swift
================================================
//
//  NSEvent+Location.swift
//  CoreUtil
//
//  Created by yuki on 2021/11/11.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa

extension NSEvent {
    @inlinable public func location(in view: NSView) -> CGPoint {
        view.convert(self.locationInWindow, from: nil)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSMenuItem.swift
================================================
//
//  Ex+NSMenuItem.swift
//  CoreUtil
//
//  Created by yuki on 2020/08/20.
//  Copyright © 2020 yuki. All rights reserved.
//

import Cocoa
import Combine

private var actionHandlerKey = 0
private var actionPublisherKey = 0

extension NSMenuItem {
    public convenience init(title: String, image: NSImage? = nil, isSelected: Bool = false, isEnabled: Bool = true, action: (() -> Void)? = nil) {
        self.init()
        self.title = title
        self.image = image
        self.isSelected = isSelected
        if let action = action { self.setAction(action) } 
    }
    
    public var isSelected: Bool {
        get { self.state == .on } set { self.state = newValue ? .on : .off }
    }
    
    public func setAction(_ block: @escaping () -> ()) {
        self.actionHandler.action = block
    }
    
    private var actionHandler: ActionHandler {
        if let handler = objc_getAssociatedObject(self, &actionHandlerKey) as? ActionHandler { return handler }
        let handler = ActionHandler()
        self.target = handler
        self.action = #selector(ActionHandler.run)
        objc_setAssociatedObject(self, &actionHandlerKey, handler, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return handler
    }
    
    final private class ActionHandler {
        var action: (() -> ())?
        @objc func run(_ sender: Any?) { self.action?() }
    }
}

extension NSMenu {
    public func addItem(title: String, image: NSImage? = nil, isSelected: Bool = false, isEnabled: Bool = true, action: (() -> Void)?) {
        let item = NSMenuItem(title: title, image: image, isSelected: isSelected, isEnabled: isEnabled, action: action)
        self.addItem(item)
    }
}


================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSPopover.swift
================================================
//
//  Ex+NSPopover.swift
//  CoreUtil
//
//  Created by yuki on 2021/05/31.
//  Copyright © 2021 yuki. All rights reserved.
//

import Cocoa
import Combine

extension NSPopover {
    public var willClosePublisher: AnyPublisher<Void, Never> { publisherDelegate.willClosePublisher.eraseToAnyPublisher() }
    public var willShowPublisher: AnyPublisher<Void, Never> { publisherDelegate.willShowPublisher.eraseToAnyPublisher() }
    public var didClosePublisher: AnyPublisher<Void, Never> { publisherDelegate.didClosePublisher.eraseToAnyPublisher() }
    public var didShowPublisher: AnyPublisher<Void, Never> { publisherDelegate.didShowPublisher.eraseToAnyPublisher() }
    public var didDetachPublisher: AnyPublisher<Void, Never> { publisherDelegate.didDetachPublisher.eraseToAnyPublisher() }
    
    private static var delegateKey = 0
    private var publisherDelegate: PublisherDelegate {
        if let delegate = objc_getAssociatedObject(self, &Self.delegateKey) as? PublisherDelegate { return delegate }
        
        let delegate = PublisherDelegate()
        self.delegate = delegate
        objc_setAssociatedObject(self, &Self.delegateKey, delegate, .OBJC_ASSOCIATION_RETAIN)
        return delegate
    }
    
    final private class PublisherDelegate: NSObject, NSPopoverDelegate {
        let willClosePublisher = PassthroughSubject<Void, Never>()
        let willShowPublisher = PassthroughSubject<Void, Never>()
        let didClosePublisher = PassthroughSubject<Void, Never>()
        let didShowPublisher = PassthroughSubject<Void, Never>()
        let didDetachPublisher = PassthroughSubject<Void, Never>()
        
        func popoverWillClose(_ notification: Notification) { willClosePublisher.send() }
        func popoverWillShow(_ notification: Notification) { willShowPublisher.send() }
        func popoverDidDetach(_ popover: NSPopover) { didDetachPublisher.send() }
        func popoverDidShow(_ notification: Notification) { didShowPublisher.send() }
        func popoverDidClose(_ notification: Notification) { didClosePublisher.send() }
    }
}



================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+NSTableView.swift
================================================
//
//  Ex+NSTableView.swift
//  CoreUtil
//
//  Created by yuki on 2022/01/29.
//

import Cocoa

extension NSTableView {
    public static let listColumnIdentifier = NSUserInterfaceItemIdentifier("$_column")
        
    public func becomeListStyle() {
        let column = NSTableColumn(identifier: Self.listColumnIdentifier)
        column.resizingMask = .autoresizingMask

        // column
        self.addTableColumn(column)
        self.columnAutoresizingStyle = .firstColumnOnlyAutoresizingStyle
        self.allowsColumnResizing = false
        self.allowsColumnSelection = false

        // appearance
        self.headerView = nil
        self.intercellSpacing = .zero
        self.focusRingType = .none

        // behavior
        self.allowsEmptySelection = true
        self.allowsMultipleSelection = false
        self.backgroundColor = .clear
        
        if #available(OSX 11.0, *) { self.style = .plain }
    }
    
    /// 1コラムのみのTableView
    public static func list() -> Self {
        let tableView = Self()
        tableView.becomeListStyle()
        return tableView
    }
}



================================================
FILE: CoreUtil/CoreUtil/Extensions/UI/Ex+UI.swift
================================================
import Cocoa

public let NSOutlineViewNotificationItemKey = "NSObject"

extension NSView {
    #if DEBUG
    public func __setBackgroundColor(_ color: NSColor) {
        self.wantsLayer = true
        self.layer?.backgroundColor = color.cgColor
    }
    #endif
}


================================================
FILE: CoreUtil/CoreUtil/HotKey/HotKey.swift
================================================
//
//  KeyboardShortcut.swift
//  ListView
//
//  Created by yuki on 2021/06/28.
//

import Carbon
import Cocoa

public struct HotKey: Hashable {
    public let key: Key?
    public let modifiers: NSEvent.ModifierFlags
    
    public init(_ key: Key?, _ modifiers: NSEvent.ModifierFlags = []) {
        self.key = key
        self.modifiers = modifiers
    }
}

extension HotKey {
    public static let open = HotKey(.o, .command)
    public static let copy = HotKey(.c, .command)
    public static let paste = HotKey(.v, .command)
    public static let cut = HotKey(.x, .command)
    public static let duplicate = HotKey(.d, .command)
    public static let save = HotKey(.s, .command)
    public static let undo = HotKey(.z, .command)
    public static let selectAll = HotKey(.a, .command)
    public static let redo = HotKey(.z, [.command, .shift])
    public static let go = HotKey(.rightBracket, .command)
    public static let back = HotKey(.leftBracket, .command)
    public static let print = HotKey(.p, .command)
    public static let delete = HotKey(.delete)
    public static let tab = HotKey(.tab)
    public static let backtab = HotKey(.tab, .shift)
    public static let escape = HotKey(.escape)
    public static let enter = HotKey(.keypadEnter)
    public static let space = HotKey(.space)
    public static let `return` = HotKey(.return)
    public static let leftArrow = HotKey(.leftArrow, [.numericPad, .function])
    public static let rightArrow = HotKey(.rightArrow, [.numericPad, .function])
    public static let upArrow = HotKey(.upArrow, [.numericPad, .function])
    public static let downArrow = HotKey(.downArrow, [.numericPad, .function])
    public static let leftShiftArrow = HotKey(.leftArrow, [.numericPad, .function, .shift])
    public static let rightShiftArrow = HotKey(.rightArrow, [.numericPad, .function, .shift])
    public static let upShiftArrow = HotKey(.upArrow, [.numericPad, .function, .shift])
    public static let downShiftArrow = HotKey(.downArrow, [.numericPad, .function, .shift])
}

extension HotKey: CustomStringConvertible {
    public var description: String {
        var output = modifiers.description
        if let key = key {
            output += key.description
        }
        return output
    }
}

extension NSEvent.ModifierFlags: Hashable {
    public func hash(into hasher: inout Hasher) {
        hasher.combine(rawValue)
    }
}


================================================
FILE: CoreUtil/CoreUtil/HotKey/Key.swift
================================================
//
//  Key.swift
//  ListView
//
//  Created by yuki on 2021/06/28.
//

import Carbon

public enum Key {
    // MARK: - Letters -
    case a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z

    // MARK: - Numbers -
    case zero, one, two, three, four, five, six, seven, eight, nine

    // MARK: - Symbols -
    case period, quote, rightBracket, semicolon, slash, backslash, comma, equal, grave, leftBracket, minus

    // MARK: - White Spaces -
    case space, tab, `return`

    // MARK: - Modifiers -
    case command, rightCommand, option, rightOption, control, rightControl, shift, rightShift, function, capsLock

    // MARK: - Navigation
    case pageUp, pageDown, home, end, upArrow, rightArrow, downArrow, leftArrow

    // MARK: - Functions
    case f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20

    // MARK: - Keypad
    case keypad0, keypad1, keypad2, keypad3, keypad4, keypad5, keypad6, keypad7, keypad8, keypad9, keypadClear, keypadDecimal, keypadDivide, keypadEnter, keypadEquals, keypadMinus, keypadMultiply, keypadPlus

    // MARK: - Misc
    case escape, delete, forwardDelete, help, volumeUp, volumeDown, mute

    public init?(keyCode: Int) {
        switch keyCode {
        case kVK_ANSI_A: self = .a
        case kVK_ANSI_S: self = .s
        case kVK_ANSI_D: self = .d
        case kVK_ANSI_F: self = .f
        case kVK_ANSI_H: self = .h
        case kVK_ANSI_G: self = .g
        case kVK_ANSI_Z: self = .z
        case kVK_ANSI_X: self = .x
        case kVK_ANSI_C: self = .c
        case kVK_ANSI_V: self = .v
        case kVK_ANSI_B: self = .b
        case kVK_ANSI_Q: self = .q
        case kVK_ANSI_W: self = .w
        case kVK_ANSI_E: self = .e
        case kVK_ANSI_R: self = .r
        case kVK_ANSI_Y: self = .y
        case kVK_ANSI_T: self = .t
        case kVK_ANSI_1: self = .one
        case kVK_ANSI_2: self = .two
        case kVK_ANSI_3: self = .three
        case kVK_ANSI_4: self = .four
        case kVK_ANSI_6: self = .six
        case kVK_ANSI_5: self = .five
        case kVK_ANSI_Equal: self = .equal
        case kVK_ANSI_9: self = .nine
        case kVK_ANSI_7: self = .seven
        case kVK_ANSI_Minus: self = .minus
        case kVK_ANSI_8: self = .eight
        case kVK_ANSI_0: self = .zero
        case kVK_ANSI_RightBracket: self = .rightBracket
        case kVK_ANSI_O: self = .o
        case kVK_ANSI_U: self = .u
        case kVK_ANSI_LeftBracket: self = .leftBracket
        case kVK_ANSI_I: self = .i
        case kVK_ANSI_P: self = .p
        case kVK_ANSI_L: self = .l
        case kVK_ANSI_J: self = .j
        case kVK_ANSI_Quote: self = .quote
        case kVK_ANSI_K: self = .k
        case kVK_ANSI_Semicolon: self = .semicolon
        case kVK_ANSI_Backslash: self = .backslash
        case kVK_ANSI_Comma: self = .comma
        case kVK_ANSI_Slash: self = .slash
        case kVK_ANSI_N: self = .n
        case kVK_ANSI_M: self = .m
        case kVK_ANSI_Period: self = .period
        case kVK_ANSI_Grave: self = .grave
        case kVK_ANSI_KeypadDecimal: self = .keypadDecimal
        case kVK_ANSI_KeypadMultiply: self = .keypadMultiply
        case kVK_ANSI_KeypadPlus: self = .keypadPlus
        case kVK_ANSI_KeypadClear: self = .keypadClear
        case kVK_ANSI_KeypadDivide: self = .keypadDivide
        case kVK_ANSI_KeypadEnter: self = .keypadEnter
        case kVK_ANSI_KeypadMinus: self = .keypadMinus
        case kVK_ANSI_KeypadEquals: self = .keypadEquals
        case kVK_ANSI_Keypad0: self = .keypad0
        case kVK_ANSI_Keypad1: self = .keypad1
        case kVK_ANSI_Keypad2: self = .keypad2
        case kVK_ANSI_Keypad3: self = .keypad3
        case kVK_ANSI_Keypad4: self = .keypad4
        case kVK_ANSI_Keypad5: self = .keypad5
        case kVK_ANSI_Keypad6: self = .keypad6
        case kVK_ANSI_Keypad7: self = .keypad7
        case kVK_ANSI_Keypad8: self = .keypad8
        case kVK_ANSI_Keypad9: self = .keypad9
        case kVK_Return: self = .`return`
        case kVK_Tab: self = .tab
        case kVK_Space: self = .space
        case kVK_Delete: self = .delete
        case kVK_Escape: self = .escape
        case kVK_Command: self = .command
        case kVK_Shift: self = .shift
        case kVK_CapsLock: self = .capsLock
        case kVK_Option: self = .option
        case kVK_Control: self = .control
        case kVK_RightCommand: self = .rightCommand
        case kVK_RightShift: self = .rightShift
        case kVK_RightOption: self = .rightOption
        case kVK_RightControl: self = .rightControl
        case kVK_Function: self = .function
        case kVK_F17: self = .f17
        case kVK_VolumeUp: self = .volumeUp
        case kVK_VolumeDown: self = .volumeDown
        case kVK_Mute: self = .mute
        case kVK_F18: self = .f18
        case kVK_F19: self = .f19
        case kVK_F20: self = .f20
        case kVK_F5: self = .f5
        case kVK_F6: self = .f6
        case kVK_F7: self = .f7
        case kVK_F3: self = .f3
        case kVK_F8: self = .f8
        case kVK_F9: self = .f9
        case kVK_F11: self = .f11
        case kVK_F13: self = .f13
        case kVK_F16: self = .f16
        case kVK_F14: self = .f14
        case kVK_F10: self = .f10
        case kVK_F12: self = .f12
        case kVK_F15: self = .f15
        case kVK_Help: self = .help
        case kVK_Home: self = .home
        case kVK_PageUp: self = .pageUp
        case kVK_ForwardDelete: self = .forwardDelete
        case kVK_F4: self = .f4
        case kVK_End: self = .end
        case kVK_F2: self = .f2
        case kVK_PageDown: self = .pageDown
        case kVK_F1: self = .f1
        case kVK_LeftArrow: self = .leftArrow
        case kVK_RightArrow: self = .rightArrow
        case kVK_DownArrow: self = .downArrow
        case kVK_UpArrow: self = .upArrow
        default: return nil
        }
    }
    
    public var keyCode: Int {
        switch self {
        case .a: return kVK_ANSI_A
        case .s: return kVK_ANSI_S
        case .d: return kVK_ANSI_D
        case .f: return kVK_ANSI_F
        case .h: return kVK_ANSI_H
        case .g: return kVK_ANSI_G
        case .z: return kVK_ANSI_Z
        case .x: return kVK_ANSI_X
        case .c: return kVK_ANSI_C
        case .v: return kVK_ANSI_V
        case .b: return kVK_ANSI_B
        case .q: return kVK_ANSI_Q
        case .w: return kVK_ANSI_W
        case .e: return kVK_ANSI_E
        case .r: return kVK_ANSI_R
        case .y: return kVK_ANSI_Y
        case .t: return kVK_ANSI_T
        case .one: return kVK_ANSI_1
        case .two: return kVK_ANSI_2
        case .three: return kVK_ANSI_3
        case .four: return kVK_ANSI_4
        case .six: return kVK_ANSI_6
        case .five: return kVK_ANSI_5
        case .equal: return kVK_ANSI_Equal
        case .nine: return kVK_ANSI_9
        case .seven: return kVK_ANSI_7
        case .minus: return kVK_ANSI_Minus
        case .eight: return kVK_ANSI_8
        case .zero: return kVK_ANSI_0
        case .rightBracket: return kVK_ANSI_RightBracket
        case .o: return kVK_ANSI_O
        case .u: return kVK_ANSI_U
        case .leftBracket: return kVK_ANSI_LeftBracket
        case .i: return kVK_ANSI_I
        case .p: return kVK_ANSI_P
        case .l: return kVK_ANSI_L
        case .j: return kVK_ANSI_J
        case .quote: return kVK_ANSI_Quote
        case .k: return kVK_ANSI_K
        case .semicolon: return kVK_ANSI_Semicolon
        case .backslash: return kVK_ANSI_Backslash
        case .comma: return kVK_ANSI_Comma
        case .slash: return kVK_ANSI_Slash
        case .n: return kVK_ANSI_N
        case .m: return kVK_ANSI_M
        case .period: return kVK_ANSI_Period
        case .grave: return kVK_ANSI_Grave
        case .keypadDecimal: return kVK_ANSI_KeypadDecimal
        case .keypadMultiply: return kVK_ANSI_KeypadMultiply
        case .keypadPlus: return kVK_ANSI_KeypadPlus
        case .keypadClear: return kVK_ANSI_KeypadClear
        case .keypadDivide: return kVK_ANSI_KeypadDivide
        case .keypadEnter: return kVK_ANSI_KeypadEnter
        case .keypadMinus: return kVK_ANSI_KeypadMinus
        case .keypadEquals: return kVK_ANSI_KeypadEquals
        case .keypad0: return kVK_ANSI_Keypad0
        case .keypad1: return kVK_ANSI_Keypad1
        case .keypad2: return kVK_ANSI_Keypad2
        case .keypad3: return kVK_ANSI_Keypad3
        case .keypad4: return kVK_ANSI_Keypad4
        case .keypad5: return kVK_ANSI_Keypad5
        case .keypad6: return kVK_ANSI_Keypad6
        case .keypad7: return kVK_ANSI_Keypad7
        case .keypad8: return kVK_ANSI_Keypad8
        case .keypad9: return kVK_ANSI_Keypad9
        case .`return`: return kVK_Return
        case .tab: return kVK_Tab
        case .space: return kVK_Space
        case .delete: return kVK_Delete
        case .escape: return kVK_Escape
        case .command: return kVK_Command
        case .shift: return kVK_Shift
        case .capsLock: return kVK_CapsLock
        case .option: return kVK_Option
        case .control: return kVK_Control
        case .rightCommand: return kVK_RightCommand
        case .rightShift: return kVK_RightShift
        case .rightOption: return kVK_RightOption
        case .rightControl: return kVK_RightControl
        case .function: return kVK_Function
        case .f17: return kVK_F17
        case .volumeUp: return kVK_VolumeUp
        case .volumeDown: return kVK_VolumeDown
        case .mute: return kVK_Mute
        case .f18: return kVK_F18
        case .f19: return kVK_F19
        case .f20: return kVK_F20
        case .f5: return kVK_F5
        case .f6: return kVK_F6
        case .f7: return kVK_F7
        case .f3: return kVK_F3
        case .f8: return kVK_F8
        case .f9: return kVK_F9
        case .f11: return kVK_F11
        case .f13: return kVK_F13
        case .f16: return kVK_F16
        case .f14: return kVK_F14
        case .f10: return kVK_F10
        case .f12: return kVK_F12
        case .f15: return kVK_F15
        case .help: return kVK_Help
        case .home: return kVK_Home
        case .pageUp: return kVK_PageUp
        case .forwardDelete: return kVK_ForwardDelete
        case .f4: return kVK_F4
        case .end: return kVK_End
        case .f2: return kVK_F2
        case .pageDown: return kVK_PageDown
        case .f1: return kVK_F1
        case .leftArrow: return kVK_LeftArrow
        case .rightArrow: return kVK_RightArrow
        case .downArrow: return kVK_DownArrow
        case .upArrow: return kVK_UpArrow
        }
    }
}

extension Key: CustomStringConvertible {
    public var description: String {
        switch  self {
        case .a: return "A"
        case .s: return "S"
        case .d: return "D"
        case .f: return "F"
        case .h: return "H"
        case .g: return "G"
        case .z: return "Z"
        case .x: return "X"
        case .c: return "C"
        case .v: return "V"
        case .b: return "B"
        case .q: return "Q"
        case .w: return "W"
        case .e: return "E"
        case .r: return "R"
        case .y: return "Y"
        case .t: return "T"
        case .one, .keypad1: return "1"
        case .two, .keypad2: return "2"
        case .three, .keypad3: return "3"
        case .four, .keypad4: return "4"
        case .six, .keypad6: return "6"
        case .five, .keypad5: return "5"
        case .equal: return "="
        case .nine, .keypad9: return "9"
        case .seven, .keypad7: return "7"
        case .minus: return "-"
        case .eight, .keypad8: return "8"
        case .zero, .keypad0: return "0"
        case .rightBracket: return "]"
        case .o: return "O"
        case .u: return "U"
        case .leftBracket: return "["
        case .i: return "I"
        case .p: return "P"
        case .l: return "L"
        case .j: return "J"
        case .quote: return "\""
        case .k: return "K"
        case .semicolon: return ";"
        case .backslash: return "\\"
        case .comma: return ","
        case .slash: return "/"
        case .n: return "N"
        case .m: return "M"
        case .period: return "."
        case .grave: return "`"
        case .keypadDecimal: return "."
        case .keypadMultiply: return "𝗑"
        case .keypadPlus: return "+"
        case .keypadClear: return "⌧"
        case .keypadDivide: return "/"
        case .keypadEnter: return "↩︎"
        case .keypadMinus: return "-"
        case .keypadEquals: return "="
        case .`return`: return "↩︎"
        case .tab: return "⇥"
        case .space: return "␣"
        case .delete: return "⌫"
        case .escape: return "⎋"
        case .command, .rightCommand: return "⌘"
        case .shift, .rightShift: return "⇧"
        case .capsLock: return "⇪"
        case .option, .rightOption: return "⌥"
        case .control, .rightControl: return "⌃"
        case .function: return "fn"
        case .f17: return "F17"
        case .volumeUp: return "🔊"
        case .volumeDown: return "🔉"
        case .mute: return "🔇"
        case .f18: return "F18"
        case .f19: return "F19"
        case .f20: return "F20"
        case .f5: return "F5"
        case .f6: return "F6"
        case .f7: return "F7"
        case .f3: return "F3"
        case .f8: return "F8"
        case .f9: return "F9"
        case .f11: return "F11"
        case .f13: return "F13"
        case .f16: return "F16"
        case .f14: return "F14"
        case .f10: return "F10"
        case .f12: return "F12"
        case .f15: return "F15"
        case .help: return "?⃝"
        case .home: return "↖"
        case .pageUp: return "⇞"
        case .forwardDelete: return "⌦"
        case .f4: return "F4"
        case .end: return "↘"
        case .f2: return "F2"
        case .pageDown: return "⇟"
        case .f1: return "F1"
        case .leftArrow: return "←"
        case .rightArrow: return "→"
        case .downArrow: return "↓"
        case .upArrow: return "↑"
        }
    }
}



================================================
FILE: CoreUtil/CoreUtil/HotKey/NSEvent+HotKey.swift
================================================
//
//  NSEvent+HotKey.swift
//  ListView
//
//  Created by yuki on 2021/06/28.
//

import Cocoa

extension NSEvent {
    public var hotKey: HotKey {
        HotKey(Key(keyCode: Int(self.keyCode)), self.modifierFlags.intersection(.deviceIndependentFlagsMask))
    }
}

extension NSEvent.ModifierFlags: CustomStringConvertible {
    public var description: String {
        var output = ""
        
        if self.contains(.capsLock) { output += Key.capsLock.description }
        if self.contains(.shift) { output += Key.shift.description }
        if self.contains(.control) { output += Key.control.description }
        if self.contains(.option) { output += Key.option.description }
        if self.contains(.command) { output += Key.command.description }
        if self.contains(.numericPad) { output += "Np" }
        if self.contains(.help) { output += Key.help.description }
        if self.contains(.function) { output += Key.function.description }

        return output
    }
}




================================================
FILE: CoreUtil/CoreUtil/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>


================================================
FILE: CoreUtil/CoreUtil.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 52;
	objects = {

/* Begin PBXBuildFile section */
		B608540827A66635003BF243 /* NSControl+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608540727A66635003BF243 /* NSControl+Combine.swift */; };
		B62013E927A9147600AF5386 /* Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62013E827A9147600AF5386 /* Delta.swift */; };
		B64B1E9427A4F67000AC2601 /* CoreUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B64B1E9227A4F67000AC2601 /* CoreUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
		B64B1ED027A4F71200AC2601 /* ViewPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */; };
		B64B1ED327A4F71F00AC2601 /* NS+OnAwake.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */; };
		B64B1ED627A4F72D00AC2601 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED527A4F72D00AC2601 /* Query.swift */; };
		B64B1ED927A4F73700AC2601 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED827A4F73700AC2601 /* Observable.swift */; };
		B64B1EDC27A4F75600AC2601 /* PipeOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EDB27A4F75600AC2601 /* PipeOperator.swift */; };
		B64B1EE327A4F79100AC2601 /* NSEvent+HotKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */; };
		B64B1EE427A4F79100AC2601 /* Key.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE127A4F79100AC2601 /* Key.swift */; };
		B64B1EE527A4F79100AC2601 /* HotKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE227A4F79100AC2601 /* HotKey.swift */; };
		B64B1EF727A4F7AA00AC2601 /* Ex+Number.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */; };
		B64B1EFA27A4F7AA00AC2601 /* Ex+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */; };
		B64B1F0027A4F7AA00AC2601 /* Ex+OptionSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */; };
		B64B1F0127A4F7AA00AC2601 /* Ex+Clamp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */; };
		B64B1F1627A4F80800AC2601 /* Ex+CGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */; };
		B64B1F1827A4F80800AC2601 /* Ex+CGPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */; };
		B64B1F1A27A4F80800AC2601 /* Ex+CGRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */; };
		B64B1F2B27A4F83500AC2601 /* Ex+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1F27A4F83500AC2601 /* Ex+UI.swift */; };
		B64B1F2E27A4F83500AC2601 /* Ex+NSControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */; };
		B64B1F3027A4F83500AC2601 /* Ex+NSPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */; };
		B64B1F3127A4F83500AC2601 /* Ex+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2527A4F83500AC2601 /* Ex+Image.swift */; };
		B64B1F3327A4F83500AC2601 /* Ex+NSEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */; };
		B64B1F3427A4F83500AC2601 /* Ex+NSMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */; };
		B64B1F3627A4F83500AC2601 /* Ex+NSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */; };
		B64B1F3927A4F8AD00AC2601 /* Ex+NSTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */; };
		B64B1F3C27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */; };
		B64B1F6327A4FC5100AC2601 /* Promise in Frameworks */ = {isa = PBXBuildFile; productRef = B64B1F6227A4FC5100AC2601 /* Promise */; };
		B64B1F6827A4FC8A00AC2601 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = B64B1F6727A4FC8A00AC2601 /* SnapKit */; };
		B64B1F6B27A4FC8F00AC2601 /* Export.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F6A27A4FC8F00AC2601 /* Export.swift */; };
		B64B201127A50E5200AC2601 /* NSColorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201027A50E5200AC2601 /* NSColorView.swift */; };
		B64B201A27A5103100AC2601 /* Ex+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201927A5103100AC2601 /* Ex+CALayer.swift */; };
		B64B205927A530D700AC2601 /* NSViewController+ChainObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */; };
		B64B205C27A530E800AC2601 /* NSViewController+StateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */; };
		B64B209527A5323A00AC2601 /* Combine+ObjectBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */; };
		B66F0D4C27B6176A00DC812D /* Terminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66F0D4B27B6176A00DC812D /* Terminal.swift */; };
		B680A79127A681F8007CB707 /* NSTextField+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A79027A681F8007CB707 /* NSTextField+Combine.swift */; };
		B680A86527A8C58C007CB707 /* Combine+Peek.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A86427A8C58C007CB707 /* Combine+Peek.swift */; };
		B680A89C27A8DA16007CB707 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A89B27A8DA16007CB707 /* Action.swift */; };
		B680A8A027A8DA78007CB707 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = B680A89F27A8DA78007CB707 /* OrderedCollections */; };
		B680A8A227A8DA78007CB707 /* DequeModule in Frameworks */ = {isa = PBXBuildFile; productRef = B680A8A127A8DA78007CB707 /* DequeModule */; };
		B680A8A427A8DA78007CB707 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = B680A8A327A8DA78007CB707 /* Collections */; };
		B6A93D2B27CBA2EB003A6D7F /* Zip3Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */; };
		B6AC27A327AA6F5C000FD713 /* Reachability+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */; };
		B6AC27A427AA6F5C000FD713 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC27A227AA6F5C000FD713 /* Reachability.swift */; };
		B6B5727A27AC223A0069DBA7 /* RestorableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5727927AC223A0069DBA7 /* RestorableState.swift */; };
		B6B5727D27AC22480069DBA7 /* RestorableData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5727C27AC22480069DBA7 /* RestorableData.swift */; };
		B6BD80FA27B8B06900152AB9 /* Ex+Localize.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BD80F927B8B06900152AB9 /* Ex+Localize.swift */; };
		B6D1AF3D27A60A210022FED2 /* ExceptionHanlder.m in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */; };
		B6D1AF3E27A60A210022FED2 /* ExceptionHanlder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */; settings = {ATTRIBUTES = (Public, ); }; };
		B6D1AF3F27A60A210022FED2 /* ExceptionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		B608540727A66635003BF243 /* NSControl+Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSControl+Combine.swift"; sourceTree = "<group>"; };
		B62013E827A9147600AF5386 /* Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delta.swift; sourceTree = "<group>"; };
		B64B1E8F27A4F67000AC2601 /* CoreUtil.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreUtil.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		B64B1E9227A4F67000AC2601 /* CoreUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreUtil.h; sourceTree = "<group>"; };
		B64B1E9327A4F67000AC2601 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		B64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewPlaceholder.swift; sourceTree = "<group>"; };
		B64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NS+OnAwake.swift"; sourceTree = "<group>"; };
		B64B1ED527A4F72D00AC2601 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = "<group>"; };
		B64B1ED827A4F73700AC2601 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
		B64B1EDB27A4F75600AC2601 /* PipeOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PipeOperator.swift; sourceTree = "<group>"; };
		B64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSEvent+HotKey.swift"; sourceTree = "<group>"; };
		B64B1EE127A4F79100AC2601 /* Key.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Key.swift; sourceTree = "<group>"; };
		B64B1EE227A4F79100AC2601 /* HotKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HotKey.swift; sourceTree = "<group>"; };
		B64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+Number.swift"; sourceTree = "<group>"; };
		B64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+Array.swift"; sourceTree = "<group>"; };
		B64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+OptionSet.swift"; sourceTree = "<group>"; };
		B64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+Clamp.swift"; sourceTree = "<group>"; };
		B64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+CGSize.swift"; sourceTree = "<group>"; };
		B64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+CGPoint.swift"; sourceTree = "<group>"; };
		B64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+CGRect.swift"; sourceTree = "<group>"; };
		B64B1F1F27A4F83500AC2601 /* Ex+UI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+UI.swift"; sourceTree = "<group>"; };
		B64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+NSControl.swift"; sourceTree = "<group>"; };
		B64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+NSPopover.swift"; sourceTree = "<group>"; };
		B64B1F2527A4F83500AC2601 /* Ex+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+Image.swift"; sourceTree = "<group>"; };
		B64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+NSEvent.swift"; sourceTree = "<group>"; };
		B64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+NSMenuItem.swift"; sourceTree = "<group>"; };
		B64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+NSColor.swift"; sourceTree = "<group>"; };
		B64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ex+NSTableView.swift"; sourceTree = "<group>"; };
		B64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ex+NSEdgeInsets.swift"; sourceTree = "<group>"; };
		B64B1F6A27A4FC8F00AC2601 /* Export.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Export.swift; sourceTree = "<group>"; };
		B64B201027A50E5200AC2601 /* NSColorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSColorView.swift; sourceTree = "<group>"; };
		B64B201927A5103100AC2601 /* Ex+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Ex+CALayer.swift"; sourceTree = "<group>"; };
		B64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSViewController+ChainObject.swift"; sourceTree = "<group>"; };
		B64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSViewController+StateObject.swift"; sourceTree = "<group>"; };
		B64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Combine+ObjectBag.swift"; sourceTree = "<group>"; };
		B66F0D4B27B6176A00DC812D /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terminal.swift; sourceTree = "<group>"; };
		B680A79027A681F8007CB707 /* NSTextField+Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextField+Combine.swift"; sourceTree = "<group>"; };
		B680A86427A8C58C007CB707 /* Combine+Peek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Combine+Peek.swift"; sourceTree = "<group>"; };
		B680A89B27A8DA16007CB707 /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = "<group>"; };
		B6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zip3Sequence.swift; sourceTree = "<group>"; };
		B6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reachability+Publisher.swift"; sourceTree = "<group>"; };
		B6AC27A227AA6F5C000FD713 /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = "<group>"; };
		B6B5727927AC223A0069DBA7 /* RestorableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorableState.swift; sourceTree = "<group>"; };
		B6B5727C27AC22480069DBA7 /* RestorableData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorableData.swift; sourceTree = "<group>"; };
		B6BD80F927B8B06900152AB9 /* Ex+Localize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ex+Localize.swift"; sourceTree = "<group>"; };
		B6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExceptionHanlder.m; sourceTree = "<group>"; };
		B6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHanlder.h; sourceTree = "<group>"; };
		B6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExceptionHandler.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		B64B1E8C27A4F67000AC2601 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B64B1F6327A4FC5100AC2601 /* Promise in Frameworks */,
				B680A8A227A8DA78007CB707 /* DequeModule in Frameworks */,
				B680A8A427A8DA78007CB707 /* Collections in Frameworks */,
				B64B1F6827A4FC8A00AC2601 /* SnapKit in Frameworks */,
				B680A8A027A8DA78007CB707 /* OrderedCollections in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		B64B1E8527A4F67000AC2601 = {
			isa = PBXGroup;
			children = (
				B64B1E9127A4F67000AC2601 /* CoreUtil */,
				B64B1E9027A4F67000AC2601 /* Products */,
			);
			sourceTree = "<group>";
		};
		B64B1E9027A4F67000AC2601 /* Products */ = {
			isa = PBXGroup;
			children = (
				B64B1E8F27A4F67000AC2601 /* CoreUtil.framework */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		B64B1E9127A4F67000AC2601 /* CoreUtil */ = {
			isa = PBXGroup;
			children = (
				B64B1E9227A4F67000AC2601 /* CoreUtil.h */,
				B64B1E9327A4F67000AC2601 /* Info.plist */,
				B64B1F6A27A4FC8F00AC2601 /* Export.swift */,
				B6D1AF3927A60A210022FED2 /* ExceptionHanlder */,
				B64B1F6D27A4FC9100AC2601 /* Class */,
				B64B1EE727A4F79800AC2601 /* Extensions */,
				B64B1EDF27A4F79100AC2601 /* HotKey */,
			);
			path = CoreUtil;
			sourceTree = "<group>";
		};
		B64B1EDF27A4F79100AC2601 /* HotKey */ = {
			isa = PBXGroup;
			children = (
				B64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */,
				B64B1EE127A4F79100AC2601 /* Key.swift */,
				B64B1EE227A4F79100AC2601 /* HotKey.swift */,
			);
			path = HotKey;
			sourceTree = "<group>";
		};
		B64B1EE727A4F79800AC2601 /* Extensions */ = {
			isa = PBXGroup;
			children = (
				B64B208E27A5322A00AC2601 /* Combine */,
				B64B1F1E27A4F83500AC2601 /* UI */,
				B64B1F1027A4F80800AC2601 /* CoreGraphics */,
				B64B1EE827A4F7AA00AC2601 /* Swift */,
			);
			path = Extensions;
			sourceTree = "<group>";
		};
		B64B1EE827A4F7AA00AC2601 /* Swift */ = {
			isa = PBXGroup;
			children = (
				B64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */,
				B64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */,
				B64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */,
				B64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */,
				B6BD80F927B8B06900152AB9 /* Ex+Localize.swift */,
			);
			path = Swift;
			sourceTree = "<group>";
		};
		B64B1F1027A4F80800AC2601 /* CoreGraphics */ = {
			isa = PBXGroup;
			children = (
				B64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */,
				B64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */,
				B64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */,
			);
			path = CoreGraphics;
			sourceTree = "<group>";
		};
		B64B1F1E27A4F83500AC2601 /* UI */ = {
			isa = PBXGroup;
			children = (
				B64B201927A5103100AC2601 /* Ex+CALayer.swift */,
				B64B1F1F27A4F83500AC2601 /* Ex+UI.swift */,
				B64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */,
				B64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */,
				B64B1F2527A4F83500AC2601 /* Ex+Image.swift */,
				B64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */,
				B64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */,
				B64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */,
				B64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */,
				B64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */,
			);
			path = UI;
			sourceTree = "<group>";
		};
		B64B1F6D27A4FC9100AC2601 /* Class */ = {
			isa = PBXGroup;
			children = (
				B6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */,
				B6AC27A227AA6F5C000FD713 /* Reachability.swift */,
				B6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */,
				B64B201027A50E5200AC2601 /* NSColorView.swift */,
				B64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */,
				B64B1ED527A4F72D00AC2601 /* Query.swift */,
				B680A89B27A8DA16007CB707 /* Action.swift */,
				B64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */,
				B64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */,
				B62013E827A9147600AF5386 /* Delta.swift */,
				B64B1ED827A4F73700AC2601 /* Observable.swift */,
				B64B1EDB27A4F75600AC2601 /* PipeOperator.swift */,
				B64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */,
				B6B5727927AC223A0069DBA7 /* RestorableState.swift */,
				B6B5727C27AC22480069DBA7 /* RestorableData.swift */,
				B66F0D4B27B6176A00DC812D /* Terminal.swift */,
			);
			path = Class;
			sourceTree = "<group>";
		};
		B64B208E27A5322A00AC2601 /* Combine */ = {
			isa = PBXGroup;
			children = (
				B608540727A66635003BF243 /* NSControl+Combine.swift */,
				B680A79027A681F8007CB707 /* NSTextField+Combine.swift */,
				B64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */,
				B680A86427A8C58C007CB707 /* Combine+Peek.swift */,
			);
			path = Combine;
			sourceTree = "<group>";
		};
		B6D1AF3927A60A210022FED2 /* ExceptionHanlder */ = {
			isa = PBXGroup;
			children = (
				B6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */,
				B6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */,
				B6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */,
			);
			path = ExceptionHanlder;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
		B64B1E8A27A4F67000AC2601 /* Headers */ = {
			isa = PBXHeadersBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B64B1E9427A4F67000AC2601 /* CoreUtil.h in Headers */,
				B6D1AF3E27A60A210022FED2 /* ExceptionHanlder.h in Headers */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXHeadersBuildPhase section */

/* Begin PBXNativeTarget section */
		B64B1E8E27A4F67000AC2601 /* CoreUtil */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = B64B1E9727A4F67000AC2601 /* Build configuration list for PBXNativeTarget "CoreUtil" */;
			buildPhases = (
				B64B1E8A27A4F67000AC2601 /* Headers */,
				B64B1E8B27A4F67000AC2601 /* Sources */,
				B64B1E8C27A4F67000AC2601 /* Frameworks */,
				B64B1E8D27A4F67000AC2601 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = CoreUtil;
			packageProductDependencies = (
				B64B1F6227A4FC5100AC2601 /* Promise */,
				B64B1F6727A4FC8A00AC2601 /* SnapKit */,
				B680A89F27A8DA78007CB707 /* OrderedCollections */,
				B680A8A127A8DA78007CB707 /* DequeModule */,
				B680A8A327A8DA78007CB707 /* Collections */,
			);
			productName = CoreUtil;
			productReference = B64B1E8F27A4F67000AC2601 /* CoreUtil.framework */;
			productType = "com.apple.product-type.framework";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		B64B1E8627A4F67000AC2601 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 1240;
				TargetAttributes = {
					B64B1E8E27A4F67000AC2601 = {
						CreatedOnToolsVersion = 12.4;
						LastSwiftMigration = 1240;
					};
				};
			};
			buildConfigurationList = B64B1E8927A4F67000AC2601 /* Build configuration list for PBXProject "CoreUtil" */;
			compatibilityVersion = "Xcode 9.3";
			developmentRegion = en;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = B64B1E8527A4F67000AC2601;
			packageReferences = (
				B64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference "Promise" */,
				B64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference "SnapKit" */,
				B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference "swift-collections" */,
			);
			productRefGroup = B64B1E9027A4F67000AC2601 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				B64B1E8E27A4F67000AC2601 /* CoreUtil */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		B64B1E8D27A4F67000AC2601 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		B64B1E8B27A4F67000AC2601 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B6D1AF3D27A60A210022FED2 /* ExceptionHanlder.m in Sources */,
				B680A89C27A8DA16007CB707 /* Action.swift in Sources */,
				B64B1F6B27A4FC8F00AC2601 /* Export.swift in Sources */,
				B64B205C27A530E800AC2601 /* NSViewController+StateObject.swift in Sources */,
				B608540827A66635003BF243 /* NSControl+Combine.swift in Sources */,
				B64B1F3327A4F83500AC2601 /* Ex+NSEvent.swift in Sources */,
				B64B205927A530D700AC2601 /* NSViewController+ChainObject.swift in Sources */,
				B66F0D4C27B6176A00DC812D /* Terminal.swift in Sources */,
				B64B1EE427A4F79100AC2601 /* Key.swift in Sources */,
				B64B1F0027A4F7AA00AC2601 /* Ex+OptionSet.swift in Sources */,
				B6AC27A327AA6F5C000FD713 /* Reachability+Publisher.swift in Sources */,
				B64B1F2E27A4F83500AC2601 /* Ex+NSControl.swift in Sources */,
				B64B1F1627A4F80800AC2601 /* Ex+CGSize.swift in Sources */,
				B6B5727A27AC223A0069DBA7 /* RestorableState.swift in Sources */,
				B64B1ED927A4F73700AC2601 /* Observable.swift in Sources */,
				B64B201127A50E5200AC2601 /* NSColorView.swift in Sources */,
				B64B1EE327A4F79100AC2601 /* NSEvent+HotKey.swift in Sources */,
				B64B201A27A5103100AC2601 /* Ex+CALayer.swift in Sources */,
				B680A79127A681F8007CB707 /* NSTextField+Combine.swift in Sources */,
				B64B1EFA27A4F7AA00AC2601 /* Ex+Array.swift in Sources */,
				B64B1F1A27A4F80800AC2601 /* Ex+CGRect.swift in Sources */,
				B64B1F3C27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift in Sources */,
				B64B1F3427A4F83500AC2601 /* Ex+NSMenuItem.swift in Sources */,
				B64B1F3027A4F83500AC2601 /* Ex+NSPopover.swift in Sources */,
				B64B1EE527A4F79100AC2601 /* HotKey.swift in Sources */,
				B64B1F3627A4F83500AC2601 /* Ex+NSColor.swift in Sources */,
				B64B209527A5323A00AC2601 /* Combine+ObjectBag.swift in Sources */,
				B64B1EDC27A4F75600AC2601 /* PipeOperator.swift in Sources */,
				B6BD80FA27B8B06900152AB9 /* Ex+Localize.swift in Sources */,
				B64B1F1827A4F80800AC2601 /* Ex+CGPoint.swift in Sources */,
				B680A86527A8C58C007CB707 /* Combine+Peek.swift in Sources */,
				B64B1ED027A4F71200AC2601 /* ViewPlaceholder.swift in Sources */,
				B6A93D2B27CBA2EB003A6D7F /* Zip3Sequence.swift in Sources */,
				B64B1F3127A4F83500AC2601 /* Ex+Image.swift in Sources */,
				B64B1ED627A4F72D00AC2601 /* Query.swift in Sources */,
				B64B1F2B27A4F83500AC2601 /* Ex+UI.swift in Sources */,
				B64B1F3927A4F8AD00AC2601 /* Ex+NSTableView.swift in Sources */,
				B64B1F0127A4F7AA00AC2601 /* Ex+Clamp.swift in Sources */,
				B64B1EF727A4F7AA00AC2601 /* Ex+Number.swift in Sources */,
				B62013E927A9147600AF5386 /* Delta.swift in Sources */,
				B6D1AF3F27A60A210022FED2 /* ExceptionHandler.swift in Sources */,
				B64B1ED327A4F71F00AC2601 /* NS+OnAwake.swift in Sources */,
				B6AC27A427AA6F5C000FD713 /* Reachability.swift in Sources */,
				B6B5727D27AC22480069DBA7 /* RestorableData.swift in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		B64B1E9527A4F67000AC2601 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				COPY_PHASE_STRIP = NO;
				CURRENT_PROJECT_VERSION = 1;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 11.1;
				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
				MTL_FAST_MATH = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = macosx;
				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				VERSIONING_SYSTEM = "apple-generic";
				VERSION_INFO_PREFIX = "";
			};
			name = Debug;
		};
		B64B1E9627A4F67000AC2601 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				COPY_PHASE_STRIP = NO;
				CURRENT_PROJECT_VERSION = 1;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 11.1;
				MTL_ENABLE_DEBUG_INFO = NO;
				MTL_FAST_MATH = YES;
				SDKROOT = macosx;
				SWIFT_COMPILATION_MODE = wholemodule;
				SWIFT_OPTIMIZATION_LEVEL = "-O";
				VERSIONING_SYSTEM = "apple-generic";
				VERSION_INFO_PREFIX = "";
			};
			name = Release;
		};
		B64B1E9827A4F67000AC2601 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ENABLE_MODULES = YES;
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				DEFINES_MODULE = YES;
				DEVELOPMENT_TEAM = T5HMUWWK5R;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				DYLIB_INSTALL_NAME_BASE = "@rpath";
				INFOPLIST_FILE = CoreUtil/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/../Frameworks",
					"@loader_path/Frameworks",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.15;
				PRODUCT_BUNDLE_IDENTIFIER = com.yuki.CoreUtil;
				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
				SKIP_INSTALL = YES;
				SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				SWIFT_VERSION = 5.0;
			};
			name = Debug;
		};
		B64B1E9927A4F67000AC2601 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ENABLE_MODULES = YES;
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				DEFINES_MODULE = YES;
				DEVELOPMENT_TEAM = T5HMUWWK5R;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				DYLIB_INSTALL_NAME_BASE = "@rpath";
				INFOPLIST_FILE = CoreUtil/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/../Frameworks",
					"@loader_path/Frameworks",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.15;
				PRODUCT_BUNDLE_IDENTIFIER = com.yuki.CoreUtil;
				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
				SKIP_INSTALL = YES;
				SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;
				SWIFT_VERSION = 5.0;
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		B64B1E8927A4F67000AC2601 /* Build configuration list for PBXProject "CoreUtil" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				B64B1E9527A4F67000AC2601 /* Debug */,
				B64B1E9627A4F67000AC2601 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		B64B1E9727A4F67000AC2601 /* Build configuration list for PBXNativeTarget "CoreUtil" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				B64B1E9827A4F67000AC2601 /* Debug */,
				B64B1E9927A4F67000AC2601 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
		B64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference "Promise" */ = {
			isa = XCRemoteSwiftPackageReference;
			repositoryURL = "https://github.com/ObuchiYuki/Promise.git";
			requirement = {
				kind = upToNextMajorVersion;
				minimumVersion = 1.0.9;
			};
		};
		B64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference "SnapKit" */ = {
			isa = XCRemoteSwiftPackageReference;
			repositoryURL = "https://github.com/SnapKit/SnapKit.git";
			requirement = {
				kind = upToNextMajorVersion;
				minimumVersion = 5.0.1;
			};
		};
		B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference "swift-collections" */ = {
			isa = XCRemoteSwiftPackageReference;
			repositoryURL = "https://github.com/apple/swift-collections";
			requirement = {
				kind = upToNextMajorVersion;
				minimumVersion = 1.0.2;
			};
		};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
		B64B1F6227A4FC5100AC2601 /* Promise */ = {
			isa = XCSwiftPackageProductDependency;
			package = B64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference "Promise" */;
			productName = Promise;
		};
		B64B1F6727A4FC8A00AC2601 /* SnapKit */ = {
			isa = XCSwiftPackageProductDependency;
			package = B64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference "SnapKit" */;
			productName = SnapKit;
		};
		B680A89F27A8DA78007CB707 /* OrderedCollections */ = {
			isa = XCSwiftPackageProductDependency;
			package = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference "swift-collections" */;
			productName = OrderedCollections;
		};
		B680A8A127A8DA78007CB707 /* DequeModule */ = {
			isa = XCSwiftPackageProductDependency;
			package = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference "swift-collections" */;
			productName = DequeModule;
		};
		B680A8A327A8DA78007CB707 /* Collections */ = {
			isa = XCSwiftPackageProductDependency;
			package = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference "swift-collections" */;
			productName = Collections;
		};
/* End XCSwiftPackageProductDependency section */
	};
	rootObject = B64B1E8627A4F67000AC2601 /* Project object */;
}


================================================
FILE: CoreUtil/CoreUtil.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:">
   </FileRef>
</Workspace>


================================================
FILE: CoreUtil/CoreUtil.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>IDEDidComputeMac32BitWarning</key>
	<true/>
</dict>
</plist>


================================================
FILE: DevToys/DevToys/App/AppViewController.swift
================================================
//
//  ViewController.swift
//  DevToys
//
//  Created by yuki on 2022/01/29.
//

import Cocoa
import CoreUtil

final class AppViewController: NSSplitViewController {
    private let sidebarController = SidebarViewController()
    private let bodyController = BodyViewController()
    
    override func chainObjectDidLoad() {
        // The object chain will be broken on `addSplitViewItem`. So call the manual chain.
        self.sidebarController.chainObject = chainObject
        self.bodyController.chainObject = chainObject
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let sidebarItem = NSSplitViewItem(sidebarWithViewController: sidebarController)
        sidebarItem.minimumThickness = 200
        sidebarItem.canCollapse = false
        self.addSplitViewItem(sidebarItem)
        
        let bodyItem = NSSplitViewItem(viewController: bodyController)
        bodyItem.minimumThickness = 480
        bodyItem.canCollapse = false
        self.addSplitViewItem(bodyItem)
        
        splitView.setPosition(220, ofDividerAt: 0)
        
        self.splitView.autosaveName = "app.splitv"
    }
}


================================================
FILE: DevToys/DevToys/App/AppWindowController.swift
================================================
//
//  AppWindowController.swift
//  DevToys
//
//  Created by yuki on 2022/01/29.
//

import CoreUtil
import Darwin
import AppKit

final class AppWindowController: NSWindowController {
    private let appModel = AppModel()
    
    private lazy var separatorItem = NSTrackingSeparatorToolbarItem(
        identifier: AppWindowController.separatorItemIdentifier, splitView: splitViewController.splitView, dividerIndex: 0
    )
    private lazy var disclosureItem = NSToolbarItem(
        itemIdentifier: AppWindowController.disclosureItemIdentifier
    )
    private var splitViewController: NSSplitViewController {
        self.window?.contentViewController as! NSSplitViewController
    }
    
    @objc private func toggleSidebar() {
        splitViewController.splitViewItems[0].animator().isCollapsed.toggle()
    }
    
    override func windowDidLoad() {        
        self.contentViewController?.chainObject = appModel
        
        self.appModel.settings.$appearanceType
            .sink{
                switch $0 {
                case .useSystemSettings: self.window?.appearance = nil
                case .darkMode: self.window?.appearance = NSAppearance(named: .darkAqua)
                case .lightMode: self.window?.appearance = NSAppearance(named: .aqua)
                }
            }
            .store(in: &objectBag)
        self.appModel.$tool
            .sink{[unowned self] in self.window?.title = $0.title }.store(in: &objectBag)
        
        guard let toolbar = self.window?.toolbar else { return assertionFailure() }
        toolbar.delegate = self
        toolbar.allowsUserCustomization = true

        disclosureItem.view = NSButton(title: "Sidebar", image: R.Image.sidebarDisclosure) => {
            $0.bezelStyle = .texturedRounded
            $0.actionPublisher.sink{[unowned self] in toggleSidebar() }.store(in: &objectBag)
        }
    }
}

extension AppWindowController: NSToolbarDelegate {
    
    static let separatorItemIdentifier = NSToolbarItem.Identifier("separator")
    static let disclosureItemIdentifier = NSToolbarItem.Identifier("disclosure")
    
    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        if #available(macOS 11.0, *) {
            return [AppWindowController.disclosureItemIdentifier, AppWindowController.separatorItemIdentifier]
        } else {
            return [AppWindowController.disclosureItemIdentifier]
        }
    }
    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        self.toolbarDefaultItemIdentifiers(toolbar)
    }
    func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        []
    }
    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        if #available(macOS 11.0, *) {
            if itemIdentifier == AppWindowController.separatorItemIdentifier {
                return self.separatorItem
            }
        }
        if itemIdentifier == AppWindowController.disclosureItemIdentifier {
            return self.disclosureItem
        }
        return nil
    }
}


================================================
FILE: DevToys/DevToys/AppDelegate.swift
================================================
//
//  AppDelegate.swift
//  DevToys
//
//  Created by yuki on 2022/01/29.
//

import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate { 
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { true }
}


================================================
FILE: DevToys/DevToys/Body/BodyViewController.swift
================================================
//
//  BodyViewController.swift
//  DevToys
//
//  Created by yuki on 2022/01/29.
//

import CoreUtil

final class BodyViewController: NSViewController {
    private let placeholderView = NSPlaceholderView()
    private var contentViewController: NSViewController?
    
    override func loadView() { self.view = placeholderView }
    
    override func chainObjectDidLoad() {
        self.appModel.$tool
            .sink{[unowned self] in replaceTool($0) }.store(in: &objectBag)
        self.appModel.$searchQuery
            .sink{[unowned self] in handleQuery($0) }.store(in: &objectBag)
    }
    
    private func handleQuery(_ query: String) {
        if query.isEmpty {
            self.replaceTool(appModel.tool)
        } else {
            self.replaceTool(.search)
        }
    }
    
    private func replaceTool(_ tool: Tool) {
        self.contentViewController?.removeFromParent()
        self.addChild(tool.viewController)
        self.contentViewController = tool.viewController
        self.placeholderView.contentView = tool.viewController.view
    }
}


================================================
FILE: DevToys/DevToys/Body/Coder/Base64DecoderView+.swift
================================================
//
//  Base64Decoder.swift
//  DevToys
//
//  Created by yuki on 2022/01/30.
//

import CoreUtil

final class Base64DecoderViewController: NSViewController {
    private let cell = Base64DecoderView()
    
    @RestorableState("base64.sourceType") private var sourceType = SourceType.text
    @RestorableState("base64.rawString") private var rawString = defaultRawString
    @Observable private var formattedString = defaultBase64String
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.cell.inputTextSection.stringPublisher
            .sink{[unowned self] in self.rawString = $0; self.formattedString = encode($0) }.store(in: &objectBag)
        self.cell.encodeTextSection.stringPublisher
            .sink{[unowned self] in self.formattedString = $0; self.rawString = decode($0) }.store(in: &objectBag)
        self.cell.sourceTypePicker.itemPublisher
            .sink{[unowned self] in self.sourceType = $0 }.store(in: &objectBag)
        self.cell.fileDrop.urlsPublisher.compactMap{ $0.first }
            .sink{[unowned self] in self.formattedString = self.encodeFile($0) }.store(in: &objectBag)
        self.cell.exportButton.actionPublisher
            .sink{[unowned self] in self.exportFile() }.store(in: &objectBag)
        
        self.$sourceType
            .sink{[unowned self] in self.cell.sourceTypePicker.selectedItem = $0; updateEncodeView($0) }.store(in: &objectBag)
        self.$rawString
            .sink{[unowned self] in self.cell.inputTextSection.string = $0 }.store(in: &objectBag)
        self.$formattedString
            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)
    }
    
    private func updateEncodeView(_ sourceType: SourceType) {
        switch sourceType {
        case .file:
            self.cell.inputSectionContainer.contentView = cell.fileDropSection
        case .text:
            self.cell.inputSectionContainer.contentView = cell.inputTextSection
            self.formattedString = self.encode(rawString)
        }
    }
    
    private func exportFile() {
        let panel = NSSavePanel()
        guard let data = Data(base64Encoded: formattedString), panel.runModal() == .OK, let url = panel.url else { return }
        
        do {
            try data.write(to: url)
        } catch {
            NSSound.beep()
        }
    }
    private func encodeFile(_ url: URL) -> String {
        (try? Data(contentsOf: url).base64EncodedString()) ?? "[Encode Failed]"
    }
    private func encode(_ string: String) -> String {
        string.data(using: .utf8)!.base64EncodedString()
    }
    private func decode(_ string: String) -> String {
        String(data: Data(base64Encoded: string) ?? Data(), encoding: .utf8) ?? "Not String"
    }
}

private enum SourceType: String, TextItem {
    case text = "Text Source"
    case file = "File Source"
    var title: String { rawValue.localized() }
}

final private class Base64DecoderView: Page {
    let sourceTypePicker = EnumPopupButton<SourceType>()
    
    let fileDrop = FileDrop()
    let exportButton = SectionButton(title: "Export".localized(), image: R.Image.export)
    let inputSectionContainer = NSPlaceholderView()
    let inputTextSection = TextViewSection(title: "Text".localized(), options: [.all])
    lazy var fileDropSection = Section(title: "File".localized(), items: [fileDrop], toolbarItems: [exportButton])
    
    let encodeTextSection = TextViewSection(title: "Encoded".localized(), options: [.all])
    
    override func layout() {
        super.layout()
        let halfHeight = max(200, (self.frame.height - 190) / 2)
        
        self.fileDropSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
        self.inputTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
        self.encodeTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
    }
    
    override func onAwake() {            
        self.addSection(Section(title: "Configuration".localized(), items: [
            Area(icon: R.Image.convert, title: "Source Type".localized(), control: sourceTypePicker)
        ]))
        self.inputSectionContainer.contentView = inputTextSection
        self.addSection(inputSectionContainer)
        self.addSection(inputTextSection)
        self.addSection(encodeTextSection)
    }
}

private let defaultRawString = "An Open-Source Swiss Army knife for developers. DevToys helps in everyday tasks like formatting JSON, comparing text, testing RegExp. No need to use many untruthful websites to do simple tasks with your data. With Smart Detection, DevToys is able to detect the best tool that can treat the data you copied in the clipboard of your Windows. Compact overlay lets you keep the app in small and on top of other windows. Multiple instances of the app can be used at once."

private let defaultBase64String = "QW4gT3Blbi1Tb3VyY2UgU3dpc3MgQXJteSBrbmlmZSBmb3IgZGV2ZWxvcGVycy4KRGV2VG95cyBoZWxwcyBpbiBldmVyeWRheSB0YXNrcyBsaWtlIGZvcm1hdHRpbmcgSlNPTiwgY29tcGFyaW5nIHRleHQsIHRlc3RpbmcgUmVnRXhwLiBObyBuZWVkIHRvIHVzZSBtYW55IHVudHJ1dGhmdWwgd2Vic2l0ZXMgdG8gZG8gc2ltcGxlIHRhc2tzIHdpdGggeW91ciBkYXRhLiBXaXRoIFNtYXJ0IERldGVjdGlvbiwgRGV2VG95cyBpcyBhYmxlIHRvIGRldGVjdCB0aGUgYmVzdCB0b29sIHRoYXQgY2FuIHRyZWF0IHRoZSBkYXRhIHlvdSBjb3BpZWQgaW4gdGhlIGNsaXBib2FyZCBvZiB5b3VyIFdpbmRvd3MuIENvbXBhY3Qgb3ZlcmxheSBsZXRzIHlvdSBrZWVwIHRoZSBhcHAgaW4gc21hbGwgYW5kIG9uIHRvcCBvZiBvdGhlciB3aW5kb3dzLiBNdWx0aXBsZSBpbnN0YW5jZXMgb2YgdGhlIGFwcCBjYW4gYmUgdXNlZCBhdCBvbmNlLg=="


================================================
FILE: DevToys/DevToys/Body/Coder/HTMLDecoderView+.swift
================================================
//
//  HTMLDecoder.swift
//  DevToys
//
//  Created by yuki on 2022/01/30.
//

import CoreUtil
import HTMLEntities

final class HTMLDecoderViewController: NSViewController {
    private let cell = HTMLDecoderView()
    
    @RestorableState("html.rawString") var rawString = "<script>alert(\"abc\")</script>"
    @RestorableState("html.formattedString") var formattedString = "&#x3C;script&#x3E;alert(&#x22;abc&#x22;)&#x3C;/script&#x3E;"
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.cell.decodeTextSection.stringPublisher
            .sink{[unowned self] in self.rawString = $0; self.formattedString = $0.htmlEscape() }.store(in: &objectBag)
        self.cell.encodeTextSection.stringPublisher
            .sink{[unowned self] in self.formattedString = $0; self.rawString = $0.htmlUnescape() }.store(in: &objectBag)
        
        self.$rawString
            .sink{[unowned self] in self.cell.decodeTextSection.string = $0 }.store(in: &objectBag)
        self.$formattedString
            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)
    }
}

final private class HTMLDecoderView: Page {
    let decodeTextSection = CodeViewSection(title: "Decoded".localized(), options: [.all], language: .xml)
    let encodeTextSection = TextViewSection(title: "Encoded".localized(), options: [.all])
    
    override func layout() {
        super.layout()
        let halfHeight = max(200, (self.frame.height - 100) / 2)
        
        self.decodeTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
        self.encodeTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
    }
    
    override func onAwake() {        
        self.addSection(decodeTextSection)
        self.addSection(encodeTextSection)
    }
}



================================================
FILE: DevToys/DevToys/Body/Coder/JWTDecoderView+.swift
================================================
//
//  JWTDecoder.swift
//  DevToys
//
//  Created by yuki on 2022/02/01.
//

import CoreUtil

final class JWTDecoderViewController: NSViewController {
    private let cell = JWTDecoderView()
    
    @RestorableState("jwt.token") var token = defaultToken
    @RestorableState("jwt.header") var header = defaultHeader
    @RestorableState("jwt.payload") var payload = defaultPayload
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$token
            .sink{[unowned self] in self.cell.tokenTextSection.string = $0 }.store(in: &objectBag)
        self.$header
            .sink{[unowned self] in self.cell.headerCodeSection.string = $0 }.store(in: &objectBag)
        self.$payload
            .sink{[unowned self] in self.cell.payloadCodeSection.string = $0 }.store(in: &objectBag)
        
        self.cell.tokenTextSection.stringPublisher
            .sink{[unowned self] in
                self.token = $0
                guard let (header, payload) = self.decodeJWT($0) else {
                    self.header = "[Decode Failed]"
                    self.payload = "[Decode Failed]"
                    return
                }
                
                self.header = header
                self.payload = payload
            }
            .store(in: &objectBag)
    }
    
    private func decodeJWT(_ token: String) -> (header: String, payload: String)? {
        let components = token.split(separator: ".").map{ String($0) }
        
        guard components.count == 3 else { print("not3"); return nil }
        guard let header = self.decodeBase64ToJson(components[0]) else { print("he"); return nil }
        guard let payload = self.decodeBase64ToJson(components[1]) else { print("pa"); return nil }
        
        return (header, payload)
    }
    
    private func decodeBase64ToJson(_ string: String) -> String? {
        guard let data = Data(base64Encoded: string) ?? Data(base64Encoded: string + "=") ?? Data(base64Encoded: string + "==") else { return nil }
        guard let object = try? JSONSerialization.jsonObject(with: data, options: []) else { return nil }
        guard let json = try? JSONSerialization.data(withJSONObject: object, options: .prettyPrinted) else { return nil }
        
        return String(data: json, encoding: .utf8)
    }
}

final private class JWTDecoderView: Page {
        
    let tokenTextSection = TextViewSection(title: "JWT Token".localized(), options: .defaultInput)
    let headerCodeSection = CodeViewSection(title: "Header".localized(), options: .defaultOutput, language: .javascript)
    let payloadCodeSection = CodeViewSection(title: "Payload".localized(), options: .defaultOutput, language: .javascript)
    
    override func layout() {
        super.layout()
        
        let contentHeight = max(100, (self.frame.height - 100) / 3)
        
        self.tokenTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(contentHeight)
        }
        self.headerCodeSection.snp.remakeConstraints{ make in
            make.height.equalTo(contentHeight)
        }
        self.payloadCodeSection.snp.remakeConstraints{ make in
            make.height.equalTo(contentHeight)
        }
    }
    
    override func onAwake() {        
        self.addSection(tokenTextSection)
        self.tokenTextSection.textView.snp.remakeConstraints{ make in
            make.height.equalTo(85)
        }
        self.addSection(headerCodeSection)
        self.headerCodeSection.textView.snp.remakeConstraints{ make in
            make.height.equalTo(100)
        }
        self.addSection(payloadCodeSection)
        self.payloadCodeSection.textView.snp.remakeConstraints{ make in
            make.height.equalTo(100)
        }
    }
}

private let defaultToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiYWdlIjoxNn0.Ir_wyzMjqDXeeaGWJVgdysutJ6C9E3MX11t38LD2K60"

private let defaultPayload = """
{
  "sub": "1234567890",
  "name": "Alice",
  "age": 16
}
"""

private let defaultHeader = """
{
  "alg": "HS256",
  "typ": "JWT"
}
"""


================================================
FILE: DevToys/DevToys/Body/Coder/URLDecoderView+.swift
================================================
//
//  URLDecoder.swift
//  DevToys
//
//  Created by yuki on 2022/01/30.
//

import CoreUtil

final class URLDecoderViewController: NSViewController {
    private let cell = URLDecoderView()
    
    @RestorableState("url.rawString") var rawString = "https://www.microsoft.com/ja-jp/p/devtoys/9pgcv4v3bk4w?rtc=1#activetab=pivot:overviewtab"
    @RestorableState("url.formattedString") var formattedString = "https%3A%2F%2Fwww.microsoft.com%2Fja-jp%2Fp%2Fdevtoys%2F9pgcv4v3bk4w%3Frtc%3D1%23activetab%3Dpivot%3Aoverviewtab"
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.cell.decodeTextSection.stringPublisher
            .sink{[unowned self] in self.rawString = $0; self.formattedString = encodeToURL($0) }.store(in: &objectBag)
        self.cell.encodeTextSection.stringPublisher
            .sink{[unowned self] in self.formattedString = $0; if let s = $0.removingPercentEncoding { self.rawString = s } }.store(in: &objectBag)
        
        self.$rawString
            .sink{[unowned self] in self.cell.decodeTextSection.string = $0 }.store(in: &objectBag)
        self.$formattedString
            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)
    }
    
    private func encodeToURL(_ string: String) -> String {
        let allowedCharacters = NSCharacterSet.alphanumerics.union(.init(charactersIn: "-._~"))
        return string.addingPercentEncoding(withAllowedCharacters: allowedCharacters) ?? "???"
    }
}

final private class URLDecoderView: Page {
    let decodeTextSection = TextViewSection(title: "Decoded".localized(), options: [.all])
    let encodeTextSection = TextViewSection(title: "Encoded".localized(), options: [.all])
    
    override func layout() {
        super.layout()
        let halfHeight = max(200, (self.frame.height - 100) / 2)
        
        self.decodeTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
        self.encodeTextSection.snp.remakeConstraints{ make in
            make.height.equalTo(halfHeight)
        }
    }
    
    override func onAwake() {        
        self.addSection(decodeTextSection)
        self.addSection(encodeTextSection)
    }
}


================================================
FILE: DevToys/DevToys/Body/Convert/DateConverterView+.swift
================================================
//
//  DateConverter.swift
//  DevToys
//
//  Created by yuki on 2022/02/04.
//

import CoreUtil

final class DateConverterViewController: NSViewController {
    private let cell = DateConverterView()
    
    @Observable var date = Date()
    
    private let isoFormatter = ISO8601DateFormatter()
    private let gmtFormatter = DateFormatter() => {
        $0.locale = Locale(identifier: "en_US_POSIX")
        $0.timeZone = TimeZone(abbreviation: "GMT")
    }
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$date
            .sink{[unowned self] in
                self.cell.datePicker.date = $0
                self.cell.unixTimeField.value = $0.timeIntervalSince1970.rounded()
                self.cell.isoDateField.string = isoFormatter.string(from: $0)
                self.cell.graphicDatePicker.dateValue = $0
            }
            .store(in: &objectBag)
        
        self.cell.graphicDatePicker.actionPublisher
            .sink{[unowned self] in self.date = cell.graphicDatePicker.dateValue }.store(in: &objectBag)
        self.cell.nowButton.actionPublisher
            .sink{[unowned self] in self.date = Date() }.store(in: &objectBag)
        self.cell.datePicker.datePublisher
            .sink{[unowned self] in self.date = $0 }.store(in: &objectBag)
        self.cell.unixTimeField.valuePublisher
            .sink{[unowned self] in self.date = Date(timeIntervalSince1970: $0.reduce(self.date.timeIntervalSince1970)) }.store(in: &objectBag)
        self.cell.isoDateField.changeStringPublisher.compactMap{[unowned self] in isoFormatter.date(from: $0) }
            .sink{[unowned self] in self.date = $0 }.store(in: &objectBag)
    }
}

final private class DateConverterView: Page {
    
    let datePicker = DatePicker()
    let utcDatePicker = DatePicker()
    let nowButton = Button(title: "Now")
    let unixTimeField = NumberField()
    let isoDateField = TextField(showCopyButton: false)
    let timestampDateField = TextField(showCopyButton: false)
    let graphicDatePicker = NSDatePicker()
    
    override func onAwake() {        
        self.addSection(Section(title: "Date".localized(), items: [
            NSStackView() => {
                $0.distribution = .equalSpacing
                $0.addArrangedSubview(datePicker)
                $0.addArrangedSubview(nowButton)
            }
        ]))
        self.datePicker.snp.remakeConstraints{ make in
            make.right.equalTo(nowButton.snp.left).inset(-8)
        }
        
        self.addSection(Section(title: "Unix Time".localized(), items: [unixTimeField]))
        self.unixTimeField.showStepper = false
        self.unixTimeField.snp.remakeConstraints{ make in
            make.height.equalTo(R.Size.controlHeight)
        }
        self.addSection(Section(title: "ISO 8601".localized(), items: [isoDateField]))
        self.addSection(Section(title: "Timestamp".localized(), items: [timestampDateField]))
        
        self.addSection(Section(title: "Calender".localized(), items: [graphicDatePicker]))
        self.graphicDatePicker.datePickerStyle = .clockAndCalendar
    }
}



================================================
FILE: DevToys/DevToys/Body/Convert/JSONYamlConverterView+.swift
================================================
//
//  JSONYamlConverter+.swift
//  DevToys
//
//  Created by yuki on 2022/01/30.
//

import CoreUtil
import Yams
import SwiftJSONFormatter

final class JSONYamlConverterViewController: NSViewController {
    private let cell = JSONYamlConverterView()
    
    @RestorableState("jy.format") private var formatStyle: FormatStyle = .pretty
    @RestorableState("jy.json") private var jsonCode = defaultJsonCode
    @RestorableState("jy.yaml") private var yamlCode = defaultYamlCode
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$jsonCode
            .sink{[unowned self] in self.cell.jsonSection.string = $0 }.store(in: &objectBag)
        self.$yamlCode
            .sink{[unowned self] in self.cell.yamlSection.string = $0 }.store(in: &objectBag)
        self.$formatStyle
            .sink{[unowned self] in self.cell.formatStylePicker.selectedItem = $0 }.store(in: &objectBag)
     
        self.cell.formatStylePicker.itemPublisher
            .sink{[unowned self] in self.formatStyle = $0 }.store(in: &objectBag)
        self.cell.jsonSection.stringPublisher
            .sink{[unowned self] in
                self.jsonCode = $0
                if let yamlCode = convertJsonToYaml(code: $0, formatStyle: self.formatStyle) {
                    self.yamlCode = yamlCode
                }
            }
            .store(in: &objectBag)
        self.cell.yamlSection.stringPublisher
            .sink{[unowned self] in
                self.yamlCode = $0
                if let jsonCode = convertYamlToJson(code: $0, formatStyle: self.formatStyle) { self.jsonCode = jsonCode }
            }
            .store(in: &objectBag)
    }
    
    private func convertYamlToJson(code: String, formatStyle: FormatStyle) -> String? {
        if code.isEmpty { return "" }
        guard let object = try? Yams.load(yaml: code) else { return nil }
        
        var options = JSONSerialization.WritingOptions()
        options.insert(.sortedKeys)
        if formatStyle == .pretty { options.insert(.prettyPrinted) }
        return try? objc_try {
            guard let data = try? JSONSerialization.data(withJSONObject: object, options: options) else { return nil }
            let json = String(data: data, encoding: .utf8)!
            
            return SwiftJSONFormatter.beautify(json, indent: "    ")
        }
    }
    
    private func convertJsonToYaml(code: String, formatStyle: FormatStyle) -> String? {
        if code.isEmpty { return "" }
        return objc_try({
            guard let object = try? JSONSerialization.jsonObject(with: code.data(using: .utf8)!) else {
                return nil
            }
            
            let swiftObject = convertNSObject(object)
            
            return try? Yams.dump(object: swiftObject)
        }, catch: {_ in
            return nil
        })
    }
    
    private func convertNSObject(_ object: Any) -> Any {
        if let object = object as? NSDictionary {
            return (object as! [String: Any]).mapValues{ convertNSObject($0) }
        }
        if let object = object as? NSArray { return (object as! [Any]).map{ convertNSObject($0) } }
        if let object = object as? NSString { return object as String }
        if let object = object as? NSNumber {
            switch CFNumberGetType(object) {
            case .cgFloatType, .floatType, .doubleType, .float32Type, .float64Type: return object.doubleValue
            case .longLongType, .longType, .shortType, .intType, .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .cfIndexType, .nsIntegerType: return object.intValue
            case .charType: return object.boolValue
            @unknown default: return object.intValue
            }
        }
        
        return object
    }
}

private enum FormatStyle: String, TextItem {
    case pretty = "Pretty"
    case minified = "Minified"
    
    var title: String { rawValue.localized() }
}

final private class JSONYamlConverterView: Page {
    
    let formatStylePicker = EnumPopupButton<FormatStyle>()
    
    let jsonSection = CodeViewSection(title: "JSON", options: .all, language: .javascript)
    let yamlSection = CodeViewSection(title: "Yaml", options: .all, language: .yaml)
    
    private lazy var ioStack = self.addSection2(jsonSection, yamlSection)
    
    override func layout() {
        super.layout()
        
        self.ioStack.snp.remakeConstraints{ make in
            make.height.equalTo(max(240, self.frame.height - 170))
        }
    }
    
    override func onAwake() {
        self.addSection(Section(title: "Configuration".localized(), items: [
            Area(icon: R.Image.format, title: "Format".localized(), control: formatStylePicker)
        ]))
    }
}

private let defaultJsonCode = """
{
    "type" : "members",
    "members" : [
        {
            "name" : "Alice",
            "age" : 16
        },
        {
            "name" : "Bob",
            "age" : 24
        }
    ],
}
"""

private let defaultYamlCode = """
type: members
members:
- age: 16
  name: Alice
- age: 24
  name: Bob
"""



================================================
FILE: DevToys/DevToys/Body/Convert/NumberBaseConverterView+.swift
================================================
//
//  NumberBaseConverter.swift
//  DevToys
//
//  Created by yuki on 2022/01/30.
//

import CoreUtil

final class NumberBaseConverterViewController: NSViewController {
    private let cell = NumberBaseConverterView()
    
    @RestorableState("numbase.format") private var formatNumber = true
    @RestorableState("numbase.2") private var value2 = "1 0101 1010 0101 0011"
    @RestorableState("numbase.10") private var value10 = "88,659"
    @RestorableState("numbase.8") private var value8 = "255 123"
    @RestorableState("numbase.16") private var value16 = "1 5A53"
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$value2
            .sink{[unowned self] in cell.binarySection.string = $0 }.store(in: &objectBag)
        self.$value8
            .sink{[unowned self] in cell.octalSection.string = $0 }.store(in: &objectBag)
        self.$value10
            .sink{[unowned self] in cell.decimalSection.string = $0 }.store(in: &objectBag)
        self.$value16
            .sink{[unowned self] in cell.hexSection.string = $0 }.store(in: &objectBag)
        self.$formatNumber
            .sink{[unowned self] in cell.formatSwitch.state = $0 ? .on : .off }.store(in: &objectBag)
        
        self.cell.binarySection.stringPublisher
            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 2) }.store(in: &objectBag)
        self.cell.octalSection.stringPublisher
            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 8) }.store(in: &objectBag)
        self.cell.decimalSection.stringPublisher
            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 10) }.store(in: &objectBag)
        self.cell.hexSection.stringPublisher
            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 16) }.store(in: &objectBag)
        self.cell.formatSwitch.actionPublisher.map{[unowned self] in self.cell.formatSwitch.state == .on }
            .sink{[unowned self] in self.formatNumber = $0; updateFormat() }.store(in: &objectBag)
    }
    
    private func updateFormat() {
        self.updateValue(string: value10, inputRadix: 10)
    }
    private func updateValue(string: String, inputRadix: Int) {
        let value = Int(string.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: ",", with: ""), radix: inputRadix)
        self.value2 = self.convertBinary(value, format: self.formatNumber)
        self.value8 = self.convertOctal(value, format: self.formatNumber)
        self.value10 = self.convertDecimal(value, format: self.formatNumber)
        self.value16 = self.convertHex(value, format: self.formatNumber)
    }
    
    private func convertHex(_ value: Int?, format: Bool) -> String {
        guard let value = value else { return "0" }
        
        let string = String(value, radix: 16, uppercase: true)
        if format { return splitString(string, split: 4, separator: " ") } else {  return string }
    }
    private func convertDecimal(_ value: Int?, format: Bool) -> String {
        guard let value = value else { return "0" }
        
        let string = String(value, radix: 10, uppercase: true)
        if format { return splitString(string, split: 3, separator: ",") } else {  return string }
    }
    private func convertOctal(_ value: Int?, format: Bool) -> String {
        guard let value = value else { return "0" }
        
        let string = String(value, radix: 8, uppercase: true)
        if format { return splitString(string, split: 3, separator: " ") } else {  return string }
    }
    private func convertBinary(_ value: Int?, format: Bool) -> String {
        guard let value = value else { return "0" }
        
        let string = String(value, radix: 2, uppercase: true)
        if format { return splitString(string, split: 4, separator: " ") } else {  return string }
    }
    
    private func splitString(_ string: String, split: Int, separator: String) -> String {
        var result = ""
        var count = string.count
        
        for c in string {
            count -= 1
            result.append(c)
            if count != 0, count % split == 0 { result.append(separator) }
        }
        
        return result
    }
    
    private func convert(_ value: Int?, radix: Int) -> String {
        guard let value = value else { return "0" }
        return String(value, radix: radix, uppercase: true)
    }
}

final private class NumberBaseConverterView: Page {
    let formatSwitch = NSSwitch()
    
    let decimalSection = TextFieldSection(title: "Decimal".localized())
    let hexSection = TextFieldSection(title: "Hexdecimal".localized())
    let octalSection = TextFieldSection(title: "Octal".localized())
    let binarySection = TextFieldSection(title: "Binary".localized())
    
    private lazy var formatNumberArea = Area(icon: R.Image.format, title: "Format Number".localized(), control: formatSwitch)
    
    private lazy var configurationSection = Section(title: "Configuration".localized(), items: [formatNumberArea])
    
    override func onAwake() {        
        self.addSection(configurationSection)
        
        self.addSection(decimalSection)
        self.addSection(hexSection)
        self.addSection(octalSection)
        self.addSection(binarySection)
    }
}


================================================
FILE: DevToys/DevToys/Body/Format/JSONFormatterView+.swift
================================================
//
//  JSONFormatter+.swift
//  DevToys
//
//  Created by yuki on 2022/01/29.
//

import CoreUtil
import SwiftJSONFormatter

final class JSONFormatterViewController: NSViewController {
    
    @RestorableState("json.spacingtype") var spacingType: JSONSpacingType = .spaces4
    
    @RestorableState("jq.rawCode") var rawCode: String = #"{ "Hello": "World" }"#
    @RestorableState("jq.formattedCode") var formattedCode: String = "{\n    \"Hello\": \"World\"\n}"
    
    private let cell = JSONFormatterView()
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$spacingType
            .sink{[unowned self] in cell.indentControl.selectedItem = $0 }.store(in: &objectBag)
        self.$rawCode
            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)
        self.$formattedCode
            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)
        
        self.cell.inputSection.stringPublisher
            .sink{[unowned self] in self.rawCode = $0; updateFormattedCode() }.store(in: &objectBag)
        self.cell.indentControl.itemPublisher
            .sink{[unowned self] in self.spacingType = $0; updateFormattedCode() }.store(in: &objectBag)
    }
    
    private func updateFormattedCode() {
        self.formattedCode = processJSON(rawCode, spacingType: spacingType)
    }
    
    private func processJSON(_ code: String, spacingType: JSONSpacingType) -> String {
        switch spacingType {
        case .spaces2: return SwiftJSONFormatter.beautify(code, indent: "  ")
        case .spaces4: return SwiftJSONFormatter.beautify(code, indent: "    ")
        case .tab1: return SwiftJSONFormatter.beautify(code, indent: "\t")
        case .minified: return SwiftJSONFormatter.minify(code)
        }
    }
}

enum JSONSpacingType: String, TextItem {
    case spaces2 = "2 Spaces"
    case spaces4 = "4 Spaces"
    case tab1 = "1 Tab"
    case minified = "Minified"
    
    var title: String { rawValue.localized() }
}

final private class JSONFormatterView: Page {
    
    let indentControl = EnumPopupButton<JSONSpacingType>()
    let inputSection = CodeViewSection(title: "Input".localized(), options: .defaultInput, language: .javascript)
    let outputSection = CodeViewSection(title: "Output".localized(), options: .defaultOutput, language: .javascript)
        
    private lazy var indentArea = Area(icon: R.Image.spacing, title: "Indentation".localized(), control: indentControl)
    private lazy var configurationSection = Section(title: "Configuration".localized(), items: [indentArea])
    private lazy var ioStack = self.addSection2(inputSection, outputSection)
    
    override func layout() {
        super.layout()
        
        self.ioStack.snp.remakeConstraints{ make in
            make.height.equalTo(max(240, self.frame.height - 180))
        }
    }
    
    override func onAwake() {
        self.addSection(configurationSection)
        self.outputSection.textView.textView.usesFindBar = true
    }
}


================================================
FILE: DevToys/DevToys/Body/Format/SQLFormatterView+.swift
================================================
//
//  SQLFormatterView+.swift
//  DevToys
//
//  Created by yuki on 2022/02/26.
//

import CoreUtil

final class SQLFormatterViewController: NSViewController {
    private let cell = SQLFormatterView()
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        
    }
}

final private class SQLFormatterView: Page {
    override func onAwake() {
        
    }
}


================================================
FILE: DevToys/DevToys/Body/Format/XMLFormatterView+.swift
================================================
//
//  XMLFormatter.swift
//  DevToys
//
//  Created by yuki on 2022/02/04.
//

import CoreUtil

final class XMLFormatterViewController: NSViewController {
    @RestorableState("xml.rawCode") private var rawCode: String = ""
    @RestorableState("xml.formattedCode") private var formattedCode: String = ""
    @RestorableState("xml.documentType") private var documentType: DocumentType = .xmlDocument
    @RestorableState("xml.pretty") private var pretty = true
    @RestorableState("xml.autofix") private var autofix = true
    
    private let cell = XMLFormatterView()
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$rawCode
            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)
        self.$formattedCode
            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)
        self.$documentType
            .sink{[unowned self] in cell.documentTypeControl.selectedItem = $0 }.store(in: &objectBag)
        self.$pretty
            .sink{[unowned self] in cell.prettySwitch.isOn = $0 }.store(in: &objectBag)
        self.$autofix
            .sink{[unowned self] in cell.autoFixSwitch.isOn = $0 }.store(in: &objectBag)
        
        self.cell.prettySwitch.isOnPublisher
            .sink{[unowned self] in self.pretty = $0; updateFormattedCode() }.store(in: &objectBag)
        self.cell.autoFixSwitch.isOnPublisher
            .sink{[unowned self] in self.autofix = $0; updateFormattedCode() }.store(in: &objectBag)
        self.cell.documentTypeControl.itemPublisher
            .sink{[unowned self] in self.documentType = $0; updateFormattedCode() }.store(in: &objectBag)
        self.cell.inputSection.stringPublisher
            .sink{[unowned self] in self.rawCode = $0; updateFormattedCode() }.store(in: &objectBag)
        
        self.updateFormattedCode()
    }
    
    private func updateFormattedCode() {
        
        do {
            var options = XMLNode.Options()
            
            if pretty {
                options.insert(.nodePrettyPrint)
            }
            if autofix {
                switch documentType {
                case .htmlDocument: options.insert(.documentTidyHTML)
                case .xmlDocument: options.insert(.documentTidyXML)
                }
            }
            
            let document = try XMLDocument(xmlString: rawCode, options: options)
            
            self.formattedCode = document.xmlString(options: options)
                .replacingOccurrences(of: #"<?xml version="1.0" encoding="UTF-8"?>"#, with: "")
                .replacingOccurrences(of: #"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">"#, with: "")
                .replacingOccurrences(of: #"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">"#, with: "")
                .replacingOccurrences(of: #"<html xmlns="http://www.w3.org/1999/xhtml">"#, with: "<html>")
                .trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
            
        } catch {
            self.formattedCode = "[Invalid Document]"
        }
    }
}
 
private enum DocumentType: String, TextItem {
    case htmlDocument = "HTML Document"
    case xmlDocument = "XML Document"
    
    var title: String { rawValue.localized() }
}

final private class XMLFormatterView: Page {
    let prettySwitch = NSSwitch()
    let autoFixSwitch = NSSwitch()
    let documentTypeControl = EnumPopupButton<DocumentType>()
    let inputSection = CodeViewSection(title: "Input".localized(), options: .defaultInput, language: .xml)
    let outputSection = CodeViewSection(title: "Output".localized(), options: .defaultOutput, language: .xml)
        
    private lazy var configurationSection = Section(title: "Configuration".localized(), items: [
        Area(icon: R.Image.convert, title: "Document Type".localized(), control: documentTypeControl),
        NSStackView() => {
            $0.orientation = .horizontal
            $0.distribution = .fillEqually
            $0.addArrangedSubview(Area(icon: R.Image.format, title: "Auto Fix Document".localized(), control: autoFixSwitch))
            $0.addArrangedSubview(Area(icon: R.Image.format, title: "Pretty Document".localized(), control: prettySwitch))
        }
    ])
    
    private lazy var ioStack = self.addSection2(inputSection, outputSection)
    
    override func layout() {
        super.layout()
        
        self.ioStack.snp.remakeConstraints{ make in
            make.height.equalTo(max(240, self.frame.height - 230))
        }
    }
    
    override func onAwake() {
        self.addSection(configurationSection)
    }
}


================================================
FILE: DevToys/DevToys/Body/Generator/ChecksumGeneratorView+.swift
================================================
//
//  ChecksumGenerator.swift
//  DevToys
//
//  Created by yuki on 2022/02/04.
//

import CoreUtil

final class ChecksumGeneratorViewController: NSViewController {
    
    @RestorableState("checksum.uppercase") private var isUppercase = false
    @RestorableState("checksum.alg") private var hashAlgorithm = HashAlgorithm.md5
    @RestorableState("checksum.comparer") private var comparer = ""
    
    @Observable private var output = ""
    @Observable var isError = true
    @Observable var fileURL: URL?
    
    private let cell = ChecksumGeneratorView()
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.$isUppercase
            .sink{[unowned self] in cell.formatSwitch.isOn = $0 }.store(in: &objectBag)
        self.$hashAlgorithm
            .sink{[unowned self] in cell.hashAlgorithmPicker.selectedItem = $0 }.store(in: &objectBag)
        self.$output
            .sink{[unowned self] in cell.outputFieldSection.string = $0 }.store(in: &objectBag)
        self.$comparer
            .sink{[unowned self] in cell.compareFieldSection.string = $0 }.store(in: &objectBag)
        self.$isError
            .sink{[unowned self] in cell.compareFieldSection.textField.isError = $0 }.store(in: &objectBag)
        
        self.cell.formatSwitch.isOnPublisher
            .sink{[unowned self] in self.isUppercase = $0; updateHash() }.store(in: &objectBag)
        self.cell.hashAlgorithmPicker.itemPublisher
            .sink{[unowned self] in self.hashAlgorithm = $0; updateHash() }.store(in: &objectBag)
        self.cell.compareFieldSection.stringPublisher
            .sink{[unowned self] in self.comparer = $0; updateComparer() }.store(in: &objectBag)
        self.cell.fileSection.urlsPublisher.compactMap{ $0.first }
            .sink{[unowned self] in fileURL = $0; self.updateHash() }.store(in: &objectBag)
    }
    
    private func updateHash() {
        guard let url = self.fileURL, let data = try? Data(contentsOf: url) else { return NSSound.beep() }
        
        switch hashAlgorithm {
        case .md5: self.output = data.md5().hexString(uppercase: isUppercase)
        case .sha1: self.output = data.sha1().hexString(uppercase: isUppercase)
        case .sha256: self.output = data.sha256().hexString(uppercase: isUppercase)
        case .sha384: self.output = data.sha384().hexString(uppercase: isUppercase)
        case .sha512: self.output = data.sha512().hexString(uppercase: isUppercase)
        }
        self.updateComparer()
    }
    
    private func updateComparer() {
        self.isError = comparer.lowercased() != output.lowercased()
    }
}

extension Data {
    func hexString(uppercase: Bool) -> String {
        self.map{ String(format: uppercase ? "%02X" : "%02x", $0) }.joined()
    }
}

private enum HashAlgorithm: String, TextItem {
    case md5 = "MD5"
    case sha1 = "SHA1"
    case sha256 = "SHA256"
    case sha384 = "SHA384"
    case sha512 = "SHA512"
    var title: String { rawValue }
}

final private class ChecksumGeneratorView: Page {
    let formatSwitch = NSSwitch()
    let hashAlgorithmPicker = EnumPopupButton<HashAlgorithm>()
    let fileSection = FileDropSection()
    let outputFieldSection = TextFieldSection(title: "Output".localized(), isEditable: false)
    let compareFieldSection = TextFieldSection(title: "Output Comparer".localized(), isEditable: true)
    
    override func onAwake() {
        self.addSection(Section(title: "Configuration".localized(), items: [
            Area(icon: R.Image.format, title: "Uppercase".localized(), control: formatSwitch),
            Area(icon: R.Image.convert, title: "Hash Algorithm".localized(), message: "Select which algorithm you want to use".localized(), control: hashAlgorithmPicker)
        ]))
        
        self.addSection(fileSection)
        
        self.addSection(outputFieldSection)
        self.addSection(compareFieldSection)
    }
}


================================================
FILE: DevToys/DevToys/Body/Generator/HashGeneratorView+.swift
================================================
//
//  HashGenerator.swift
//  DevToys
//
//  Created by yuki on 2022/02/01.
//

import CoreUtil
import CryptoSwift

final class HashGeneratorViewController: NSViewController {
    private let cell = HashGeneratorView()
    
    @RestorableState("hash.upper") var isUppercase = false
    @RestorableState("hash.input") var input = "Hello World"
    @RestorableState("hash.md5") var md5 = ""
    @RestorableState("hash.sha1") var sha1 = ""
    @RestorableState("hash.sha256") var sha256 = ""
    @RestorableState("hash.sha512") var sha512 = ""
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.updateHash()
        
        self.$isUppercase.sink{[unowned self] in self.cell.formatSwitch.isOn = $0 }.store(in: &objectBag)
        self.$input.sink{[unowned self] in self.cell.textInputSection.string = $0 }.store(in: &objectBag)
        self.$md5.sink{[unowned self] in self.cell.md5Section.string = $0 }.store(in: &objectBag)
        self.$sha1.sink{[unowned self] in self.cell.sha1Section.string = $0 }.store(in: &objectBag)
        self.$sha256.sink{[unowned self] in self.cell.sha256Section.string = $0 }.store(in: &objectBag)
        self.$sha512.sink{[unowned self] in self.cell.sha512Section.string = $0 }.store(in: &objectBag)
        
        self.cell.textInputSection.stringPublisher
            .sink{[unowned self] in self.input = $0; updateHash() }.store(in: &objectBag)
        self.cell.formatSwitch.isOnPublisher
            .sink{[unowned self] in self.isUppercase = $0; updateHash() }.store(in: &objectBag)
    }
    
    private func updateHash() {
        self.md5 = isUppercase ? input.md5().uppercased() : input.md5()
        self.sha1 = isUppercase ? input.sha1().uppercased() : input.sha1()
        self.sha256 = isUppercase ? input.sha256().uppercased() : input.sha256()
        self.sha512 = isUppercase ? input.sha512().uppercased() : input.sha512()
    }
}

final class HashGeneratorView: Page {
    let formatSwitch = NSSwitch()
    
    let textInputSection = TextViewSection(title: "Input".localized(), options: .all)
    
    let md5Section = TextFieldSection(title: "MD5", isEditable: false)
    let sha1Section = TextFieldSection(title: "SHA1", isEditable: false)
    let sha256Section = TextFieldSection(title: "SHA256", isEditable: false)
    let sha512Section = TextFieldSection(title: "SHA512", isEditable: false)
    
    private lazy var formatNumberArea = Area(icon: R.Image.format, title: "Uppercase".localized(), control: formatSwitch)
    private lazy var configurationSection = Section(title: "Configuration".localized(), items: [formatNumberArea])

    override func onAwake() {        
        self.addSection(configurationSection)
        
        self.addSection(textInputSection)
        self.textInputSection.snp.remakeConstraints{ make in
            make.height.equalTo(180)
        }
        
        self.addSection(md5Section)
        self.addSection(sha1Section)
        self.addSection(sha256Section)
        self.addSection(sha512Section)
    }
}

extension NSSwitch {
    var isOn: Bool {
        get { self.state == .on } set { self.state = newValue ? .on : .off }
    }
    
    var isOnPublisher: AnyPublisher<Bool, Never> {
        self.actionPublisher.map{_ in self.state == .on }.eraseToAnyPublisher()
    }
}


================================================
FILE: DevToys/DevToys/Body/Generator/LoremIpsumGeneratorView+.swift
================================================
//
//  LoremIpsumGenerator.swift
//  DevToys
//
//  Created by yuki on 2022/02/01.
//

import CoreUtil

final class LoremIpsumGeneratorViewController: NSViewController {
    private let cell = LoremIpsumGeneratorView()
    
    @RestorableState("li.type") var generateType = LoremIpsumGenerateType.sentences
    @RestorableState("li.length") var length = 3
    @RestorableState("li.output") var output = "hello world"
    
    override func loadView() { self.view = cell }
    
    override func viewDidLoad() {
        self.generate()
        
        self.$generateType.sink{[unowned self] in self.cell.typePicker.selectedItem = $0 }.store(in: &objectBag)
        self.$length.sink{[unowned self] in self.cell.lengthField.value = Double($0) }.store(in: &objectBag)
        self.$output.sink{[unowned self] in self.cell.outputSection.string = $0 }.store(in: &objectBag)
        
        self.cell.typePicker.itemPublisher
            .sink{[unowned self] in self.generateType = $0; generate() }.store(in: &objectBag)
        self.cell.lengthField.valuePublisher.map{ $0.map{ Int($0) } }
            .sink{[unowned self] in
                let next = $0.reduce(self.length).clamped(1...)
                if next != self.length { self.length = next; self.generate() }
            }.store(in: &objectBag)
    }
    
    private func generate() {
        switch self.generateType {
        case .words: self.output = generateWords(length)
        case .sentences: self.output = generateSentences(length)
        case .paragraphs: self.output = generateParagraphs(length)
        }
    }
    
    private func generateParagraphs(_ count: Int) -> String {
        if count < 0 { return "" }
        return (0..<count).map{_ in generateSentences(.random(in: 3...6)) }.joined(separator: "\n\n")
    }
    private func generateSentences(_ count: Int) -> String {
        if count < 0 { return "" }
        return (0..<count).map{_ in generateWords(.random(in: 10...20)) }.map{ $0 + "." }.joined(separator: " ")
    }
    private func generateWords(_ count: Int) -> String {
        if count < 0 { return "" }
        return (0..<count).map{_ in wordSource.randomElement()! }.joined(separator: " ").capitalizingFirstLetter()
    }
}

enum LoremIpsumGenerateType: String, TextItem {
    case words = "Words"
    case sentences = "Sentences"
    case paragraphs = "Paragraphs"
    
    var title: String { rawValue.localized() }
}

final private class LoremIpsumGeneratorView: Page {
    let typePicker = EnumPopupButton<LoremIpsumGenerateType>()
    let lengthField = NumberField()
    
    let outputSection = TextViewSection(title: "Output".localized(), options: [.outputable, .copyable, .inputable])
    
    override func layout() {
        super.layout()
    
        self.outputSection.snp.remakeConstraints{ make in
            make.height.equalTo(max(240, self.frame.height - 230))
        }
    }
    
    override func onA
Download .txt
gitextract_01cekmvj/

├── .gitignore
├── CoreUtil/
│   ├── CoreUtil/
│   │   ├── Class/
│   │   │   ├── Action.swift
│   │   │   ├── Delta.swift
│   │   │   ├── NS+OnAwake.swift
│   │   │   ├── NSColorView.swift
│   │   │   ├── NSViewController+ChainObject.swift
│   │   │   ├── NSViewController+StateObject.swift
│   │   │   ├── Observable.swift
│   │   │   ├── PipeOperator.swift
│   │   │   ├── Query.swift
│   │   │   ├── Reachability+Publisher.swift
│   │   │   ├── Reachability.swift
│   │   │   ├── RestorableData.swift
│   │   │   ├── RestorableState.swift
│   │   │   ├── Terminal.swift
│   │   │   ├── ViewPlaceholder.swift
│   │   │   └── Zip3Sequence.swift
│   │   ├── CoreUtil.h
│   │   ├── ExceptionHanlder/
│   │   │   ├── ExceptionHandler.swift
│   │   │   ├── ExceptionHanlder.h
│   │   │   └── ExceptionHanlder.m
│   │   ├── Export.swift
│   │   ├── Extensions/
│   │   │   ├── Combine/
│   │   │   │   ├── Combine+ObjectBag.swift
│   │   │   │   ├── Combine+Peek.swift
│   │   │   │   ├── NSControl+Combine.swift
│   │   │   │   └── NSTextField+Combine.swift
│   │   │   ├── CoreGraphics/
│   │   │   │   ├── Ex+CGPoint.swift
│   │   │   │   ├── Ex+CGRect.swift
│   │   │   │   └── Ex+CGSize.swift
│   │   │   ├── Swift/
│   │   │   │   ├── Ex+Array.swift
│   │   │   │   ├── Ex+Clamp.swift
│   │   │   │   ├── Ex+Localize.swift
│   │   │   │   ├── Ex+Number.swift
│   │   │   │   └── Ex+OptionSet.swift
│   │   │   └── UI/
│   │   │       ├── Ex+CALayer.swift
│   │   │       ├── Ex+Image.swift
│   │   │       ├── Ex+NSColor.swift
│   │   │       ├── Ex+NSControl.swift
│   │   │       ├── Ex+NSEdgeInsets.swift
│   │   │       ├── Ex+NSEvent.swift
│   │   │       ├── Ex+NSMenuItem.swift
│   │   │       ├── Ex+NSPopover.swift
│   │   │       ├── Ex+NSTableView.swift
│   │   │       └── Ex+UI.swift
│   │   ├── HotKey/
│   │   │   ├── HotKey.swift
│   │   │   ├── Key.swift
│   │   │   └── NSEvent+HotKey.swift
│   │   └── Info.plist
│   └── CoreUtil.xcodeproj/
│       ├── project.pbxproj
│       └── project.xcworkspace/
│           ├── contents.xcworkspacedata
│           └── xcshareddata/
│               └── IDEWorkspaceChecks.plist
├── DevToys/
│   ├── DevToys/
│   │   ├── App/
│   │   │   ├── AppViewController.swift
│   │   │   └── AppWindowController.swift
│   │   ├── AppDelegate.swift
│   │   ├── Body/
│   │   │   ├── BodyViewController.swift
│   │   │   ├── Coder/
│   │   │   │   ├── Base64DecoderView+.swift
│   │   │   │   ├── HTMLDecoderView+.swift
│   │   │   │   ├── JWTDecoderView+.swift
│   │   │   │   └── URLDecoderView+.swift
│   │   │   ├── Convert/
│   │   │   │   ├── DateConverterView+.swift
│   │   │   │   ├── JSONYamlConverterView+.swift
│   │   │   │   └── NumberBaseConverterView+.swift
│   │   │   ├── Format/
│   │   │   │   ├── JSONFormatterView+.swift
│   │   │   │   ├── SQLFormatterView+.swift
│   │   │   │   └── XMLFormatterView+.swift
│   │   │   ├── Generator/
│   │   │   │   ├── ChecksumGeneratorView+.swift
│   │   │   │   ├── HashGeneratorView+.swift
│   │   │   │   ├── LoremIpsumGeneratorView+.swift
│   │   │   │   ├── QRCodeGeneratorView+.swift
│   │   │   │   └── UUIDGeneratorView+.swift
│   │   │   ├── Graphic/
│   │   │   │   ├── Icon Generator/
│   │   │   │   │   ├── Generators/
│   │   │   │   │   │   ├── AndroidIconGenerator.swift
│   │   │   │   │   │   ├── IOSIconGenerator.swift
│   │   │   │   │   │   ├── IcnsGenerator.swift
│   │   │   │   │   │   ├── IcoGenerator.swift
│   │   │   │   │   │   ├── IconFolderGenerator.swift
│   │   │   │   │   │   ├── IconGenerator+Model.swift
│   │   │   │   │   │   ├── IconsetGenerator.swift
│   │   │   │   │   │   ├── IosIconGenerator.swift
│   │   │   │   │   │   └── PngIconGenerator.swift
│   │   │   │   │   ├── Icon Templete/
│   │   │   │   │   │   ├── IconImageManager.swift
│   │   │   │   │   │   ├── IconSet.swift
│   │   │   │   │   │   ├── IconTemplete+.swift
│   │   │   │   │   │   └── IconTemplete.swift
│   │   │   │   │   └── IconGeneratorView+.swift
│   │   │   │   ├── Image Converter/
│   │   │   │   │   ├── Exporters/
│   │   │   │   │   │   ├── DefaultImageExporter.swift
│   │   │   │   │   │   ├── HeicImageExporter.swift
│   │   │   │   │   │   ├── WebpImageExporter.swift
│   │   │   │   │   │   └── cwebp
│   │   │   │   │   ├── ImageConverter.swift
│   │   │   │   │   └── ImageConverterView+.swift
│   │   │   │   ├── Image Optimizer/
│   │   │   │   │   ├── ImageOptimaizerView.swift
│   │   │   │   │   ├── ImageOptimizer.swift
│   │   │   │   │   ├── jpegoptim
│   │   │   │   │   └── optipng
│   │   │   │   ├── PDFGeneratorView+.swift
│   │   │   │   └── QRCodeReaderView+.swift
│   │   │   ├── HomeView+.swift
│   │   │   ├── Media/
│   │   │   │   ├── Audio Converter/
│   │   │   │   │   ├── AudioConverter.swift
│   │   │   │   │   ├── AudioConverterView+.swift
│   │   │   │   │   └── AudioFileScanner.swift
│   │   │   │   ├── Color Picker/
│   │   │   │   │   ├── Color.swift
│   │   │   │   │   ├── ColorPickerView+.swift
│   │   │   │   │   ├── Components/
│   │   │   │   │   │   ├── BoxHSBColorPicker.swift
│   │   │   │   │   │   ├── BrightnessBarView.swift
│   │   │   │   │   │   ├── CircleBarsHSBColorPicker.swift
│   │   │   │   │   │   ├── CircleBoxHSBColorPicker.swift
│   │   │   │   │   │   ├── CircleHueBarView.swift
│   │   │   │   │   │   ├── ColorBoxView.swift
│   │   │   │   │   │   ├── ColorPickerHandleLayer.swift
│   │   │   │   │   │   ├── ColorSampleView.swift
│   │   │   │   │   │   ├── HueBarView.swift
│   │   │   │   │   │   ├── OpacityBarView.swift
│   │   │   │   │   │   └── SaturationBarView.swift
│   │   │   │   │   ├── Pixel Picker/
│   │   │   │   │   │   ├── ACOverlayController.swift
│   │   │   │   │   │   ├── ACOverlayController.xib
│   │   │   │   │   │   ├── ACOverlayPanel.swift
│   │   │   │   │   │   ├── ACOverlayPreview.swift
│   │   │   │   │   │   ├── ACOverlayWrapper.swift
│   │   │   │   │   │   ├── ACPixelPicker.swift
│   │   │   │   │   │   └── Utils/
│   │   │   │   │   │       ├── Ex+CGImage.swift
│   │   │   │   │   │       ├── Ex+NSBezierPath.swift
│   │   │   │   │   │       ├── Ex+NSColor.swift
│   │   │   │   │   │       ├── ShowAndHideCursor.h
│   │   │   │   │   │       ├── ShowAndHideCursor.m
│   │   │   │   │   │       ├── ShowAndHideCursor.swift
│   │   │   │   │   │       └── Util+PixelPicker.swift
│   │   │   │   │   └── R+ColorPicker.swift
│   │   │   │   └── Movie to Gif/
│   │   │   │       ├── GifConverter.swift
│   │   │   │       └── GifConverterView+.swift
│   │   │   ├── SettingView+.swift
│   │   │   ├── Text/
│   │   │   │   ├── HyphenationRemoverView+.swift
│   │   │   │   ├── JSON Search/
│   │   │   │   │   ├── JSONNormalSearchView.swift
│   │   │   │   │   └── JSONSearchView+.swift
│   │   │   │   ├── RegexTesterView+.swift
│   │   │   │   ├── TextDiffView+.swift
│   │   │   │   └── TextInspectorView+.swift
│   │   │   └── Utils/
│   │   │       ├── CameraViewController.swift
│   │   │       ├── FileConflictAvoider.swift
│   │   │       ├── Identifier.swift
│   │   │       ├── ImageDropper.swift
│   │   │       ├── Slugify.swift
│   │   │       └── ffmpeg/
│   │   │           ├── FFMpegExecutor.swift
│   │   │           ├── FFProgressReport.swift
│   │   │           ├── FFTask.swift
│   │   │           ├── FFThumnailGenerator.swift
│   │   │           ├── FFTime.swift
│   │   │           └── ffmpeg
│   │   ├── Bridging-Header.h
│   │   ├── Component/
│   │   │   ├── Area.swift
│   │   │   ├── Button.swift
│   │   │   ├── CodeTextView.swift
│   │   │   ├── ControlBackgroundLayer.swift
│   │   │   ├── ControlContainer.swift
│   │   │   ├── DatePicker.swift
│   │   │   ├── DragImageView.swift
│   │   │   ├── EmptyImageTableView.swift
│   │   │   ├── FileDrop.swift
│   │   │   ├── ImageDropView.swift
│   │   │   ├── NumberField.swift
│   │   │   ├── Page.swift
│   │   │   ├── PopupButton.swift
│   │   │   ├── RegexTextView.swift
│   │   │   ├── Section.swift
│   │   │   ├── SectionButton+.swift
│   │   │   ├── SectionButton.swift
│   │   │   ├── TagCloudView.swift
│   │   │   ├── TextField.swift
│   │   │   ├── TextFieldSection.swift
│   │   │   ├── TextView.swift
│   │   │   ├── TextViewSection.swift
│   │   │   └── Toast.swift
│   │   ├── DevToys.entitlements
│   │   ├── Info.plist
│   │   ├── Model/
│   │   │   ├── AppModel.swift
│   │   │   ├── Settings.swift
│   │   │   ├── Tool+Default.swift
│   │   │   ├── ToolCategory+Default.swift
│   │   │   └── ToolManager+.swift
│   │   ├── Resource/
│   │   │   ├── Assets.xcassets/
│   │   │   │   ├── AccentColor.colorset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── Contents.json
│   │   │   │   ├── applewatch.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── carplay.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── check.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── clear.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── convert.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── copy.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── drop.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── error.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── export.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── format.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── hyphen.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── ipad.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── ipaddress.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── iphone.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── mac.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── network.status.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── number.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── open.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── paramators.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── paste.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── pulldown.indicator.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── search.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── settings.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── sidebar.disclosure.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── spacing.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── speed.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── spuit.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── stepper.down.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── stepper.up.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── text.imageset/
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── tool/
│   │   │   │   │   ├── Contents.json
│   │   │   │   │   ├── api.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── audio.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── base64.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── color.blindness.simulator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── color.picker.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── date.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── encoder.decoder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── gif.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── graphic.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── hash.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── home.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── html.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── icon.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── image.compressor.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── image.converter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── json.search.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── jwt.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── lorem.ipsum.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── markdown.preview.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── media.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── network.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── number.base.convert.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── pdf.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── qr.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── regex.tester.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── settings.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── sql.formatter.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.diff.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── text.inspector.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── url.coder.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   ├── uuid.generator.imageset/
│   │   │   │   │   │   └── Contents.json
│   │   │   │   │   └── xml.formatter.imageset/
│   │   │   │   │       └── Contents.json
│   │   │   │   └── transparent_background.imageset/
│   │   │   │       └── Contents.json
│   │   │   ├── Base.lproj/
│   │   │   │   └── Main.storyboard
│   │   │   ├── R.swift
│   │   │   ├── de.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── en.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── es.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── ja.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   ├── pt-BR.lproj/
│   │   │   │   ├── Localizable.strings
│   │   │   │   └── Main.strings
│   │   │   └── zh-Hans.lproj/
│   │   │       ├── Localizable.strings
│   │   │       └── Main.strings
│   │   └── Sidebar/
│   │       ├── SearchCell.swift
│   │       ├── SidebarView+.swift
│   │       ├── ToolCategoryCell.swift
│   │       ├── ToolMenuCell.swift
│   │       └── View/
│   │           └── Separator.swift
│   └── DevToys.xcodeproj/
│       ├── project.pbxproj
│       ├── project.xcworkspace/
│       │   ├── contents.xcworkspacedata
│       │   └── xcshareddata/
│       │       └── IDEWorkspaceChecks.plist
│       └── xcshareddata/
│           └── xcschemes/
│               └── DevToys.xcscheme
├── DevToys.xcworkspace/
│   ├── contents.xcworkspacedata
│   └── xcshareddata/
│       ├── IDEWorkspaceChecks.plist
│       └── swiftpm/
│           └── Package.resolved
├── LICENSE
├── README.md
├── Release Checklist.md
└── docs/
    ├── index.html
    └── sparkle/
        └── appcast.xml
Condensed preview — 282 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (977K chars).
[
  {
    "path": ".gitignore",
    "chars": 2188,
    "preview": "# Mac\n.DS_Store\n\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & "
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Action.swift",
    "chars": 337,
    "preview": "//\n//  Action.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/16.\n//  Copyright © 2022 yuki. All rights reserved.\n/"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Delta.swift",
    "chars": 2881,
    "preview": "//\n//  Delta.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/05/14.\n//  Copyright © 2020 yuki. All rights reserved.\n//"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NS+OnAwake.swift",
    "chars": 5858,
    "preview": "//\n//  NSLoadView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/08/31.\n//  Copyright © 2020 yuki. All rights reserve"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSColorView.swift",
    "chars": 819,
    "preview": "//\n//  NSColorView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/10/05.\n//  Copyright © 2021 yuki. All rights reserv"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSViewController+ChainObject.swift",
    "chars": 1524,
    "preview": "//\n//  NSViewController.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/07/19.\n//  Copyright © 2021 yuki. All rights r"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSViewController+StateObject.swift",
    "chars": 3257,
    "preview": "//\n//  NSViewController+StateObject.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/24.\n//  Copyright © 2021 yuki. "
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Observable.swift",
    "chars": 1081,
    "preview": "//\n//  Property.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/07/06.\n//  Copyright © 2020 yuki. All rights reserved."
  },
  {
    "path": "CoreUtil/CoreUtil/Class/PipeOperator.swift",
    "chars": 740,
    "preview": "//\n//  +Functions.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/10/01.\n//  Copyright © 2020 yuki. All rights reserve"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Query.swift",
    "chars": 1222,
    "preview": "//\n//  Query.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/01/13.\n//  Copyright © 2020 yuki. All rights reserved.\n//"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Reachability+Publisher.swift",
    "chars": 920,
    "preview": "//\n//  Reachability+Ex.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/09/14.\n//  Copyright © 2021 yuki. All rights re"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Reachability.swift",
    "chars": 13812,
    "preview": "/*\nCopyright (c) 2014, Ashley Mills\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or wit"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/RestorableData.swift",
    "chars": 3318,
    "preview": "//\n//  RestorableData.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport Cocoa\n\nextension FileManager {"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/RestorableState.swift",
    "chars": 2177,
    "preview": "//\n//  RestorableState.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport Foundation\n\n@propertyWrapper\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Terminal.swift",
    "chars": 1811,
    "preview": "//\n//  Terminal.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/11.\n//\n\nimport Foundation\n\npublic enum TerminalErro"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/ViewPlaceholder.swift",
    "chars": 910,
    "preview": "//\n//  ViewPlaceholder.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/03.\n//  Copyright © 2021 yuki. All rights re"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Zip3Sequence.swift",
    "chars": 2051,
    "preview": "//\n//  Zip3Sequence.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/22.\n//  Copyright © 2022 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/CoreUtil.h",
    "chars": 466,
    "preview": "//\n//  CoreUtil.h\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\n#import <Foundation/Foundation.h>\n#import \"Exce"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHandler.swift",
    "chars": 1446,
    "preview": "//\n//  ExceptionHandler.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights r"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.h",
    "chars": 463,
    "preview": "//\n//  ExceptionHanlder.h\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.m",
    "chars": 675,
    "preview": "//\n//  ExceptionHanlder.m\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/Export.swift",
    "chars": 177,
    "preview": "//\n//  Export.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\n@_exported import Promise\n@_exported import S"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/Combine+ObjectBag.swift",
    "chars": 754,
    "preview": "//\n//  NSObject+Combine.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/05/22.\n//  Copyright © 2020 yuki. All rights r"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/Combine+Peek.swift",
    "chars": 432,
    "preview": "//\n//  Combine+Peek.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport Combine\n\nextension Publisher {\n "
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/NSControl+Combine.swift",
    "chars": 1396,
    "preview": "//\n//  NSButton+Combine.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/07/23.\n//  Copyright © 2021 yuki. All rights r"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/NSTextField+Combine.swift",
    "chars": 2455,
    "preview": "//\n//  Combine+TextField.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/01/03.\n//  Copyright © 2021 yuki. All rights "
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGPoint.swift",
    "chars": 4204,
    "preview": "//\n//  Ex+CGPoint.swift\n//  Topica\n//\n//  Created by yuki on 2019/10/27.\n//  Copyright © 2019 yuki. All rights reserved."
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGRect.swift",
    "chars": 5197,
    "preview": "//\n//  Ex+CGRect.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/02/03.\n//  Copyright © 2020 yuki. All rights reserved"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGSize.swift",
    "chars": 4126,
    "preview": "import CoreGraphics\n\n\n@inlinable public func round(_ size: CGSize) -> CGSize {\n    CGSize(width: round(size.width), heig"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Array.swift",
    "chars": 3549,
    "preview": "//\n//  Extensions.swift\n//  DANMAKER\n//\n//  Created by yuki on 2015/06/24.\n//  Copyright © 2015 yuki. All rights reserve"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Clamp.swift",
    "chars": 1055,
    "preview": "//\n//  Ex+Comparable.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/04/01.\n//  Copyright © 2020 yuki. All rights rese"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Localize.swift",
    "chars": 213,
    "preview": "//\n//  Ex+Localize.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/13.\n//\n\nimport Foundation\n\nextension String {\n  "
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Number.swift",
    "chars": 1053,
    "preview": "//\n//  Ex+NUmber.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/06/24.\n//  Copyright © 2020 yuki. All rights reserved"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+OptionSet.swift",
    "chars": 292,
    "preview": "//\n//  Ex+OptionSet.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/04/13.\n//  Copyright © 2020 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+CALayer.swift",
    "chars": 808,
    "preview": "//\n//  Ex+CALayer.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/06/23.\n//  Copyright © 2020 yuki. All rights reserve"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+Image.swift",
    "chars": 811,
    "preview": "//\n//  Ex+Image.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/03/10.\n//  Copyright © 2020 yuki. All rights reserved."
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSColor.swift",
    "chars": 967,
    "preview": "import Cocoa\n\n// MARK: - Extension for Color\nextension NSColor {\n    public convenience init(colorSpace: NSColorSpace = "
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSControl.swift",
    "chars": 557,
    "preview": "//\n//  Ex+NSControl.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/10/28.\n//  Copyright © 2021 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSEdgeInsets.swift",
    "chars": 865,
    "preview": "//\n//  Ex+NSEdgeInsets.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\nextension NSEdgeInsets"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSEvent.swift",
    "chars": 296,
    "preview": "//\n//  NSEvent+Location.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/11/11.\n//  Copyright © 2021 yuki. All rights r"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSMenuItem.swift",
    "chars": 1676,
    "preview": "//\n//  Ex+NSMenuItem.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/08/20.\n//  Copyright © 2020 yuki. All rights rese"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSPopover.swift",
    "chars": 2079,
    "preview": "//\n//  Ex+NSPopover.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/05/31.\n//  Copyright © 2021 yuki. All rights reser"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSTableView.swift",
    "chars": 1104,
    "preview": "//\n//  Ex+NSTableView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\nextension NSTableView {"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+UI.swift",
    "chars": 264,
    "preview": "import Cocoa\n\npublic let NSOutlineViewNotificationItemKey = \"NSObject\"\n\nextension NSView {\n    #if DEBUG\n    public func"
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/HotKey.swift",
    "chars": 2403,
    "preview": "//\n//  KeyboardShortcut.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Carbon\nimport Cocoa\n\npublic "
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/Key.swift",
    "chars": 14023,
    "preview": "//\n//  Key.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Carbon\n\npublic enum Key {\n    // MARK: - "
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/NSEvent+HotKey.swift",
    "chars": 990,
    "preview": "//\n//  NSEvent+HotKey.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Cocoa\n\nextension NSEvent {\n   "
  },
  {
    "path": "CoreUtil/CoreUtil/Info.plist",
    "chars": 752,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "CoreUtil/CoreUtil.xcodeproj/project.pbxproj",
    "chars": 37045,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 52;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "CoreUtil/CoreUtil.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 135,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef"
  },
  {
    "path": "CoreUtil/CoreUtil.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "DevToys/DevToys/App/AppViewController.swift",
    "chars": 1151,
    "preview": "//\n//  ViewController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\nimport CoreUtil\n\nfinal cl"
  },
  {
    "path": "DevToys/DevToys/App/AppWindowController.swift",
    "chars": 3214,
    "preview": "//\n//  AppWindowController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport Darwin\nimp"
  },
  {
    "path": "DevToys/DevToys/AppDelegate.swift",
    "chars": 254,
    "preview": "//\n//  AppDelegate.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\n@main\nclass AppDelegate: NS"
  },
  {
    "path": "DevToys/DevToys/Body/BodyViewController.swift",
    "chars": 1074,
    "preview": "//\n//  BodyViewController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class BodyV"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/Base64DecoderView+.swift",
    "chars": 5618,
    "preview": "//\n//  Base64Decoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class Base64Deco"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/HTMLDecoderView+.swift",
    "chars": 1899,
    "preview": "//\n//  HTMLDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\nimport HTMLEntities\n\nfina"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/JWTDecoderView+.swift",
    "chars": 4117,
    "preview": "//\n//  JWTDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class JWTDecoderVie"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/URLDecoderView+.swift",
    "chars": 2253,
    "preview": "//\n//  URLDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class URLDecoderVie"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/DateConverterView+.swift",
    "chars": 3150,
    "preview": "//\n//  DateConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class DateConver"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/JSONYamlConverterView+.swift",
    "chars": 5100,
    "preview": "//\n//  JSONYamlConverter+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\nimport Yams\nimport"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/NumberBaseConverterView+.swift",
    "chars": 5309,
    "preview": "//\n//  NumberBaseConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class Numb"
  },
  {
    "path": "DevToys/DevToys/Body/Format/JSONFormatterView+.swift",
    "chars": 3059,
    "preview": "//\n//  JSONFormatter+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport SwiftJSONFormat"
  },
  {
    "path": "DevToys/DevToys/Body/Format/SQLFormatterView+.swift",
    "chars": 407,
    "preview": "//\n//  SQLFormatterView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nfinal class SQLFor"
  },
  {
    "path": "DevToys/DevToys/Body/Format/XMLFormatterView+.swift",
    "chars": 4787,
    "preview": "//\n//  XMLFormatter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class XMLFormatte"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/ChecksumGeneratorView+.swift",
    "chars": 3929,
    "preview": "//\n//  ChecksumGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class Checks"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/HashGeneratorView+.swift",
    "chars": 3332,
    "preview": "//\n//  HashGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\nimport CryptoSwift\n\nfin"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/LoremIpsumGeneratorView+.swift",
    "chars": 4008,
    "preview": "//\n//  LoremIpsumGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class Lore"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/QRCodeGeneratorView+.swift",
    "chars": 4247,
    "preview": "//\n//  QLCodeGeneratorView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/23.\n//\n\nimport CoreUtil\nimport CoreImage"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/UUIDGeneratorView+.swift",
    "chars": 3469,
    "preview": "//\n//  UUIDGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class UUIDGenera"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/AndroidIconGenerator.swift",
    "chars": 1887,
    "preview": "//\n//  AndroidIconGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\nenum AndroidIco"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IOSIconGenerator.swift",
    "chars": 10052,
    "preview": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IosIconGenerator "
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IcnsGenerator.swift",
    "chars": 1204,
    "preview": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IcnsGenerator {\n "
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IcoGenerator.swift",
    "chars": 851,
    "preview": "//\n//  IcoGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\n\nenum IcoGenerator {\n  "
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconFolderGenerator.swift",
    "chars": 666,
    "preview": "//\n//  IconFolderGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\nimport CoreGraphi"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconGenerator+Model.swift",
    "chars": 285,
    "preview": "//\n//  IconGenerator+Model.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nstruct IconGener"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconsetGenerator.swift",
    "chars": 767,
    "preview": "//\n//  IconsetGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IconsetGenerat"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IosIconGenerator.swift",
    "chars": 10052,
    "preview": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IosIconGenerator "
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/PngIconGenerator.swift",
    "chars": 1093,
    "preview": "//\n//  PNGGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport Foundation\n\nenum PngIconGenerator"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconImageManager.swift",
    "chars": 943,
    "preview": "//\n//  IconImageManager.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\nfinal class IconIma"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconSet.swift",
    "chars": 3205,
    "preview": "//\n//  IconSet.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\n\n\nstruct IconSet {\n    enum "
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconTemplete+.swift",
    "chars": 10219,
    "preview": "//\n//  FolderFillIconImage.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\nimport CoreGraphi"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconTemplete.swift",
    "chars": 403,
    "preview": "//\n//  IconImageManager+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\nprotocol IconTempl"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/IconGeneratorView+.swift",
    "chars": 10231,
    "preview": "//\n//  IconGeneratorView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nfinal class IconG"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/DefaultImageExporter.swift",
    "chars": 1953,
    "preview": "//\n//  DefaultImageExporter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport CoreUtil\n\nenum ImageExpor"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/HeicImageExporter.swift",
    "chars": 891,
    "preview": "//\n//  HeicConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport AVFoundation\nimport CoreUtil\n\nen"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/WebpImageExporter.swift",
    "chars": 1046,
    "preview": "//\n//  WebpExporter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport CoreUtil\n\nenum WebpExportError: E"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/ImageConverter.swift",
    "chars": 5956,
    "preview": "//\n//  ImageConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nstruct ImageConvertTa"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/ImageConverterView+.swift",
    "chars": 9750,
    "preview": "//\n//  ImageConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class ImageConv"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Optimizer/ImageOptimaizerView.swift",
    "chars": 7951,
    "preview": "//\n//  Image Optimizer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class ImageOpt"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Optimizer/ImageOptimizer.swift",
    "chars": 5356,
    "preview": "//\n//  ImageOptimizer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nstruct ImageOptimizeT"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/PDFGeneratorView+.swift",
    "chars": 10550,
    "preview": "//\n//  PDFGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nfinal class PDFGenerato"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/QRCodeReaderView+.swift",
    "chars": 7251,
    "preview": "//\n//  QRCodeReaderView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\nimport AVFoundation"
  },
  {
    "path": "DevToys/DevToys/Body/HomeView+.swift",
    "chars": 7142,
    "preview": "//\n//  HomeViewController+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass SearchView"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioConverter.swift",
    "chars": 1399,
    "preview": "//\n//  AudioConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nstruct AudioConvertOp"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioConverterView+.swift",
    "chars": 13304,
    "preview": "//\n//  AudioConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\nimport Quartz\n\nfinal c"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioFileScanner.swift",
    "chars": 1256,
    "preview": "//\n//  FileTreeScanner.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nenum AudioFileScanne"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Color.swift",
    "chars": 5873,
    "preview": "//\n//  Color.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nstruct Color: Codable {\n    va"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/ColorPickerView+.swift",
    "chars": 14043,
    "preview": "//\n//  ColorPickerView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal class ColorP"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/BoxHSBColorPicker.swift",
    "chars": 1153,
    "preview": "//\n//  BoxColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class BoxHSBCol"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/BrightnessBarView.swift",
    "chars": 1874,
    "preview": "//\n//  BrightnessBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class Bright"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleBarsHSBColorPicker.swift",
    "chars": 1432,
    "preview": "//\n//  CircleBarsHSBColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal clas"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleBoxHSBColorPicker.swift",
    "chars": 1206,
    "preview": "//\n//  CircleColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class Circle"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleHueBarView.swift",
    "chars": 2827,
    "preview": "//\n//  CircleHueBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal class Circle"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorBoxView.swift",
    "chars": 2361,
    "preview": "//\n//  ColorBoxView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class ColorBoxVie"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorPickerHandleLayer.swift",
    "chars": 1033,
    "preview": "//\n//  ColorPickerHandleLayer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nprivate let h"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorSampleView.swift",
    "chars": 949,
    "preview": "//\n//  ColorSampleView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class ColorSam"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/HueBarView.swift",
    "chars": 1724,
    "preview": "//\n//  HueBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class HueBarView: N"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/OpacityBarView.swift",
    "chars": 1724,
    "preview": "//\n//  OpacityBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class OpacityBa"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/SaturationBarView.swift",
    "chars": 1876,
    "preview": "//\n//  SaturationBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class Satura"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayController.swift",
    "chars": 8834,
    "preview": "//\n//  PPOverlayController.swift\n//  Pixel Picker\n//\n\nimport Cocoa\nimport Carbon.HIToolbox\n\nprivate let magnification = "
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayController.xib",
    "chars": 5744,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayPanel.swift",
    "chars": 999,
    "preview": "//\n//  ACOverlayPanel.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights "
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayPreview.swift",
    "chars": 2455,
    "preview": "//\n//  ACOverlayPreview.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All right"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayWrapper.swift",
    "chars": 467,
    "preview": "//\n//  ACOverlayWrapper.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All right"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACPixelPicker.swift",
    "chars": 985,
    "preview": "//\n//  ACPixelPicker.swift\n//  AxComponents\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights "
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+CGImage.swift",
    "chars": 2141,
    "preview": "//\n//  CGImage.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension CGImage {\n    func colorAt(x: Int, y: Int) -> NSColor "
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+NSBezierPath.swift",
    "chars": 663,
    "preview": "//\n//  NSBezierPath.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension NSBezierPath {\n    var cgPath: CGPath {\n        l"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+NSColor.swift",
    "chars": 764,
    "preview": "//\n//  NSColor.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension NSColor {\n    func image(withSize size: NSSize) -> NSI"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.h",
    "chars": 226,
    "preview": "//\n//  ShowAndHideCursor.h\n//  Pixel Picker\n//\n\n#ifndef ShowAndHideCursor_h\n#define ShowAndHideCursor_h\n\n#import <Founda"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.m",
    "chars": 229,
    "preview": "//\n//  ShowAndHideCursor.m\n//  Pixel Picker\n//\n\n#include \"ShowAndHideCursor.h\"\n\n// Unfortunately `kCGDirectMainDisplay` "
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.swift",
    "chars": 2361,
    "preview": "//\n//  ShowAndHideCursor.swift\n//  Pixel Picker\n//\n\nimport Foundation\nimport ApplicationServices\n\ntypealias notAPrivateA"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Util+PixelPicker.swift",
    "chars": 2439,
    "preview": "//\n//  Util.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nlet APP_NAME = Bundle.main.infoDictionary![kCFBundleNameKey as Stri"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/R+ColorPicker.swift",
    "chars": 217,
    "preview": "//\n//  R+ColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nextension R {\n    enum ColorPicker {\n//"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Movie to Gif/GifConverter.swift",
    "chars": 1713,
    "preview": "//\n//  GifConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nstr"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Movie to Gif/GifConverterView+.swift",
    "chars": 10424,
    "preview": "//\n//  MovieToGifView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\nimport CoreGraphics\nim"
  },
  {
    "path": "DevToys/DevToys/Body/SettingView+.swift",
    "chars": 1143,
    "preview": "//\n//  SettingView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/16.\n//\n\nimport CoreUtil\n\nfinal class SettingView"
  },
  {
    "path": "DevToys/DevToys/Body/Text/HyphenationRemoverView+.swift",
    "chars": 1821,
    "preview": "import CoreUtil\n\nfinal class HyphenationRemoverViewController: NSViewController {\n    @RestorableState(\"hyphenation.rawC"
  },
  {
    "path": "DevToys/DevToys/Body/Text/JSON Search/JSONNormalSearchView.swift",
    "chars": 261,
    "preview": "//\n//  JSONNormalSearchView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\n\nfinal class JSO"
  },
  {
    "path": "DevToys/DevToys/Body/Text/JSON Search/JSONSearchView+.swift",
    "chars": 824,
    "preview": "//\n//  JSONSearchView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\n\nfinal class JSONSearc"
  },
  {
    "path": "DevToys/DevToys/Body/Text/RegexTesterView+.swift",
    "chars": 2975,
    "preview": "//\n//  RegexTesterView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class RegexTe"
  },
  {
    "path": "DevToys/DevToys/Body/Text/TextDiffView+.swift",
    "chars": 4622,
    "preview": "//\n//  TextDiffView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/23.\n//\n\nimport DiffMatchPatch\nimport CoreUtil\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/TextInspectorView+.swift",
    "chars": 5571,
    "preview": "//\n//  TextInspector.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class TextInspec"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/CameraViewController.swift",
    "chars": 2229,
    "preview": "//\n//  ViewController.swift\n//  macOS Camera\n//\n//  Created by Mihail Șalari. on 4/24/17.\n//  Copyright © 2017 Mihail Șa"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/FileConflictAvoider.swift",
    "chars": 1312,
    "preview": "//\n//  FileConflictAvoider.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nenum FileConflic"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/Identifier.swift",
    "chars": 1522,
    "preview": "//\n//  Identifier.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/04/29.\n//  Copyright © 2021 yuki. All rights reserve"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ImageDropper.swift",
    "chars": 965,
    "preview": "//\n//  ImageDropper.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport Cocoa\n\nenum ImageDropper {\n    st"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/Slugify.swift",
    "chars": 8373,
    "preview": "//\n//  Slugify.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport Foundation\n\nextension String {\n    pub"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFMpegExecutor.swift",
    "chars": 3213,
    "preview": "//\n//  FFMpegExecutor.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\n\nenum FFExecutor {\n   "
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFProgressReport.swift",
    "chars": 1540,
    "preview": "//\n//  FFProgressReport.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\n\nstruct FFProgressRe"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFTask.swift",
    "chars": 696,
    "preview": "//\n//  FFTask.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nfinal class FFTask {\n    let "
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFThumnailGenerator.swift",
    "chars": 998,
    "preview": "//\n//  FFThumnailGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nenum FFThumnailG"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFTime.swift",
    "chars": 982,
    "preview": "//\n//  FFTime.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport Foundation\n\nstruct FFTime: CustomString"
  },
  {
    "path": "DevToys/DevToys/Bridging-Header.h",
    "chars": 194,
    "preview": "//\n//  Bridging-Header.h\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\n#ifndef Bridging_Header_h\n#define Bridgin"
  },
  {
    "path": "DevToys/DevToys/Component/Area.swift",
    "chars": 3504,
    "preview": "//\n//  ComponentBaseView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class Area: "
  },
  {
    "path": "DevToys/DevToys/Component/Button.swift",
    "chars": 1001,
    "preview": "//\n//  Button.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class Button: NSLoadBut"
  },
  {
    "path": "DevToys/DevToys/Component/CodeTextView.swift",
    "chars": 14857,
    "preview": "//\n//  CodeTextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport Highlightr\nimport"
  },
  {
    "path": "DevToys/DevToys/Component/ControlBackgroundLayer.swift",
    "chars": 1339,
    "preview": "//\n//  ControlBackgroundLayer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class C"
  },
  {
    "path": "DevToys/DevToys/Component/ControlContainer.swift",
    "chars": 3005,
    "preview": "//\n//  ComponentBaseView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class Contro"
  },
  {
    "path": "DevToys/DevToys/Component/DatePicker.swift",
    "chars": 1248,
    "preview": "//\n//  DatePicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class DatePicker: N"
  },
  {
    "path": "DevToys/DevToys/Component/DragImageView.swift",
    "chars": 2642,
    "preview": "//\n//  ImageBoxView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\nimport AppKit\n\nprotocol "
  },
  {
    "path": "DevToys/DevToys/Component/EmptyImageTableView.swift",
    "chars": 2082,
    "preview": "//\n//  EmptyImageTableView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nopen class Empty"
  },
  {
    "path": "DevToys/DevToys/Component/FileDrop.swift",
    "chars": 2182,
    "preview": "//\n//  FileDrop.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nfinal class FileDropSection"
  },
  {
    "path": "DevToys/DevToys/Component/ImageDropView.swift",
    "chars": 1825,
    "preview": "//\n//  ImageDropView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\nclass ImageDropView: N"
  },
  {
    "path": "DevToys/DevToys/Component/NumberField.swift",
    "chars": 6832,
    "preview": "//\n//  NumberField.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nfina"
  },
  {
    "path": "DevToys/DevToys/Component/Page.swift",
    "chars": 1813,
    "preview": "//\n//  ToolPage.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n \nclass Page: NSLoadView { \n"
  },
  {
    "path": "DevToys/DevToys/Component/PopupButton.swift",
    "chars": 2707,
    "preview": "//\n//  PopupButton.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nprotocol TextItem: CaseI"
  },
  {
    "path": "DevToys/DevToys/Component/RegexTextView.swift",
    "chars": 2009,
    "preview": "//\n//  RegexTextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class RegexTextV"
  },
  {
    "path": "DevToys/DevToys/Component/Section.swift",
    "chars": 2766,
    "preview": "//\n//  ControlStack.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass Section: NSLoadVi"
  },
  {
    "path": "DevToys/DevToys/Component/SectionButton+.swift",
    "chars": 3073,
    "preview": "//\n//  SectionButton+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class SearchSec"
  },
  {
    "path": "DevToys/DevToys/Component/SectionButton.swift",
    "chars": 2509,
    "preview": "//\n//  ControlStackButton.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass SectionButt"
  },
  {
    "path": "DevToys/DevToys/Component/TagCloudView.swift",
    "chars": 5978,
    "preview": "//\n//  TagCloudView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\n\nfinal class TagCloudVi"
  },
  {
    "path": "DevToys/DevToys/Component/TextField.swift",
    "chars": 3818,
    "preview": "//\n//  TextField.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class TextField: NSL"
  },
  {
    "path": "DevToys/DevToys/Component/TextFieldSection.swift",
    "chars": 1196,
    "preview": "//\n//  TextFieldSection.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nstruct TextFieldSec"
  },
  {
    "path": "DevToys/DevToys/Component/TextView.swift",
    "chars": 2262,
    "preview": "//\n//  TextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class TextView: NSLoa"
  },
  {
    "path": "DevToys/DevToys/Component/TextViewSection.swift",
    "chars": 3760,
    "preview": "//\n//  TextViewSection.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nstruct TextSectionOp"
  },
  {
    "path": "DevToys/DevToys/Component/Toast.swift",
    "chars": 10267,
    "preview": "//\n//  ACToast.swift\n//  AxComponents\n//\n//  Created by yuki on 2021/09/13.\n//  Copyright © 2021 yuki. All rights reserv"
  },
  {
    "path": "DevToys/DevToys/DevToys.entitlements",
    "chars": 301,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "DevToys/DevToys/Info.plist",
    "chars": 1350,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "DevToys/DevToys/Model/AppModel.swift",
    "chars": 573,
    "preview": "//\n//  AppModel.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nextension NSViewController "
  },
  {
    "path": "DevToys/DevToys/Model/Settings.swift",
    "chars": 383,
    "preview": "//\n//  Settings.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/16.\n//\n\nimport CoreUtil\n\nfinal class Settings {\n    "
  },
  {
    "path": "DevToys/DevToys/Model/Tool+Default.swift",
    "chars": 12331,
    "preview": "//\n//  Tool+Default.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/13.\n//\n\nimport CoreUtil\n\nextension Tool {\n    st"
  },
  {
    "path": "DevToys/DevToys/Model/ToolCategory+Default.swift",
    "chars": 1289,
    "preview": "//\n//  ToolCategory+Default.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/13.\n//\n\nextension ToolCategory {\n    sta"
  },
  {
    "path": "DevToys/DevToys/Model/ToolManager+.swift",
    "chars": 3389,
    "preview": "//\n//  ToolManager.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/12.\n//\n\nimport CoreUtil\nimport OrderedCollections"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/AccentColor.colorset/Contents.json",
    "chars": 123,
    "preview": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1301,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"icon_16x16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/Contents.json",
    "chars": 63,
    "preview": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/applewatch.imageset/Contents.json",
    "chars": 377,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"applewatch.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/carplay.imageset/Contents.json",
    "chars": 374,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"carplay.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/check.imageset/Contents.json",
    "chars": 314,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 22.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/clear.imageset/Contents.json",
    "chars": 372,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"clear.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n  "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/convert.imageset/Contents.json",
    "chars": 374,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"convert.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/copy.imageset/Contents.json",
    "chars": 371,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/drop.imageset/Contents.json",
    "chars": 371,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"drop.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/error.imageset/Contents.json",
    "chars": 314,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 23.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/export.imageset/Contents.json",
    "chars": 373,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"export.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/format.imageset/Contents.json",
    "chars": 373,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"format.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/hyphen.imageset/Contents.json",
    "chars": 373,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"hyphen.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/ipad.imageset/Contents.json",
    "chars": 371,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"ipad.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/ipaddress.imageset/Contents.json",
    "chars": 376,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"ipaddress.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/iphone.imageset/Contents.json",
    "chars": 373,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"iphone.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/mac.imageset/Contents.json",
    "chars": 370,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"mac.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n    "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/network.status.imageset/Contents.json",
    "chars": 381,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"network.status.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/number.imageset/Contents.json",
    "chars": 378,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 5.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n  "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/open.imageset/Contents.json",
    "chars": 371,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"open.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/paramators.imageset/Contents.json",
    "chars": 377,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"paramators.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n   "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/paste.imageset/Contents.json",
    "chars": 372,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"paste.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n  "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/pulldown.indicator.imageset/Contents.json",
    "chars": 379,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 26.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/search.imageset/Contents.json",
    "chars": 379,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 25.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n "
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/settings.imageset/Contents.json",
    "chars": 375,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"settings.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {"
  }
]

// ... and 82 more files (download for full content)

About this extraction

This page contains the full source code of the DevToys-app/DevToysMac GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 282 files (22.5 MB), approximately 260.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!