diff --git a/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/build-request.json b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/build-request.json new file mode 100644 index 00000000..38eab09c --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/build-request.json @@ -0,0 +1,27 @@ +{ + "buildCommand" : { + "command" : "build", + "skipDependencies" : false, + "style" : "buildOnly" + }, + "configuredTargets" : [ + + ], + "continueBuildingAfterErrors" : false, + "dependencyScope" : "workspace", + "enableIndexBuildArena" : false, + "hideShellScriptEnvironment" : false, + "parameters" : { + "action" : "build", + "overrides" : { + + } + }, + "qos" : "utility", + "schemeCommand" : "launch", + "showNonLoggedProgress" : true, + "useDryRun" : false, + "useImplicitDependencies" : false, + "useLegacyBuildLocations" : false, + "useParallelTargets" : true +} \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/description.msgpack b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/description.msgpack new file mode 100644 index 00000000..43049977 Binary files /dev/null and b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/description.msgpack differ diff --git a/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/manifest.json b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/manifest.json new file mode 100644 index 00000000..7391713b --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/manifest.json @@ -0,0 +1 @@ +{"client":{"name":"basic","version":0,"file-system":"device-agnostic","perform-ownership-analysis":"no"},"targets":{"":[""]},"commands":{"":{"tool":"phony","inputs":[""],"outputs":[""]},"P0:::Gate WorkspaceHeaderMapVFSFilesWritten":{"tool":"phony","inputs":[],"outputs":[""]}}} \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/target-graph.txt b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/target-graph.txt new file mode 100644 index 00000000..b83b1580 --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/target-graph.txt @@ -0,0 +1 @@ +Target dependency graph (0 target) \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/task-store.msgpack b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/task-store.msgpack new file mode 100644 index 00000000..6cef3fe3 Binary files /dev/null and b/CLDemo-OC/build/XCBuildData/0a2fcb2f923e9b62ba5f1b5c46b35d49.xcbuilddata/task-store.msgpack differ diff --git a/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/build-request.json b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/build-request.json new file mode 100644 index 00000000..38eab09c --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/build-request.json @@ -0,0 +1,27 @@ +{ + "buildCommand" : { + "command" : "build", + "skipDependencies" : false, + "style" : "buildOnly" + }, + "configuredTargets" : [ + + ], + "continueBuildingAfterErrors" : false, + "dependencyScope" : "workspace", + "enableIndexBuildArena" : false, + "hideShellScriptEnvironment" : false, + "parameters" : { + "action" : "build", + "overrides" : { + + } + }, + "qos" : "utility", + "schemeCommand" : "launch", + "showNonLoggedProgress" : true, + "useDryRun" : false, + "useImplicitDependencies" : false, + "useLegacyBuildLocations" : false, + "useParallelTargets" : true +} \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/description.msgpack b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/description.msgpack new file mode 100644 index 00000000..851c39f0 Binary files /dev/null and b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/description.msgpack differ diff --git a/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/manifest.json b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/manifest.json new file mode 100644 index 00000000..7391713b --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/manifest.json @@ -0,0 +1 @@ +{"client":{"name":"basic","version":0,"file-system":"device-agnostic","perform-ownership-analysis":"no"},"targets":{"":[""]},"commands":{"":{"tool":"phony","inputs":[""],"outputs":[""]},"P0:::Gate WorkspaceHeaderMapVFSFilesWritten":{"tool":"phony","inputs":[],"outputs":[""]}}} \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/target-graph.txt b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/target-graph.txt new file mode 100644 index 00000000..b83b1580 --- /dev/null +++ b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/target-graph.txt @@ -0,0 +1 @@ +Target dependency graph (0 target) \ No newline at end of file diff --git a/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/task-store.msgpack b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/task-store.msgpack new file mode 100644 index 00000000..6cef3fe3 Binary files /dev/null and b/CLDemo-OC/build/XCBuildData/c49f86284b5f2798667fdb536425c370.xcbuilddata/task-store.msgpack differ diff --git a/CLDemo-Swift/CLDemo-Swift.xcodeproj/project.pbxproj b/CLDemo-Swift/CLDemo-Swift.xcodeproj/project.pbxproj index e0c2509d..4c1f3982 100644 --- a/CLDemo-Swift/CLDemo-Swift.xcodeproj/project.pbxproj +++ b/CLDemo-Swift/CLDemo-Swift.xcodeproj/project.pbxproj @@ -2887,7 +2887,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 533J5B8T42; + DEVELOPMENT_TEAM = 3D47N4555T; ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ""; INFOPLIST_FILE = "$(SRCROOT)/CLDemo-Swift/Resource/Info.plist"; @@ -2918,7 +2918,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 533J5B8T42; + DEVELOPMENT_TEAM = 3D47N4555T; ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ""; INFOPLIST_FILE = "$(SRCROOT)/CLDemo-Swift/Resource/Info.plist"; diff --git a/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationController.swift b/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationController.swift index 95e2de11..1f788739 100644 --- a/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationController.swift +++ b/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationController.swift @@ -28,7 +28,7 @@ class CLTruncationController: CLController { private lazy var truncationLabel: CLTruncationLabel = { let view = CLTruncationLabel() - view.numberOfLines = 3 + view.numberOfLines = 5 view.contentEdgeInsets = .init(top: 10, left: 10, bottom: 10, right: 10) view.layer.cornerRadius = 5 view.layer.borderColor = UIColor.orange.cgColor diff --git a/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationLabel.swift b/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationLabel.swift index c89f33a4..8f60d59e 100644 --- a/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationLabel.swift +++ b/CLDemo-Swift/CLDemo-Swift/Class/CLTruncationController/CLTruncationLabel.swift @@ -93,7 +93,7 @@ extension CLTruncationLabel { let width = textLabel.bounds.width let lines = attributedText.lines(width) if numberOfLines > 0, - lines.count >= numberOfLines + lines.count > numberOfLines { let additionalAttributedText = isOpen ? truncationToken.close : truncationToken.open let length = lines.prefix(numberOfLines).reduce(0) { $0 + CTLineGetStringRange($1).length } diff --git a/Podfile.lock b/Podfile.lock index d40c4d44..9ac22ae7 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -110,4 +110,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 817a9f6635815ee132800871dcfecfd381ee2044 -COCOAPODS: 1.16.2 +COCOAPODS: 1.15.2 diff --git a/Pods/CLCamera/Camera/Contrller/CLCameraController.swift b/Pods/CLCamera/Camera/Contrller/CLCameraController.swift new file mode 100644 index 00000000..a7ac57ad --- /dev/null +++ b/Pods/CLCamera/Camera/Contrller/CLCameraController.swift @@ -0,0 +1,226 @@ +// +// CLCameraController.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import SnapKit +import UIKit + +// MARK: - JmoVxia---CLCameraViewControllerDelegate + +public protocol CLCameraControllerDelegate: AnyObject { + func cameraController(_ controller: CLCameraController, didFinishTakingPhoto photo: UIImage) + func cameraController(_ controller: CLCameraController, didFinishTakingVideo videoURL: URL) +} + +// MARK: - JmoVxia---类-属性 + +public class CLCameraController: UIViewController { + public init(config: ((inout CLCameraConfig) -> Void)? = nil) { + super.init(nibName: nil, bundle: nil) + modalPresentationStyle = .fullScreen + modalPresentationCapturesStatusBarAppearance = true + config?(&self.config) + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit {} + + private lazy var controlView: CLCameraControlView = { + let view = CLCameraControlView(config: config) + view.delegate = self + cameraHelper.setupPreviewLayer(to: view.previewContentView) + return view + }() + + private lazy var cameraHelper: CLCameraHelper = { + let helper = CLCameraHelper(config: config) + helper.delegate = self + return helper + }() + + private var config = CLCameraConfig() + + public weak var delegate: CLCameraControllerDelegate? +} + +// MARK: - JmoVxia---生命周期 + +public extension CLCameraController { + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + makeConstraints() + requestPermissions() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + } +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraController { + func setupUI() { + view.backgroundColor = .black + view.addSubview(controlView) + } + + func makeConstraints() { + controlView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} + +// MARK: - JmoVxia---数据 + +private extension CLCameraController { + func requestPermissions() { + CLPermissions.request([.camera, .microphone]) { state in + guard CLPermissions.isAllowed(.camera) else { return self.showError(.cameraPermissionDenied) } + guard CLPermissions.isAllowed(.microphone) else { return self.showError(.microphonePermissionDenied) } + DispatchQueue.main.async { + self.showAnimation() + } + } + } +} + +// MARK: - JmoVxia---override + +public extension CLCameraController { + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portrait + } + + override var prefersStatusBarHidden: Bool { + true + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraController {} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraController { + func showAnimation() { + controlView.showRunningAnimation() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { + self.controlView.showFocusAnimationAt(point: self.controlView.previewContentView.center) + } + } + + func stopRunning() { + cameraHelper.stopRunning() + } + + func showError(_ error: CLCameraError) { + let alert = UIAlertController(title: nil, message: error.localizedDescription, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "确定", style: .cancel, handler: { [weak self] _ in + self?.dismiss(animated: true, completion: nil) + })) + present(alert, animated: true, completion: nil) + } +} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraController {} + +// MARK: - JmoVxia---CLCameraHelperDelegate + +extension CLCameraController: CLCameraHelperDelegate { + func cameraHelper(_ helper: CLCameraHelper, didOccurError error: CLCameraError) { + showError(error) + } + + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingPhoto photo: UIImage) { + let controller = CLCameraImagePreviewController(image: photo) + controller.delegate = self + present(controller, animated: false, completion: nil) + } + + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingVideo url: URL) { + let controller = CLCameraVideoPreviewController(url: url) + controller.delegate = self + present(controller, animated: false, completion: nil) + } +} + +// MARK: - JmoVxia---CLCameraControlDelegate + +extension CLCameraController: CLCameraControlDelegate { + func cameraControlDidTapExit(_ controlView: CLCameraControlView) { + dismiss(animated: true, completion: nil) + } + + func cameraControlDidTapChangeCamera(_ controlView: CLCameraControlView) { + cameraHelper.switchCamera() + } + + func cameraControlDidTakePhoto(_ controlView: CLCameraControlView) { + cameraHelper.capturePhoto() + } + + func cameraControlDidBeginTakingVideo(_ controlView: CLCameraControlView) { + cameraHelper.startRecordingVideo() + } + + func cameraControlDidEndTakingVideo(_ controlView: CLCameraControlView) { + cameraHelper.stopRecordingVideo() + } + + func cameraControl(_ controlView: CLCameraControlView, didChangeVideoZoom zoomScale: Double) { + cameraHelper.zoom(zoomScale) + } + + func cameraControl(_ controlView: CLCameraControlView, didFocusAt point: CGPoint) { + cameraHelper.focusAt(point) + } + + func cameraControlDidPrepareForZoom(_ controlView: CLCameraControlView) { + cameraHelper.prepareForZoom() + } +} + +// MARK: - JmoVxia---CLCameraImagePreviewControllerDelegate + +extension CLCameraController: CLCameraImagePreviewControllerDelegate { + func imagePreviewController(_ controller: CLCameraImagePreviewController, didClickDoneButtonWith photo: UIImage) { + delegate?.cameraController(self, didFinishTakingPhoto: photo) + } +} + +// MARK: - JmoVxia---CLCameraControlDelegate + +extension CLCameraController: CLCameraVideoPreviewControllerDelegate { + func videoPreviewController(_ controller: CLCameraVideoPreviewController, didClickDoneButtonWith videoURL: URL) { + delegate?.cameraController(self, didFinishTakingVideo: videoURL) + } +} diff --git a/Pods/CLCamera/Camera/Contrller/CLCameraImagePreviewController.swift b/Pods/CLCamera/Camera/Contrller/CLCameraImagePreviewController.swift new file mode 100644 index 00000000..d59924f6 --- /dev/null +++ b/Pods/CLCamera/Camera/Contrller/CLCameraImagePreviewController.swift @@ -0,0 +1,201 @@ +// +// CLCameraImagePreviewController.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/20. +// + +import SnapKit +import UIKit + +// MARK: - JmoVxia---CLCameraVideoPreviewControllerDelegate + +protocol CLCameraImagePreviewControllerDelegate: AnyObject { + func imagePreviewController(_ controller: CLCameraImagePreviewController, didClickDoneButtonWith photo: UIImage) +} + +// MARK: - JmoVxia---类-属性 + +class CLCameraImagePreviewController: UIViewController { + init(image: UIImage) { + photo = image + super.init(nibName: nil, bundle: nil) + modalPresentationStyle = .fullScreen + modalPresentationCapturesStatusBarAppearance = true + previewImageView.image = image + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private lazy var mainStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = true + view.axis = .vertical + view.distribution = .fill + view.alignment = .fill + view.insetsLayoutMarginsFromSafeArea = false + view.isLayoutMarginsRelativeArrangement = true + view.layoutMargins = .zero + view.spacing = 0 + return view + }() + + private lazy var toolBar: CLCameraPreviewToolBar = { + let view = CLCameraPreviewToolBar() + view.setContentCompressionResistancePriority(.required, for: .vertical) + view.delegate = self + return view + }() + + private lazy var previewStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = true + view.axis = .vertical + view.distribution = .fill + view.alignment = .fill + view.insetsLayoutMarginsFromSafeArea = false + view.isLayoutMarginsRelativeArrangement = true + view.layoutMargins = .zero + view.spacing = 0 + return view + }() + + private lazy var previewScrollView: UIScrollView = { + let view = UIScrollView() + view.isUserInteractionEnabled = true + view.bounces = false + view.maximumZoomScale = 2.0 + view.minimumZoomScale = 1.0 + view.showsVerticalScrollIndicator = false + view.showsHorizontalScrollIndicator = false + view.delegate = self + view.backgroundColor = .clear + view.contentInsetAdjustmentBehavior = .never + return view + }() + + private lazy var previewImageView: UIImageView = { + let view = UIImageView() + view.isUserInteractionEnabled = false + view.clipsToBounds = true + view.contentMode = .scaleAspectFit + return view + }() + + private var photo: UIImage + + weak var delegate: CLCameraImagePreviewControllerDelegate? +} + +// MARK: - JmoVxia---生命周期 + +extension CLCameraImagePreviewController { + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + makeConstraints() + configData() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + } +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraImagePreviewController { + func setupUI() { + view.backgroundColor = .black + view.addSubview(mainStackView) + mainStackView.addArrangedSubview(previewStackView) + mainStackView.addArrangedSubview(toolBar) + previewStackView.addArrangedSubview(previewScrollView) + previewScrollView.addSubview(previewImageView) + } + + func makeConstraints() { + mainStackView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + previewImageView.snp.makeConstraints { make in + make.size.equalToSuperview() + make.center.equalToSuperview() + } + } +} + +// MARK: - JmoVxia---数据 + +private extension CLCameraImagePreviewController { + func configData() {} +} + +// MARK: - JmoVxia---override + +extension CLCameraImagePreviewController { + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portrait + } + + override var prefersStatusBarHidden: Bool { + true + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraImagePreviewController {} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraImagePreviewController {} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraImagePreviewController {} + +// MARK: - JmoVxia---CLCameraPreviewToolBarDelegate + +extension CLCameraImagePreviewController: CLCameraPreviewToolBarDelegate { + func didTapCancelButton(on toolBar: CLCameraPreviewToolBar) { + dismiss(animated: false, completion: nil) + } + + func didTapDoneButton(on toolBar: CLCameraPreviewToolBar) { + delegate?.imagePreviewController(self, didClickDoneButtonWith: photo) + } +} + +// MARK: - JmoVxia---UIScrollViewDelegate + +extension CLCameraImagePreviewController: UIScrollViewDelegate { + func viewForZooming(in scrollView: UIScrollView) -> UIView? { + previewImageView + } + + func scrollViewDidZoom(_ scrollView: UIScrollView) { + let x = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0) + scrollView.contentSize.width * 0.5 + let y = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0) + scrollView.contentSize.height * 0.5 + previewImageView.center = .init(x: x, y: y) + } +} diff --git a/Pods/CLCamera/Camera/Contrller/CLCameraVideoPreviewController.swift b/Pods/CLCamera/Camera/Contrller/CLCameraVideoPreviewController.swift new file mode 100644 index 00000000..fb44ce12 --- /dev/null +++ b/Pods/CLCamera/Camera/Contrller/CLCameraVideoPreviewController.swift @@ -0,0 +1,191 @@ +// +// CLCameraVideoPreviewController.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import AVFoundation +import SnapKit +import UIKit + +// MARK: - JmoVxia---CLCameraVideoPreviewControllerDelegate + +protocol CLCameraVideoPreviewControllerDelegate: AnyObject { + func videoPreviewController(_ controller: CLCameraVideoPreviewController, didClickDoneButtonWith videoURL: URL) +} + +// MARK: - JmoVxia---类-属性 + +class CLCameraVideoPreviewController: UIViewController { + init(url: URL) { + let session = AVAudioSession.sharedInstance() + try? session.setCategory(.playback) + try? session.setActive(true) + self.url = url + player = AVPlayer(playerItem: AVPlayerItem(asset: .init(url: url))) + playerLayer = AVPlayerLayer(player: player) + super.init(nibName: nil, bundle: nil) + modalPresentationStyle = .fullScreen + modalPresentationCapturesStatusBarAppearance = true + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: nil) + } + + private lazy var mainStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = true + view.axis = .vertical + view.distribution = .fill + view.alignment = .fill + view.insetsLayoutMarginsFromSafeArea = false + view.isLayoutMarginsRelativeArrangement = true + view.layoutMargins = .zero + view.spacing = 0 + return view + }() + + private lazy var toolBar: CLCameraPreviewToolBar = { + let view = CLCameraPreviewToolBar() + view.setContentCompressionResistancePriority(.required, for: .vertical) + view.delegate = self + return view + }() + + private lazy var previewStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = false + view.axis = .vertical + view.distribution = .fill + view.alignment = .fill + view.insetsLayoutMarginsFromSafeArea = false + view.isLayoutMarginsRelativeArrangement = true + view.layoutMargins = .zero + view.spacing = 0 + return view + }() + + private lazy var previewView: UIView = { + let view = UIView() + return view + }() + + private var url: URL + + private var player: AVPlayer + + private var playerLayer: AVPlayerLayer + + weak var delegate: CLCameraVideoPreviewControllerDelegate? +} + +// MARK: - JmoVxia---生命周期 + +extension CLCameraVideoPreviewController { + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + makeConstraints() + configData() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + } +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraVideoPreviewController { + func setupUI() { + view.backgroundColor = .black + view.addSubview(mainStackView) + mainStackView.addArrangedSubview(previewStackView) + mainStackView.addArrangedSubview(toolBar) + previewStackView.addArrangedSubview(previewView) + previewView.layer.addSublayer(playerLayer) + } + + func makeConstraints() { + mainStackView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} + +// MARK: - JmoVxia---数据 + +private extension CLCameraVideoPreviewController { + func configData() { + view.setNeedsDisplay() + view.layoutIfNeeded() + NotificationCenter.default.addObserver(self, selector: #selector(playToEndTime), name: .AVPlayerItemDidPlayToEndTime, object: nil) + playerLayer.videoGravity = .resizeAspectFill + playerLayer.frame = previewView.bounds + player.play() + } +} + +// MARK: - JmoVxia---override + +extension CLCameraVideoPreviewController { + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portrait + } + + override var prefersStatusBarHidden: Bool { + true + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraVideoPreviewController { + func playToEndTime() { + player.seek(to: .zero) + player.play() + } +} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraVideoPreviewController {} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraVideoPreviewController {} + +// MARK: - JmoVxia---CLCameraPreviewToolBarDelegate + +extension CLCameraVideoPreviewController: CLCameraPreviewToolBarDelegate { + func didTapCancelButton(on toolBar: CLCameraPreviewToolBar) { + dismiss(animated: false, completion: nil) + } + + func didTapDoneButton(on toolBar: CLCameraPreviewToolBar) { + delegate?.videoPreviewController(self, didClickDoneButtonWith: url) + } +} diff --git a/Pods/CLCamera/Camera/Extension/AVCaptureDevice+Extension.swift b/Pods/CLCamera/Camera/Extension/AVCaptureDevice+Extension.swift new file mode 100644 index 00000000..cbd0423c --- /dev/null +++ b/Pods/CLCamera/Camera/Extension/AVCaptureDevice+Extension.swift @@ -0,0 +1,30 @@ +// +// AVCaptureDevice+Extension.swift +// CLCarmera +// +// Created by Chen JmoVxia on 2024/2/27. +// + +import AVFoundation + +extension AVCaptureDevice { + func bestMatchingFormat(for cameraConfig: CLCameraConfig) -> AVCaptureDevice.Format? { + let compatibleFormats = formats.filter { format in + let formatDimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription) + let presetDimensions = cameraConfig.sessionPreset.size + + let hasMatchingSize = CGFloat(formatDimensions.width) == presetDimensions.width && + CGFloat(formatDimensions.height) == presetDimensions.height + + let supportsDesiredFrameRate = format.videoSupportedFrameRateRanges.contains { + $0.maxFrameRate >= cameraConfig.videoFrameRate + } + + let desiredStabilizationMode = cameraConfig.videoStabilizationMode.avPreferredVideoStabilizationMode + let supportsStabilizationMode = format.isVideoStabilizationModeSupported(desiredStabilizationMode) + + return hasMatchingSize && supportsDesiredFrameRate && supportsStabilizationMode + } + return compatibleFormats.last + } +} diff --git a/Pods/CLCamera/Camera/Extension/AVCapturePhoto+Extension.swift b/Pods/CLCamera/Camera/Extension/AVCapturePhoto+Extension.swift new file mode 100644 index 00000000..52547dd2 --- /dev/null +++ b/Pods/CLCamera/Camera/Extension/AVCapturePhoto+Extension.swift @@ -0,0 +1,26 @@ +// +// AVCapturePhoto+Extension.swift +// CLCarmera +// +// Created by Chen JmoVxia on 2024/2/28. +// + +import AVFoundation +import UIKit + +extension AVCapturePhoto { + func captureAsUIImage() -> UIImage? { + guard let data = fileDataRepresentation() else { return nil } + guard var image = CIImage(data: data) else { return nil } + + if let source = CGImageSourceCreateWithData(data as CFData, nil), + let metadata = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [String: Any], + let originalOrientation = metadata[kCGImagePropertyOrientation as String] as? Int32 + { + image = image.oriented(forExifOrientation: originalOrientation) + } + + guard let cgImage = CIContext().createCGImage(image, from: image.extent) else { return nil } + return UIImage(cgImage: cgImage) + } +} diff --git a/Pods/CLCamera/Camera/Extension/UIImage+Extension.swift b/Pods/CLCamera/Camera/Extension/UIImage+Extension.swift new file mode 100644 index 00000000..86d4b700 --- /dev/null +++ b/Pods/CLCamera/Camera/Extension/UIImage+Extension.swift @@ -0,0 +1,65 @@ +// +// UIImage+Extension.swift +// CLCarmera +// +// Created by Chen JmoVxia on 2024/2/27. +// + +import UIKit + +extension UIImage { + func rotated(by orientation: UIImage.Orientation) -> UIImage { + func swapWidthHeight(_ rect: inout CGRect) { + (rect.size.width, rect.size.height) = (rect.size.height, rect.size.width) + } + + let rect = CGRect(origin: .zero, size: size) + var bounds = rect + var transform = CGAffineTransform.identity + + switch orientation { + case .up: + return self + case .upMirrored: + transform = transform.translatedBy(x: rect.width, y: 0).scaledBy(x: -1, y: 1) + case .down: + transform = transform.translatedBy(x: rect.width, y: rect.height).rotated(by: .pi) + case .downMirrored: + transform = transform.translatedBy(x: 0, y: rect.height).scaledBy(x: 1, y: -1) + case .left: + swapWidthHeight(&bounds) + transform = transform.translatedBy(x: 0, y: rect.width).rotated(by: CGFloat.pi * 3 / 2) + case .leftMirrored: + swapWidthHeight(&bounds) + transform = transform.translatedBy(x: rect.height, y: rect.width).scaledBy(x: -1, y: 1).rotated(by: CGFloat.pi * 3 / 2) + case .right: + swapWidthHeight(&bounds) + transform = transform.translatedBy(x: rect.height, y: 0).rotated(by: CGFloat.pi / 2) + case .rightMirrored: + swapWidthHeight(&bounds) + transform = transform.scaledBy(x: -1, y: 1).rotated(by: CGFloat.pi / 2) + @unknown default: + return self + } + + UIGraphicsBeginImageContext(bounds.size) + defer { + UIGraphicsEndImageContext() + } + + guard let context = UIGraphicsGetCurrentContext() else { return self } + switch orientation { + case .left, .leftMirrored, .right, .rightMirrored: + context.scaleBy(x: -1, y: 1) + context.translateBy(x: -rect.height, y: 0) + default: + context.scaleBy(x: 1, y: -1) + context.translateBy(x: 0, y: -rect.height) + } + context.concatenate(transform) + if let cgImage { + context.draw(cgImage, in: rect) + } + return UIGraphicsGetImageFromCurrentImageContext() ?? self + } +} diff --git a/Pods/CLCamera/Camera/Model/CLCameraConfig.swift b/Pods/CLCamera/Camera/Model/CLCameraConfig.swift new file mode 100644 index 00000000..9d624ee3 --- /dev/null +++ b/Pods/CLCamera/Camera/Model/CLCameraConfig.swift @@ -0,0 +1,34 @@ +// +// CLCameraConfig.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import UIKit + +public struct CLCameraConfig { + /// 是否允许拍摄照片 + public var allowTakingPhoto: Bool = true + + /// 是否允许拍摄视频 + public var allowTakingVideo: Bool = true + + /// 视频拍摄最长时长 + public var maximumVideoDuration: TimeInterval = 60 + + /// 拍摄闪光灯开关 + public var flashMode: CLCameraFlashMode = .off + + /// 视频拍摄格式 + public var videoFileType: CLCameraVideoFileType = .mp4 + + /// 视频拍摄帧率 + public var videoFrameRate: Double = 60 + + /// 视频拍摄预设 + public var sessionPreset: CLCameraSessionPreset = .hd4K3840x2160 + + /// 视频拍摄防抖模式 + public var videoStabilizationMode: CLCameraVideoStabilizationMode = .off +} diff --git a/Pods/CLCamera/Camera/Model/CLCameraEnum.swift b/Pods/CLCamera/Camera/Model/CLCameraEnum.swift new file mode 100644 index 00000000..0ceb455f --- /dev/null +++ b/Pods/CLCamera/Camera/Model/CLCameraEnum.swift @@ -0,0 +1,113 @@ +// +// CLCameraEnum.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import AVFoundation +import UIKit + +// 拍摄闪光灯选项 +public enum CLCameraFlashMode { + case auto + case on + case off +} + +extension CLCameraFlashMode { + var avFlashMode: AVCaptureDevice.FlashMode { + switch self { + case .auto: .auto + case .on: .on + case .off: .off + } + } + + var cameraFlashMode: UIImagePickerController.CameraFlashMode { + switch self { + case .auto: .auto + case .on: .on + case .off: .off + } + } +} + +// 拍摄视频稳定配置 +public enum CLCameraVideoStabilizationMode { + case auto + case off + case standard + case cinematic + @available(iOS 13.0, *) + case cinematicExtended +} + +extension CLCameraVideoStabilizationMode { + var avPreferredVideoStabilizationMode: AVCaptureVideoStabilizationMode { + switch self { + case .auto: return .auto + case .off: return .off + case .standard: return .standard + case .cinematic: return .cinematic + case .cinematicExtended: + if #available(iOS 13.0, *) { + return .cinematicExtended + } + return .auto + } + } +} + +// 拍摄视频预设 +public enum CLCameraSessionPreset { + case cif352x288 + case vga640x480 + case hd1280x720 + case hd1920x1080 + case hd4K3840x2160 +} + +extension CLCameraSessionPreset { + var avSessionPreset: AVCaptureSession.Preset { + switch self { + case .cif352x288: .cif352x288 + case .vga640x480: .vga640x480 + case .hd1280x720: .hd1280x720 + case .hd1920x1080: .hd1920x1080 + case .hd4K3840x2160: .hd4K3840x2160 + } + } + + var size: CGSize { + switch self { + case .cif352x288: CGSize(width: 352, height: 288) + case .vga640x480: CGSize(width: 640, height: 480) + case .hd1280x720: CGSize(width: 1280, height: 720) + case .hd1920x1080: CGSize(width: 1920, height: 1080) + case .hd4K3840x2160: CGSize(width: 3840, height: 2160) + } + } +} + +// 拍摄视频格式 +public enum CLCameraVideoFileType { + case mp4 + case mov +} + +extension CLCameraVideoFileType { + var avFileType: AVFileType { + switch self { + case .mov: .mov + case .mp4: .mp4 + } + } + + var suffix: String { + switch self { + case .mov: ".mov" + case .mp4: ".mp4" + } + } +} diff --git a/Pods/CLCamera/Camera/Model/CLCameraError.swift b/Pods/CLCamera/Camera/Model/CLCameraError.swift new file mode 100644 index 00000000..e9db8123 --- /dev/null +++ b/Pods/CLCamera/Camera/Model/CLCameraError.swift @@ -0,0 +1,36 @@ +// +// CLCameraError.swift +// CLCamera +// +// Created by Chen JmoVxia on 2022/1/1. +// + +import UIKit + +enum CLCameraError { + case failedToInitializeCameraDevice + case failedToInitializeMicrophoneDevice + case cameraPermissionDenied + case microphonePermissionDenied + case imageNotFound + case underlying(Error) +} + +extension CLCameraError: LocalizedError { + var errorDescription: String? { + switch self { + case .failedToInitializeCameraDevice: + "相机初始化失败" + case .failedToInitializeMicrophoneDevice: + "麦克风初始化失败" + case .cameraPermissionDenied: + "无法获取相机权限,请在“设置”中允许访问相机" + case .microphonePermissionDenied: + "无法获取麦克风权限,请在“设置”中允许访问麦克风" + case .imageNotFound: + "获取图片失败" + case let .underlying(error): + error.localizedDescription + } + } +} diff --git a/Pods/CLCamera/Camera/Model/CLCameraHelper.swift b/Pods/CLCamera/Camera/Model/CLCameraHelper.swift new file mode 100644 index 00000000..ed4ea644 --- /dev/null +++ b/Pods/CLCamera/Camera/Model/CLCameraHelper.swift @@ -0,0 +1,341 @@ +// +// CLCameraHelper.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import AVFoundation +import UIKit + +protocol CLCameraHelperDelegate: AnyObject { + func cameraHelper(_ helper: CLCameraHelper, didOccurError error: CLCameraError) + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingPhoto photo: UIImage) + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingVideo url: URL) +} + +extension CLCameraHelperDelegate { + func cameraHelper(_ helper: CLCameraHelper, didOccurError error: CLCameraError) {} + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingPhoto photo: UIImage) {} + func cameraHelper(_ helper: CLCameraHelper, didFinishTakingVideo url: URL) {} +} + +class CLCameraHelper: NSObject { + init(config: CLCameraConfig) { + self.config = config + super.init() + initializeCameraSession() + } + + deinit { + try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation) + } + + weak var delegate: CLCameraHelperDelegate? + + private let orientation = CLCameraOrientation() + private let sessionQueue = DispatchQueue(label: "com.Camera.Session") + private let movieFileOutputQueue = DispatchQueue(label: "com.Camera.Movie") + private let photoOutputQueue = DispatchQueue(label: "com.Camera.Photo") + private let captureSession = AVCaptureSession() + private let photoOutput = AVCapturePhotoOutput() + private let movieFileOutput = AVCaptureMovieFileOutput() + private var videoDeviceInput: AVCaptureDeviceInput? + private var audioDeviceInput: AVCaptureDeviceInput? + private var videoCurrentZoom = 1.0 + private var currentOrientation = CLCameraOrientation.CaptureOrientation.up + private var config: CLCameraConfig + private lazy var previewLayer: AVCaptureVideoPreviewLayer = { + let layer = AVCaptureVideoPreviewLayer(session: captureSession) + layer.videoGravity = .resizeAspectFill + layer.frame = .init(origin: .zero, size: .init(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.size.height - 130 - safeAreaInsets.bottom)) + return layer + }() + + /// 切换到主线程同步执行 + @discardableResult private func mainSync(execute block: () -> T) -> T { + guard !Thread.isMainThread else { return block() } + return DispatchQueue.main.sync { block() } + } + + /// 安全区域 + private var safeAreaInsets: UIEdgeInsets { mainSync { keyWindow?.safeAreaInsets ?? .zero } } + + /// keyWindow + private var keyWindow: UIWindow? { + mainSync { + if #available(iOS 13.0, *) { + UIApplication.shared.connectedScenes + .compactMap { $0 as? UIWindowScene } + .flatMap(\.windows) + .first { $0.isKeyWindow } + } else { + UIApplication.shared.keyWindow + } + } + } +} + +private extension CLCameraHelper { + func initializeCameraSession() { + try? AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation) + orientation.delegate = self + sessionQueue.async { [weak self] in + self?.setupCapture() + self?.startRunning() + } + } + + func setupCapture() { + captureSession.beginConfiguration() + + let sessionPreset = config.sessionPreset.avSessionPreset + if captureSession.canSetSessionPreset(sessionPreset) { + captureSession.sessionPreset = sessionPreset + } else { + captureSession.sessionPreset = CLCameraSessionPreset.hd1920x1080.avSessionPreset + } + + setupDataOutput() + setupCameraDevice(position: .back) + setupMicrophoneDevice() + + captureSession.commitConfiguration() + } + + func setupDataOutput() { + photoOutput.isHighResolutionCaptureEnabled = true + if captureSession.canAddOutput(photoOutput) { + captureSession.addOutput(photoOutput) + } + + movieFileOutput.movieFragmentInterval = .invalid + if captureSession.canAddOutput(movieFileOutput) { + captureSession.addOutput(movieFileOutput) + } + } + + func setupCameraDevice(position: AVCaptureDevice.Position) { + if let videoDeviceInput = self.videoDeviceInput { + captureSession.removeInput(videoDeviceInput) + } + guard let videoDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], + mediaType: .video, + position: position).devices.first, + let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice) + else { + delegate?.cameraHelper(self, didOccurError: .failedToInitializeCameraDevice) + return + } + self.videoDeviceInput = videoDeviceInput + + if captureSession.canAddInput(videoDeviceInput) { + captureSession.addInput(videoDeviceInput) + } + + try? videoDevice.lockForConfiguration() + + videoDevice.isSubjectAreaChangeMonitoringEnabled = true + if videoDevice.isSmoothAutoFocusSupported { + videoDevice.isSmoothAutoFocusEnabled = true + } + + if let availableActiveFormat = videoDevice.bestMatchingFormat(for: config) { + videoDevice.activeFormat = availableActiveFormat + let frameDuration = CMTime(value: 1, timescale: CMTimeScale(config.videoFrameRate)) + videoDevice.activeVideoMinFrameDuration = frameDuration + videoDevice.activeVideoMaxFrameDuration = frameDuration + } + + if let connection = movieFileOutput.connection(with: .video) { + let stabilizationMode = config.videoStabilizationMode.avPreferredVideoStabilizationMode + connection.preferredVideoStabilizationMode = stabilizationMode + if connection.isVideoMirroringSupported { + connection.isVideoMirrored = position == .front + } + } + + if let connection = photoOutput.connection(with: .video), + connection.isVideoMirroringSupported + { + connection.isVideoMirrored = position == .front + } + + videoDevice.unlockForConfiguration() + } + + func setupMicrophoneDevice() { + guard let audioDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInMicrophone], + mediaType: .audio, + position: .unspecified).devices.first, + let audioDeviceInput = try? AVCaptureDeviceInput(device: audioDevice) + else { + delegate?.cameraHelper(self, didOccurError: .failedToInitializeMicrophoneDevice) + return + } + self.audioDeviceInput = audioDeviceInput + if captureSession.canAddInput(audioDeviceInput) { + captureSession.addInput(audioDeviceInput) + } + } + + func lockVideoDeviceForConfiguration(_ closure: (AVCaptureDevice) -> Void) { + guard let videoDeviceInput else { return } + let captureDevice = videoDeviceInput.device + try? captureDevice.lockForConfiguration() + closure(captureDevice) + captureDevice.unlockForConfiguration() + } +} + +extension CLCameraHelper { + func startRunning() { + orientation.startDeviceMotionUpdates() + sessionQueue.async { [weak self] in + guard let self, !captureSession.isRunning else { return } + captureSession.startRunning() + zoom(1.0) + } + } + + func stopRunning() { + orientation.stopDeviceMotionUpdates() + sessionQueue.async { [weak self] in + guard let self, captureSession.isRunning else { return } + captureSession.stopRunning() + } + } +} + +extension CLCameraHelper { + func setupPreviewLayer(to superView: UIView) { + superView.layer.addSublayer(previewLayer) + } +} + +extension CLCameraHelper { + func capturePhoto() { + photoOutputQueue.async { [weak self] in + guard let self else { return } + let settings = AVCapturePhotoSettings() + settings.flashMode = config.flashMode.avFlashMode + settings.isAutoStillImageStabilizationEnabled = photoOutput.isStillImageStabilizationSupported + photoOutput.capturePhoto(with: settings, delegate: self) + } + } + + func startRecordingVideo() { + func createCaptureVideoPath(fileType: CLCameraVideoFileType) -> String { + let directoryPath = NSTemporaryDirectory() + "CLCamera/" + "Video" + "/" + if !FileManager.default.fileExists(atPath: directoryPath) { + try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directoryPath), + withIntermediateDirectories: true, + attributes: nil) + } + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "YYYY-MM-DD_HH-MM-SS.SSS" + return directoryPath + dateFormatter.string(from: Date()) + fileType.suffix + } + movieFileOutputQueue.async { [weak self] in + guard let self else { return } + guard let connection = movieFileOutput.connection(with: .video) else { return } + let videoPath = createCaptureVideoPath(fileType: config.videoFileType) + let fileUrl = URL(fileURLWithPath: videoPath) + connection.videoOrientation = currentOrientation.captureVideoOrientation + movieFileOutput.startRecording(to: fileUrl, recordingDelegate: self) + } + } + + func stopRecordingVideo() { + CLLoadingHUD.showLoading() + movieFileOutputQueue.async { [weak self] in + self?.movieFileOutput.stopRecording() + } + } +} + +extension CLCameraHelper { + func switchCamera() { + if movieFileOutput.isRecording { return } + + guard let videoDeviceInput else { return } + let currentPosition = videoDeviceInput.device.position + var toChangePosition = AVCaptureDevice.Position.front + if currentPosition == .front { + toChangePosition = .back + } + + sessionQueue.async { [weak self] in + self?.captureSession.beginConfiguration() + self?.setupCameraDevice(position: toChangePosition) + self?.captureSession.commitConfiguration() + } + } + + func prepareForZoom() { + guard let videoDeviceInput else { return } + videoCurrentZoom = Double(videoDeviceInput.device.videoZoomFactor) + } + + func focusAt(_ point: CGPoint) { + lockVideoDeviceForConfiguration { [weak self] device in + guard let self else { return } + let cameraPoint = previewLayer.captureDevicePointConverted(fromLayerPoint: point) + + if device.isFocusModeSupported(.continuousAutoFocus) { + device.focusMode = .continuousAutoFocus + } + if device.isFocusPointOfInterestSupported { + device.focusPointOfInterest = cameraPoint + } + if device.isExposurePointOfInterestSupported { + device.exposurePointOfInterest = cameraPoint + } + if device.isExposureModeSupported(.continuousAutoExposure) { + device.exposureMode = .continuousAutoExposure + } + } + } + + func zoom(_ multiple: Double) { + guard let videoDeviceInput else { return } + let videoMaxZoomFactor = min(5, videoDeviceInput.device.activeFormat.videoMaxZoomFactor) + let toZoomFactor = max(1, videoCurrentZoom * multiple) + let finalZoomFactor = min(toZoomFactor, videoMaxZoomFactor) + lockVideoDeviceForConfiguration { device in + device.videoZoomFactor = CGFloat(finalZoomFactor) + } + } +} + +extension CLCameraHelper: CLCameraOrientationDelegate { + func captureOrientation(_ deviceOrientation: CLCameraOrientation, didUpdateOrientation orientation: CLCameraOrientation.CaptureOrientation) { + currentOrientation = orientation + print(orientation) + } +} + +extension CLCameraHelper: AVCapturePhotoCaptureDelegate { + func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { + if let error { + delegate?.cameraHelper(self, didOccurError: .underlying(error)) + } else if let image = photo.captureAsUIImage()?.rotated(by: currentOrientation.imageOrientation) { + delegate?.cameraHelper(self, didFinishTakingPhoto: image) + } else { + delegate?.cameraHelper(self, didOccurError: .imageNotFound) + } + } +} + +extension CLCameraHelper: AVCaptureFileOutputRecordingDelegate { + func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { + CLLoadingHUD.hideLoading() + DispatchQueue.main.async { + if let error { + self.delegate?.cameraHelper(self, didOccurError: .underlying(error)) + } else { + self.delegate?.cameraHelper(self, didFinishTakingVideo: outputFileURL) + } + } + } +} diff --git a/Pods/CLCamera/Camera/Model/CLCameraOrientation.swift b/Pods/CLCamera/Camera/Model/CLCameraOrientation.swift new file mode 100644 index 00000000..1676302a --- /dev/null +++ b/Pods/CLCamera/Camera/Model/CLCameraOrientation.swift @@ -0,0 +1,102 @@ +// +// CLCameraOrientation.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/27. +// + +import AVFoundation +import CoreMotion +import UIKit + +protocol CLCameraOrientationDelegate: AnyObject { + func captureOrientation(_ deviceOrientation: CLCameraOrientation, didUpdateOrientation orientation: CLCameraOrientation.CaptureOrientation) +} + +extension CLCameraOrientation { + enum CaptureOrientation { + case up + case left + case down + case right + + var captureVideoOrientation: AVCaptureVideoOrientation { + switch self { + case .up: + .portrait + case .left: + .landscapeRight + case .down: + .portraitUpsideDown + case .right: + .landscapeLeft + } + } + + var imageOrientation: UIImage.Orientation { + switch self { + case .up: + .up + case .left: + .left + case .down: + .down + case .right: + .right + } + } + } +} + +class CLCameraOrientation: NSObject { + weak var delegate: CLCameraOrientationDelegate? + + private var orientation = CLCameraOrientation.CaptureOrientation.up { + didSet { + guard orientation != oldValue else { return } + delegate?.captureOrientation(self, didUpdateOrientation: orientation) + } + } + + private lazy var motionManager: CMMotionManager = { + let manager = CMMotionManager() + manager.deviceMotionUpdateInterval = 0.5 + return manager + }() +} + +extension CLCameraOrientation { + func startDeviceMotionUpdates() { + if motionManager.isDeviceMotionAvailable, + let queue = OperationQueue.current + { + motionManager.startDeviceMotionUpdates(to: queue) { [weak self] motion, _ in + guard let motion else { return } + self?.handleDeviceMotionUpdate(motion) + } + } + } + + func stopDeviceMotionUpdates() { + motionManager.stopDeviceMotionUpdates() + } +} + +private extension CLCameraOrientation { + func handleDeviceMotionUpdate(_ motion: CMDeviceMotion) { + let sensitive = 0.77 + let x = motion.gravity.x + let y = motion.gravity.y + + if y < 0, fabs(y) > sensitive { + orientation = .up + } else if y > sensitive { + orientation = .down + } + if x < 0, fabs(x) > sensitive { + orientation = .left + } else if x > sensitive { + orientation = .right + } + } +} diff --git a/Pods/CLCamera/Camera/Permissions/CLPermissionInterface.swift b/Pods/CLCamera/Camera/Permissions/CLPermissionInterface.swift new file mode 100644 index 00000000..d47c537f --- /dev/null +++ b/Pods/CLCamera/Camera/Permissions/CLPermissionInterface.swift @@ -0,0 +1,162 @@ +// +// CLPermissionInterface.swift +// CLCamera +// +// Created by JmoVxia on 2020/7/1. +// Copyright © 2020 JmoVxia. All rights reserved. +// + +import Photos +import UIKit + +enum CLAuthorizationStatus { + /// 未知状态 + case unknown + /// 用户未选择 + case notDetermined + /// 用户没有权限 + case restricted + /// 拒绝 + case denied + /// 允许 + case authorized + /// 临时允许 + case provisional + /// 设备不支持 + case noSupport + /// 是否可以访问 + var isAuthorized: Bool { + self == .authorized || self == .provisional + } + + /// 是否不支持 + var isNoSupport: Bool { + self == .noSupport + } +} + +protocol CLPermissionInterface { + /// 是否允许 + var isAuthorized: Bool { get } + /// 是否拒绝 + var isDenied: Bool { get } + /// 请求权限 + func request(сompletionCallback: ((CLAuthorizationStatus) -> Void)?) +} + +/// 相册权限 +struct CLPhotoLibraryPermission: CLPermissionInterface { + var isAuthorized: Bool { + PHPhotoLibrary.authorizationStatus() == .authorized + } + + var isDenied: Bool { + PHPhotoLibrary.authorizationStatus() == .denied + } + + func request(сompletionCallback: ((CLAuthorizationStatus) -> Void)?) { + if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { + var authorizationStatus: CLAuthorizationStatus = .unknown + switch PHPhotoLibrary.authorizationStatus() { + case .authorized: + authorizationStatus = .authorized + case .notDetermined: + authorizationStatus = .notDetermined + case .restricted: + authorizationStatus = .restricted + case .denied: + authorizationStatus = .denied + default: + authorizationStatus = .unknown + } + if authorizationStatus == .notDetermined { + PHPhotoLibrary.requestAuthorization { status in + if status == .authorized { + authorizationStatus = .authorized + } else if status == .denied { + authorizationStatus = .denied + } + сompletionCallback?(authorizationStatus) + } + } else { + сompletionCallback?(authorizationStatus) + } + } else { + сompletionCallback?(.noSupport) + } + } +} + +/// 相机权限 +struct CLCameraPermission: CLPermissionInterface { + var isAuthorized: Bool { + AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.authorized + } + + var isDenied: Bool { + AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.denied + } + + func request(сompletionCallback: ((CLAuthorizationStatus) -> Void)?) { + if UIImagePickerController.isSourceTypeAvailable(.camera) { + var authorizationStatus: CLAuthorizationStatus = .unknown + switch AVCaptureDevice.authorizationStatus(for: .video) { + case .authorized: + authorizationStatus = .authorized + case .notDetermined: + authorizationStatus = .notDetermined + case .restricted: + authorizationStatus = .restricted + case .denied: + authorizationStatus = .denied + default: + authorizationStatus = .unknown + } + if authorizationStatus == .notDetermined { + AVCaptureDevice.requestAccess(for: .video) { authorized in + сompletionCallback?(authorized ? .authorized : .denied) + } + } else { + сompletionCallback?(authorizationStatus) + } + } else { + сompletionCallback?(.noSupport) + } + } +} + +/// 麦克风权限 +struct CLMicrophonePermission: CLPermissionInterface { + var isAuthorized: Bool { + AVAudioSession.sharedInstance().recordPermission == .granted + } + + var isDenied: Bool { + AVAudioSession.sharedInstance().recordPermission == .denied + } + + func request(сompletionCallback: ((CLAuthorizationStatus) -> Void)?) { + if AVAudioSession.sharedInstance().isInputAvailable { + var authorizationStatus: CLAuthorizationStatus = .unknown + switch AVAudioSession.sharedInstance().recordPermission { + case .undetermined: + authorizationStatus = .notDetermined + case .granted: + authorizationStatus = .authorized + case .denied: + authorizationStatus = .denied + default: + authorizationStatus = .unknown + } + if authorizationStatus == .notDetermined { + AVAudioSession.sharedInstance().requestRecordPermission { granted in + сompletionCallback?(granted ? .authorized : .denied) + } + } else { + сompletionCallback?(authorizationStatus) + } + } else { + сompletionCallback?(.noSupport) + } + } +} diff --git a/Pods/CLCamera/Camera/Permissions/CLPermissions.swift b/Pods/CLCamera/Camera/Permissions/CLPermissions.swift new file mode 100644 index 00000000..e0f2bd92 --- /dev/null +++ b/Pods/CLCamera/Camera/Permissions/CLPermissions.swift @@ -0,0 +1,69 @@ +// +// CLPermissions.swift +// CLCamera +// +// Created by JmoVxia on 2020/6/30. +// Copyright © 2020 JmoVxia. All rights reserved. +// + +import AVFoundation +import Photos +import UIKit + +class CLPermissions: NSObject { + enum CLPermissionType: Int { + /// 相机 + case camera = 0 + /// 相册 + case photoLibrary = 1 + /// 麦克风 + case microphone = 2 + } + + /// 是否允许权限 + class func isAllowed(_ permission: CLPermissionType) -> Bool { + let manager = getManagerForPermission(permission) + return manager.isAuthorized + } + + /// 是否拒绝权限 + class func isDenied(_ permission: CLPermissionType) -> Bool { + let manager = getManagerForPermission(permission) + return manager.isDenied + } + + /// 请求权限 + static func request(_ permission: CLPermissionType, completion: ((CLAuthorizationStatus) -> Void)? = nil) { + let manager = getManagerForPermission(permission) + manager.request { status in + DispatchQueue.main.async { + completion?(status) + } + } + } + + static func request(_ permissions: [CLPermissionType], completion: ((CLAuthorizationStatus) -> Void)? = nil) { + request(permissions[0]) { status in + guard status.isAuthorized, permissions.count > 1 else { + completion?(status) + return + } + var temp = permissions + temp.remove(at: 0) + request(temp, completion: completion) + } + } +} + +extension CLPermissions { + private class func getManagerForPermission(_ permission: CLPermissionType) -> CLPermissionInterface { + switch permission { + case .camera: + CLCameraPermission() + case .photoLibrary: + CLPhotoLibraryPermission() + case .microphone: + CLMicrophonePermission() + } + } +} diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@2x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@2x.png new file mode 100644 index 00000000..a4435afc Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@2x.png differ diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@3x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@3x.png new file mode 100644 index 00000000..89523866 Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_back@3x.png differ diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@2x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@2x.png new file mode 100644 index 00000000..55665fb0 Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@2x.png differ diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@3x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@3x.png new file mode 100644 index 00000000..6ecf602c Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_focus@3x.png differ diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@2x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@2x.png new file mode 100644 index 00000000..db4720c5 Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@2x.png differ diff --git a/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@3x.png b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@3x.png new file mode 100644 index 00000000..8b1a7e9c Binary files /dev/null and b/Pods/CLCamera/Camera/Resource/CLCamera.bundle/camera_rotate_camera@3x.png differ diff --git a/Pods/CLCamera/Camera/View/CLCameraButton.swift b/Pods/CLCamera/Camera/View/CLCameraButton.swift new file mode 100644 index 00000000..1cafb939 --- /dev/null +++ b/Pods/CLCamera/Camera/View/CLCameraButton.swift @@ -0,0 +1,132 @@ +// +// CLCameraButton.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/21. +// + +import SnapKit +import UIKit + +// MARK: - JmoVxia---枚举 + +extension CLCameraButton {} + +// MARK: - JmoVxia---类-属性 + +class CLCameraButton: UIView { + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + makeConstraints() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private lazy var backgroundView: UIVisualEffectView = { + let view = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight)) + view.layer.cornerRadius = intrinsicContentSize.width * 0.5 + view.layer.masksToBounds = true + return view + }() + + private lazy var buttonCenterView: UIView = { + let view = UIView() + view.layer.cornerRadius = (intrinsicContentSize.width - 20) * 0.5 + view.backgroundColor = .white + return view + }() + + private lazy var progressLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.frame = CGRect(origin: .zero, size: intrinsicContentSize) + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = UIColor.black.cgColor + layer.lineCap = .round + layer.lineWidth = 5 + layer.strokeEnd = 0 + layer.path = { + let progressLayerCenter = intrinsicContentSize.width * 0.5 + let progressLayerRadius = progressLayerCenter - 2.5 + return UIBezierPath(arcCenter: CGPoint(x: progressLayerCenter, y: progressLayerCenter), + radius: progressLayerRadius, + startAngle: .pi * -0.5, + endAngle: .pi * 1.5, + clockwise: true).cgPath + }() + return layer + }() + + private lazy var gradientLayer: CAGradientLayer = { + let layer = CAGradientLayer() + layer.frame = CGRect(origin: .zero, size: intrinsicContentSize) + layer.colors = [#colorLiteral(red: 0.9960784314, green: 0.6745098039, blue: 0.368627451, alpha: 1).cgColor, #colorLiteral(red: 0.7803921569, green: 0.4745098039, blue: 0.8156862745, alpha: 1).cgColor, #colorLiteral(red: 0.2941176471, green: 0.7529411765, blue: 0.7843137255, alpha: 1).cgColor] + layer.startPoint = CGPoint(x: 0, y: 0) + layer.endPoint = CGPoint(x: 0, y: 1) + layer.mask = progressLayer + return layer + }() +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraButton { + func setupUI() { + backgroundView.contentView.addSubview(buttonCenterView) + addSubview(backgroundView) + layer.addSublayer(gradientLayer) + } + + func makeConstraints() { + backgroundView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + buttonCenterView.snp.makeConstraints { make in + make.center.equalToSuperview() + make.height.width.equalTo(intrinsicContentSize.width - 20) + } + } +} + +// MARK: - JmoVxia---override + +extension CLCameraButton { + override var intrinsicContentSize: CGSize { + CGSize(width: 70, height: 70) + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraButton {} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraButton {} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraButton { + func showBeginAnimation() { + UIView.animate(withDuration: 0.2, animations: { + self.transform = CGAffineTransform(scaleX: 1.5, y: 1.5) + self.buttonCenterView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) + }) + } + + func showEndAnimation() { + UIView.animate(withDuration: 0.1, animations: { + self.transform = .identity + self.buttonCenterView.transform = .identity + }) + progressLayer.strokeEnd = 0 + progressLayer.removeAllAnimations() + } + + func updateProgress(_ progress: CGFloat) { + progressLayer.strokeEnd = progress + } +} diff --git a/Pods/CLCamera/Camera/View/CLCameraControlView.swift b/Pods/CLCamera/Camera/View/CLCameraControlView.swift new file mode 100644 index 00000000..2fb6bfee --- /dev/null +++ b/Pods/CLCamera/Camera/View/CLCameraControlView.swift @@ -0,0 +1,376 @@ +// +// CLCameraControlView.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/21. +// + +import SnapKit +import UIKit + +protocol CLCameraControlDelegate: AnyObject { + func cameraControlDidTapExit(_ controlView: CLCameraControlView) + func cameraControlDidTapChangeCamera(_ controlView: CLCameraControlView) + func cameraControlDidPrepareForZoom(_ controlView: CLCameraControlView) + func cameraControl(_ controlView: CLCameraControlView, didFocusAt point: CGPoint) + func cameraControlDidTakePhoto(_ controlView: CLCameraControlView) + func cameraControlDidBeginTakingVideo(_ controlView: CLCameraControlView) + func cameraControlDidEndTakingVideo(_ controlView: CLCameraControlView) + func cameraControl(_ controlView: CLCameraControlView, didChangeVideoZoom zoomScale: Double) +} + +class CLCameraControlView: UIView { + init(config: CLCameraConfig) { + self.config = config + super.init(frame: .zero) + setupUI() + makeConstraints() + } + + @available(*, unavailable) + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private(set) lazy var previewContentView: UIView = { + let view = UIView() + view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(focusTapGes(_:)))) + view.addGestureRecognizer(UIPinchGestureRecognizer(target: self, action: #selector(zoomPinchGesture(_:)))) + view.backgroundColor = .black + return view + }() + + private lazy var blurEffectView: UIVisualEffectView = { + let view = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) + view.isUserInteractionEnabled = false + view.backgroundColor = .black + return view + }() + + private lazy var animationView: UIView = { + let view = UIView() + view.backgroundColor = .black + view.isHidden = true + view.isUserInteractionEnabled = false + return view + }() + + private lazy var cameraButton: CLCameraButton = { + let view = CLCameraButton() + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGesture)) + tapGesture.isEnabled = config.allowTakingPhoto + view.addGestureRecognizer(tapGesture) + let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressGesture(_:))) + longPressGesture.isEnabled = config.allowTakingVideo + longPressGesture.minimumPressDuration = 0.5 + view.addGestureRecognizer(longPressGesture) + return view + }() + + private lazy var tipLabel: UILabel = { + let view = UILabel() + view.alpha = 0.0 + view.font = UIFont.systemFont(ofSize: 13) + view.textColor = .white + view.text = { + var text = config.allowTakingPhoto ? "轻触拍照" : "" + text += config.allowTakingVideo ? (text.isEmpty ? "按住摄像" : ",按住摄像") : "" + return text + }() + return view + }() + + private lazy var mainStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = true + view.axis = .vertical + view.distribution = .fill + view.alignment = .fill + view.insetsLayoutMarginsFromSafeArea = false + view.isLayoutMarginsRelativeArrangement = false + view.layoutMargins = .zero + view.spacing = 0 + return view + }() + + private lazy var bottomStackView: UIStackView = { + let view = UIStackView() + view.isUserInteractionEnabled = true + view.axis = .horizontal + view.distribution = .equalSpacing + view.alignment = .center + view.insetsLayoutMarginsFromSafeArea = true + view.isLayoutMarginsRelativeArrangement = true + view.layoutMargins = .init(top: 30, left: 0, bottom: 30, right: 0) + return view + }() + + private lazy var leftView: UIView = { + let view = UIView() + return view + }() + + private lazy var rightView: UIView = { + let view = UIView() + return view + }() + + private lazy var cancelButton: UIButton = { + let view = UIButton() + view.contentMode = .center + view.tintColor = .white + view.setImage(image("camera_back")?.withRenderingMode(.alwaysTemplate), for: .normal) + view.addTarget(self, action: #selector(cancelButtonClick), for: .touchUpInside) + return view + }() + + private lazy var changeCameraButton: UIButton = { + let view = UIButton() + view.contentMode = .center + view.tintColor = .white + view.setImage(image("camera_rotate_camera")?.withRenderingMode(.alwaysTemplate), for: .normal) + view.addTarget(self, action: #selector(changeCameraButtonClick), for: .touchUpInside) + return view + }() + + private lazy var focusImageView: UIImageView = { + let view = UIImageView() + view.alpha = 0.0 + view.frame = CGRect(origin: .zero, size: CGSize(width: 70, height: 70)) + view.image = image("camera_focus")?.withRenderingMode(.alwaysTemplate) + view.tintColor = .green + return view + }() + + private var isAnimating: Bool = false { + didSet { + previewContentView.isUserInteractionEnabled = !isAnimating + cameraButton.isUserInteractionEnabled = !isAnimating + changeCameraButton.isUserInteractionEnabled = !isAnimating + } + } + + private var isRecording: Bool = false { + didSet { + cancelButton.isUserInteractionEnabled = !isRecording + changeCameraButton.isUserInteractionEnabled = !isRecording + } + } + + private var isFocusing: Bool = false + + private var videoTimer: Timer? + + private var videoRecordTime: Double = 0 + + private let config: CLCameraConfig + + weak var delegate: CLCameraControlDelegate? +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraControlView { + func setupUI() { + backgroundColor = .clear + addSubview(mainStackView) + addSubview(previewContentView) + addSubview(blurEffectView) + addSubview(animationView) + addSubview(tipLabel) + addSubview(focusImageView) + mainStackView.addArrangedSubview(previewContentView) + mainStackView.addArrangedSubview(bottomStackView) + bottomStackView.addArrangedSubview(leftView) + bottomStackView.addArrangedSubview(cancelButton) + bottomStackView.addArrangedSubview(cameraButton) + bottomStackView.addArrangedSubview(changeCameraButton) + bottomStackView.addArrangedSubview(rightView) + } + + func makeConstraints() { + mainStackView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + blurEffectView.snp.makeConstraints { make in + make.edges.equalTo(previewContentView) + } + + animationView.snp.makeConstraints { make in + make.edges.equalTo(previewContentView) + } + + tipLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalTo(previewContentView.snp.bottom).offset(-30) + } + + cancelButton.snp.makeConstraints { make in + make.size.equalTo(70) + } + + changeCameraButton.snp.makeConstraints { make in + make.size.equalTo(70) + } + + bottomStackView.snp.makeConstraints { make in + make.bottom.left.right.equalToSuperview() + } + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraControlView { + func zoomPinchGesture(_ gesture: UIPinchGestureRecognizer) { + guard gesture.numberOfTouches == 2 else { return } + if gesture.state == .began { delegate?.cameraControlDidPrepareForZoom(self) } + delegate?.cameraControl(self, didChangeVideoZoom: gesture.scale) + } + + func longPressGesture(_ res: UIGestureRecognizer) { + switch res.state { + case .began: + longPressBegin() + delegate?.cameraControlDidPrepareForZoom(self) + case .changed: + let pointY = res.location(in: cameraButton).y + let zoom = pointY > 0 ? 1 : -pointY / (Double(bounds.width) * 0.15) + 1 + delegate?.cameraControl(self, didChangeVideoZoom: zoom) + default: + longPressEnd() + } + } + + func focusTapGes(_ gesture: UIGestureRecognizer) { + showFocusAnimationAt(point: gesture.location(in: previewContentView)) + } + + func cancelButtonClick() { + delegate?.cameraControlDidTapExit(self) + } + + func tapGesture() { + delegate?.cameraControlDidTakePhoto(self) + animationView.isHidden = false + UIView.animate(withDuration: 0.75) { + self.animationView.backgroundColor = .clear + } completion: { _ in + self.animationView.isHidden = true + self.animationView.backgroundColor = .black + } + } + + func timeRecord() { + videoRecordTime += 0.1 + let progress = videoRecordTime / config.maximumVideoDuration + progress >= 1 ? longPressEnd() : cameraButton.updateProgress(progress) + } + + func changeCameraButtonClick() { + blurEffectView.effect = UIBlurEffect(style: .regular) + UIView.transition(with: previewContentView, duration: 0.75, options: .transitionFlipFromLeft) { + self.blurEffectView.effect = nil + self.delegate?.cameraControlDidTapChangeCamera(self) + } + } +} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraControlView { + func longPressBegin() { + isRecording = true + cameraButton.showBeginAnimation() + videoTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timeRecord), userInfo: nil, repeats: true) + delegate?.cameraControlDidBeginTakingVideo(self) + } + + func longPressEnd() { + isRecording = false + guard videoRecordTime != .zero else { return } + videoTimer?.invalidate() + videoTimer = nil + videoRecordTime = .zero + cameraButton.showEndAnimation() + delegate?.cameraControlDidEndTakingVideo(self) + } + + func image(_ name: String) -> UIImage? { + let filePath = Bundle(for: CLCameraControlView.classForCoder()).resourcePath! + "/CLCamera.bundle" + let bundle = Bundle(path: filePath) + let scale = max(min(Int(UIScreen.main.scale), 2), 3) + return .init(named: "\(name)@\(scale)x", in: bundle, compatibleWith: nil) + } +} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraControlView { + func showRunningAnimation() { + guard !isAnimating else { return } + isAnimating = true + let blurInAnimator = UIViewPropertyAnimator(duration: 0.75, curve: .easeOut) { + self.blurEffectView.backgroundColor = nil + } + + let blurOutAnimator = UIViewPropertyAnimator(duration: 0.5, curve: .easeOut) { + self.blurEffectView.effect = nil + } + + let tipLabelInAnimator = UIViewPropertyAnimator(duration: 1.0, curve: .easeIn) { + self.tipLabel.alpha = 1.0 + } + + let tipLabelOutAnimator = UIViewPropertyAnimator(duration: 0.35, curve: .easeOut) { + self.tipLabel.alpha = 0.0 + } + + blurInAnimator.addCompletion { _ in + blurOutAnimator.startAnimation() + } + + blurOutAnimator.addCompletion { _ in + self.isAnimating = false + tipLabelInAnimator.startAnimation() + } + + tipLabelInAnimator.addCompletion { _ in + tipLabelOutAnimator.startAnimation(afterDelay: 2.0) + } + + blurInAnimator.startAnimation() + } + + func showFocusAnimationAt(point: CGPoint) { + guard !isFocusing else { return } + isFocusing = true + + focusImageView.center = previewContentView.convert(point, to: focusImageView.superview) + focusImageView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5) + focusImageView.alpha = 1.0 + + let transformIn = UIViewPropertyAnimator(duration: 0.3, curve: .easeIn) { + self.focusImageView.alpha = 0.1 + self.focusImageView.transform = .identity + } + let alphaIn = UIViewPropertyAnimator(duration: 0.3, curve: .easeIn) { + self.focusImageView.alpha = 1.0 + } + let alphaOut = UIViewPropertyAnimator(duration: 0.2, curve: .easeOut) { + self.focusImageView.alpha = 0.0 + } + transformIn.addCompletion { _ in + alphaIn.startAnimation() + } + alphaIn.addCompletion { _ in + alphaOut.startAnimation() + } + alphaOut.addCompletion { _ in + self.isFocusing = false + } + transformIn.startAnimation() + delegate?.cameraControl(self, didFocusAt: point) + } +} diff --git a/Pods/CLCamera/Camera/View/CLCameraPreviewToolBar.swift b/Pods/CLCamera/Camera/View/CLCameraPreviewToolBar.swift new file mode 100644 index 00000000..5a0417fb --- /dev/null +++ b/Pods/CLCamera/Camera/View/CLCameraPreviewToolBar.swift @@ -0,0 +1,113 @@ +// +// CLCameraPreviewToolBar.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/19. +// + +import SnapKit +import UIKit + +protocol CLCameraPreviewToolBarDelegate: AnyObject { + func didTapCancelButton(on toolBar: CLCameraPreviewToolBar) + func didTapDoneButton(on toolBar: CLCameraPreviewToolBar) +} + +// MARK: - JmoVxia---枚举 + +extension CLCameraPreviewToolBar {} + +// MARK: - JmoVxia---类-属性 + +class CLCameraPreviewToolBar: UIView { + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + makeConstraints() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private lazy var mainStackView: UIStackView = { + let stackView = UIStackView() + stackView.isUserInteractionEnabled = true + stackView.axis = .horizontal + stackView.distribution = .equalSpacing + stackView.alignment = .center + stackView.insetsLayoutMarginsFromSafeArea = true + stackView.isLayoutMarginsRelativeArrangement = true + stackView.layoutMargins = UIEdgeInsets(top: 30, left: 45, bottom: 30, right: 45) + stackView.spacing = 0 + return stackView + }() + + private lazy var cancelButton: UIButton = { + let button = UIButton() + button.setTitle("取消", for: .normal) + button.setTitleColor(.white, for: .normal) + button.titleLabel?.font = UIFont.systemFont(ofSize: 16) + button.addTarget(self, action: #selector(cancelButtonTapped), for: .touchUpInside) + return button + }() + + private lazy var doneButton: UIButton = { + let button = UIButton() + button.setTitle("确定", for: .normal) + button.setTitleColor(.white, for: .normal) + button.titleLabel?.font = UIFont.systemFont(ofSize: 16) + button.addTarget(self, action: #selector(doneButtonTapped), for: .touchUpInside) + return button + }() + + weak var delegate: CLCameraPreviewToolBarDelegate? +} + +// MARK: - JmoVxia---布局 + +private extension CLCameraPreviewToolBar { + func setupUI() { + backgroundColor = .black + addSubview(mainStackView) + mainStackView.addArrangedSubview(cancelButton) + mainStackView.addArrangedSubview(doneButton) + } + + func makeConstraints() { + cancelButton.snp.makeConstraints { make in + make.height.equalTo(70) + } + doneButton.snp.makeConstraints { make in + make.height.equalTo(70) + } + mainStackView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} + +// MARK: - JmoVxia---override + +extension CLCameraPreviewToolBar {} + +// MARK: - JmoVxia---objc + +@objc private extension CLCameraPreviewToolBar { + func cancelButtonTapped() { + delegate?.didTapCancelButton(on: self) + } + + func doneButtonTapped() { + delegate?.didTapDoneButton(on: self) + } +} + +// MARK: - JmoVxia---私有方法 + +private extension CLCameraPreviewToolBar {} + +// MARK: - JmoVxia---公共方法 + +extension CLCameraPreviewToolBar {} diff --git a/Pods/CLCamera/Camera/View/Loading/CLLoadingHUD.swift b/Pods/CLCamera/Camera/View/Loading/CLLoadingHUD.swift new file mode 100644 index 00000000..18a0f178 --- /dev/null +++ b/Pods/CLCamera/Camera/View/Loading/CLLoadingHUD.swift @@ -0,0 +1,46 @@ +// +// CLLoadingHUD.swift +// CLCamera +// +// Created by Chen JmoVxia on 2021/12/29. +// + +import UIKit + +class CLLoadingHUD { + static let shared = CLLoadingHUD() + + private var window: UIWindow? + + private weak var loadingView: CLLoadingHUDView? + + private init() {} +} + +private extension CLLoadingHUD { + static func createWindow() { + shared.window = UIWindow(frame: UIScreen.main.bounds) + shared.window?.backgroundColor = .clear + shared.window?.isHidden = false + + let view = CLLoadingHUDView(frame: UIScreen.main.bounds) + shared.window?.addSubview(view) + shared.loadingView = view + } +} + +extension CLLoadingHUD { + static func showLoading() { + if shared.loadingView == nil { createWindow() } + shared.loadingView?.showLoading() + } + + static func showProgress(_ progress: CGFloat) { + if shared.loadingView == nil { createWindow() } + shared.loadingView?.showProgress(progress) + } + + static func hideLoading() { + shared.window = nil + } +} diff --git a/Pods/CLCamera/Camera/View/Loading/CLLoadingHUDView.swift b/Pods/CLCamera/Camera/View/Loading/CLLoadingHUDView.swift new file mode 100644 index 00000000..788edf39 --- /dev/null +++ b/Pods/CLCamera/Camera/View/Loading/CLLoadingHUDView.swift @@ -0,0 +1,120 @@ +// +// CLLoadingHUDView.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import SnapKit +import UIKit + +// MARK: - JmoVxia---枚举 + +extension CLLoadingHUDView {} + +// MARK: - JmoVxia---类-属性 + +class CLLoadingHUDView: UIView { + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + makeConstraints() + setNeedsLayout() + layoutIfNeeded() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private lazy var contentVisualEffectView: UIVisualEffectView = { + let view = UIVisualEffectView(effect: UIBlurEffect(style: .light)) + view.contentView.backgroundColor = #colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1).withAlphaComponent(0.6) + view.layer.cornerRadius = 10 + view.layer.masksToBounds = true + return view + }() + + private lazy var activityIndicator: UIActivityIndicatorView = { + let view = UIActivityIndicatorView(style: .white) + view.hidesWhenStopped = true + view.tintColor = .white + view.style = .whiteLarge + return view + }() + + private lazy var progressView: CLLoadingProgressView = { + let view = CLLoadingProgressView() + view.isHidden = true + return view + }() + + private lazy var tipLabel: UILabel = { + let view = UILabel() + view.text = "正在处理中" + view.textColor = .white + view.font = UIFont.systemFont(ofSize: 16) + return view + }() +} + +// MARK: - JmoVxia---布局 + +private extension CLLoadingHUDView { + func setupUI() { + addSubview(contentVisualEffectView) + contentVisualEffectView.contentView.addSubview(progressView) + contentVisualEffectView.contentView.addSubview(activityIndicator) + contentVisualEffectView.contentView.addSubview(tipLabel) + } + + func makeConstraints() { + contentVisualEffectView.snp.makeConstraints { make in + make.center.equalToSuperview() + make.height.equalTo(108) + make.width.equalTo(140) + } + + progressView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(20) + make.height.width.equalTo(30) + } + + activityIndicator.snp.makeConstraints { make in + make.center.equalTo(progressView.snp.center) + } + + tipLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalTo(-20) + } + } +} + +// MARK: - JmoVxia---override + +extension CLLoadingHUDView {} + +// MARK: - JmoVxia---objc + +@objc private extension CLLoadingHUDView {} + +// MARK: - JmoVxia---私有方法 + +private extension CLLoadingHUDView {} + +// MARK: - JmoVxia---公共方法 + +extension CLLoadingHUDView { + func showLoading() { + progressView.isHidden = true + activityIndicator.startAnimating() + } + + func showProgress(_ progress: CGFloat) { + progressView.progress = progress + activityIndicator.stopAnimating() + } +} diff --git a/Pods/CLCamera/Camera/View/Loading/CLLoadingProgressView.swift b/Pods/CLCamera/Camera/View/Loading/CLLoadingProgressView.swift new file mode 100644 index 00000000..ea2921fa --- /dev/null +++ b/Pods/CLCamera/Camera/View/Loading/CLLoadingProgressView.swift @@ -0,0 +1,87 @@ +// +// CLLoadingProgressView.swift +// CLCamera +// +// Created by Chen JmoVxia on 2024/2/26. +// + +import UIKit + +// MARK: - JmoVxia---枚举 + +extension CLLoadingProgressView {} + +// MARK: - JmoVxia---类-属性 + +class CLLoadingProgressView: UIView { + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + makeConstraints() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private lazy var progressLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = UIColor.white.cgColor + layer.opacity = 1 + layer.lineCap = CAShapeLayerLineCap.round + layer.lineWidth = 4 + layer.shadowColor = UIColor.black.cgColor + layer.shadowOffset = CGSize(width: 1, height: 1) + layer.shadowRadius = 2 + layer.shadowOpacity = 0.5 + return layer + }() + + var progress: CGFloat = 0 { + didSet { + setNeedsDisplay() + isHidden = progress == 1 + } + } +} + +// MARK: - JmoVxia---布局 + +private extension CLLoadingProgressView { + func setupUI() { + backgroundColor = .clear + layer.addSublayer(progressLayer) + } + + func makeConstraints() {} +} + +// MARK: - JmoVxia---override + +extension CLLoadingProgressView { + override func draw(_ rect: CGRect) { + let center = CGPoint(x: rect.size.width * 0.5, y: rect.size.height * 0.5) + let radius = rect.size.width * 0.5 + + let startAngle = -Double.pi / 2 + let endAngle = -Double.pi / 2 + Double.pi * 2 * progress + let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) + + progressLayer.frame = bounds + progressLayer.path = path.cgPath + } +} + +// MARK: - JmoVxia---objc + +@objc private extension CLLoadingProgressView {} + +// MARK: - JmoVxia---私有方法 + +private extension CLLoadingProgressView {} + +// MARK: - JmoVxia---公共方法 + +extension CLLoadingProgressView {} diff --git a/Pods/CLCamera/LICENSE b/Pods/CLCamera/LICENSE new file mode 100644 index 00000000..341939b5 --- /dev/null +++ b/Pods/CLCamera/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 JmoVxia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/CLCamera/README.md b/Pods/CLCamera/README.md new file mode 100755 index 00000000..9a84c8df --- /dev/null +++ b/Pods/CLCamera/README.md @@ -0,0 +1,47 @@ +# CLCamera + +## 功能 + +- [x] 拍照 +- [x] 视频录制 + +## 配置 + +```swift +public struct CLCameraConfig { + // 是否允许拍摄照片 + public var allowTakingPhoto: Bool = true + + // 是否允许拍摄视频 + public var allowTakingVideo: Bool = true + + // 视频拍摄最长时长 + public var maximumVideoDuration: TimeInterval = 60 + + // 拍摄闪光灯开关 + public var flashMode: CLCameraFlashMode = .auto + + // 视频拍摄格式 + public var videoFileType: CLCameraVideoFileType = .mp4 + + // 视频拍摄帧率 + public var videoFrameRate: Double = 60 + + // 视频拍摄预设 + public var sessionPreset: CLCameraSessionPreset = .hd1920x1080 + + // 视频拍摄防抖模式 + public var videoStabilizationMode: CLCameraVideoStabilizationMode = .off +} +``` + +## cocoapods + +```swift +pod 'CLCamera' +``` + +## 使用 + +使用参考[demo](https://github.com/JmoVxia/CLDemo) + diff --git a/Pods/CLPopoverManager/CLPopoverManager/CLPopoverConfig.swift b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverConfig.swift new file mode 100644 index 00000000..2d6648d3 --- /dev/null +++ b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverConfig.swift @@ -0,0 +1,101 @@ +// +// CLPopoverConfig.swift +// +// +// Created by Chen JmoVxia on 2022/11/3. +// + +import Foundation +import UIKit + +// MARK: - 弹窗配置 + +/// 配置 +@objcMembers public class CLPopoverConfig: NSObject { + public enum CLUserInterfaceStyle: Int { + case unspecified = 0 + case light = 1 + case dark = 2 + } + + public enum CLPopoverPriority { + case low + case mediumLow + case medium + case mediumHigh + case high + case customValue(Int) + var rawValue: Int { + switch self { + case .low: + 0 + case .mediumLow: + 250 + case .medium: + 500 + case .mediumHigh: + 750 + case .high: + 1000 + case let .customValue(value): + value + } + } + + static func > (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue > rhs.rawValue + } + + static func < (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue < rhs.rawValue + } + + static func >= (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue >= rhs.rawValue + } + + static func <= (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue <= rhs.rawValue + } + + static func == (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue == rhs.rawValue + } + + static func != (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue != rhs.rawValue + } + } + + public enum CLMode { + /// 排队 + case queue + /// 插队 + case interrupt + /// 替换 + case replace + /// 唯一 + case unique + } + + /// 弹窗模式 + public var popoverMode: CLMode = .queue + /// 弹窗优先级,只影响等待队列 + public var popoverPriority: CLPopoverPriority = .medium + /// 是否允许手势穿透 + public var allowsEventPenetration = false + /// 手势穿透时是否自动隐藏 + public var autoHideWhenPenetrated = false + /// 是否自动旋转屏幕 + public var shouldAutorotate = false + /// 是否隐藏状态栏 + public var prefersStatusBarHidden = false + /// 状态栏样式 + public var preferredStatusBarStyle = UIStatusBarStyle.lightContent + /// 支持的界面方向 + public var supportedInterfaceOrientations = UIInterfaceOrientationMask.portrait + /// 用户界面样式,包括夜间模式 + public var userInterfaceStyleOverride = CLUserInterfaceStyle.light + /// 弹窗的唯一标识符,用于去重 + public var identifier: String? +} diff --git a/Pods/CLPopoverManager/CLPopoverManager/CLPopoverController.swift b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverController.swift new file mode 100644 index 00000000..db7cc51c --- /dev/null +++ b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverController.swift @@ -0,0 +1,101 @@ +// +// CLPopoverController.swift +// +// +// Created by Chen JmoVxia on 2022/7/8. +// + +import UIKit + +// MARK: - 弹窗父类控制器 + +@objcMembers open class CLPopoverController: UIViewController { + @available(*, unavailable) + public required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + let keyWindow = if #available(iOS 13.0, *) { + UIApplication.shared.connectedScenes + .compactMap { $0 as? UIWindowScene } + .flatMap(\.windows) + .first { $0.isKeyWindow } + } else { + UIApplication.shared.keyWindow + } + if let prefersStatusBarHidden = keyWindow?.rootViewController?.prefersStatusBarHidden { + config.prefersStatusBarHidden = prefersStatusBarHidden + } + if let preferredStatusBarStyle = keyWindow?.rootViewController?.preferredStatusBarStyle { + config.preferredStatusBarStyle = preferredStatusBarStyle + } + if let supportedInterfaceOrientations = keyWindow?.rootViewController?.supportedInterfaceOrientations { + config.supportedInterfaceOrientations = supportedInterfaceOrientations + } + } + + open var config = CLPopoverConfig() + + open var key: String { + "\(Unmanaged.passUnretained(self).toOpaque())" + } +} + +extension CLPopoverController { + @available(iOS 13.0, *) + override open var overrideUserInterfaceStyle: UIUserInterfaceStyle { + set { + super.overrideUserInterfaceStyle = newValue + } + get { + .init(rawValue: config.userInterfaceStyleOverride.rawValue) ?? .light + } + } +} + +extension CLPopoverController { + override open func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override open func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override open func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .clear + } + + override open func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + + override open func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + } + + override open func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + } +} + +extension CLPopoverController { + override open var preferredStatusBarStyle: UIStatusBarStyle { + config.preferredStatusBarStyle + } + + override open var prefersStatusBarHidden: Bool { + config.prefersStatusBarHidden + } + + override open var shouldAutorotate: Bool { + config.shouldAutorotate + } + + override open var supportedInterfaceOrientations: UIInterfaceOrientationMask { + config.supportedInterfaceOrientations + } +} diff --git a/Pods/CLPopoverManager/CLPopoverManager/CLPopoverManager.swift b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverManager.swift new file mode 100644 index 00000000..834711de --- /dev/null +++ b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverManager.swift @@ -0,0 +1,116 @@ +// +// CLPopoverManager +// +// +// Created by Chen JmoVxia on 2019/12/24. +// + +import UIKit + +// MARK: - 弹窗管理者 + +@objcMembers public class CLPopoverManager: NSObject { + override private init() { + super.init() + } + + deinit {} + + private var waitQueue = [String: CLPopoverProtocol]() + + private var windows = [String: CLPopoverWindow]() +} + +public extension CLPopoverManager { + @discardableResult static func mainSync(execute block: () -> T) -> T { + guard !Thread.isMainThread else { return block() } + return DispatchQueue.main.sync { block() } + } +} + +public extension CLPopoverManager { + private static var manager: CLPopoverManager? + + private static let singletonSemaphore: DispatchSemaphore = { + let semap = DispatchSemaphore(value: 0) + semap.signal() + return semap + }() + + private static var shared: CLPopoverManager { + singletonSemaphore.wait() + defer { singletonSemaphore.signal() } + if let sharedManager = manager { + return sharedManager + } else { + manager = CLPopoverManager() + return manager! + } + } +} + +public extension CLPopoverManager { + /// 显示自定义弹窗 + static func show(_ controller: CLPopoverProtocol, completion: (() -> Void)? = nil) { + mainSync { + let shouldShow = !shared.windows.values.contains { $0.rootPopoverController?.config.popoverMode == .unique } && + !shared.windows.values.contains { $0.rootPopoverController?.config.identifier == controller.config.identifier && controller.config.identifier != nil } && + !shared.waitQueue.values.contains { $0.key != controller.key && $0.config.identifier == controller.config.identifier && controller.config.identifier != nil } + + guard shouldShow else { return } + + switch controller.config.popoverMode { + case .queue, .interrupt: + break + case .replace: + shared.windows.removeAll() + case .unique: + shared.windows.removeAll() + shared.waitQueue.removeAll() + } + guard !(controller.config.popoverMode == .queue && !shared.windows.isEmpty) else { + shared.waitQueue[controller.key] = controller + return + } + let window = CLPopoverWindow(frame: UIScreen.main.bounds) + window.backgroundColor = .clear + if #available(iOS 13.0, *) { + window.overrideUserInterfaceStyle = .init(rawValue: controller.config.userInterfaceStyleOverride.rawValue) ?? .light + } + window.autoHideWhenPenetrated = controller.config.autoHideWhenPenetrated + window.allowsEventPenetration = controller.config.allowsEventPenetration + window.windowLevel = .alert + 50 + window.rootViewController = controller + window.makeKeyAndVisible() + shared.windows[controller.key] = window + shared.waitQueue.removeValue(forKey: controller.key) + controller.showAnimation(completion: completion) + } + } + + /// 隐藏指定弹窗 + static func dismiss(_ key: String?, completion: (() -> Void)? = nil) { + guard let key else { return } + func remove() {} + mainSync { + guard let window = shared.windows[key] else { return } + window.rootPopoverController?.dismissAnimation { + completion?() + shared.waitQueue.removeValue(forKey: key) + shared.windows.removeValue(forKey: key) + guard !(shared.windows.isEmpty && shared.waitQueue.isEmpty) else { return dismissAll() } + guard let lastController = shared.waitQueue.values.max(by: { $0.config.popoverPriority < $1.config.popoverPriority }) else { return } + show(lastController) + } + } + } + + /// 隐藏所有弹窗 + static func dismissAll() { + mainSync { + shared.waitQueue.removeAll() + shared.windows.removeAll() + manager = nil + } + } +} diff --git a/Pods/CLPopoverManager/CLPopoverManager/CLPopoverProtocol.swift b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverProtocol.swift new file mode 100644 index 00000000..ac58979b --- /dev/null +++ b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverProtocol.swift @@ -0,0 +1,15 @@ +// +// CLPopoverProtocol.swift +// +// +// Created by Chen JmoVxia on 2023/6/27. +// + +import Foundation + +public protocol CLPopoverProtocol where Self: CLPopoverController { + /// 显示 + func showAnimation(completion: (() -> Void)?) + /// 隐藏 + func dismissAnimation(completion: (() -> Void)?) +} diff --git a/Pods/CLPopoverManager/CLPopoverManager/CLPopoverWindow.swift b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverWindow.swift new file mode 100644 index 00000000..d7c9ac2a --- /dev/null +++ b/Pods/CLPopoverManager/CLPopoverManager/CLPopoverWindow.swift @@ -0,0 +1,32 @@ +// +// CLPopoverWindow.swift +// +// +// Created by Chen JmoVxia on 2022/7/8. +// + +import UIKit + +// MARK: - 弹窗Window + +@objcMembers public class CLPopoverWindow: UIWindow { + public var allowsEventPenetration = false + + public var autoHideWhenPenetrated = false + + public var rootPopoverController: CLPopoverProtocol? { + rootViewController as? CLPopoverProtocol + } + + override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let view = super.hitTest(point, with: event) + + guard view == rootViewController?.view else { return view } + + guard allowsEventPenetration else { return view } + + autoHideWhenPenetrated ? (rootViewController as? (CLPopoverController & CLPopoverProtocol))?.dismissAnimation(completion: nil) : () + + return nil + } +} diff --git a/Pods/CLPopoverManager/LICENSE b/Pods/CLPopoverManager/LICENSE new file mode 100644 index 00000000..341939b5 --- /dev/null +++ b/Pods/CLPopoverManager/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 JmoVxia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/CLPopoverManager/README.md b/Pods/CLPopoverManager/README.md new file mode 100644 index 00000000..77d8aadf --- /dev/null +++ b/Pods/CLPopoverManager/README.md @@ -0,0 +1,112 @@ +# iOS开发之弹窗管理 + +## 前言 + +“千淘万漉虽辛苦,吹尽狂沙始到金。”在这快速变化的互联网行业,身边的朋友有的选择了勇敢创业,有的则在技术的海洋中默默耕耘。时常在深夜反思,作为一个开发者,我们的价值何在?答案或许就在那行代码中,润物细无声。以下是我在日常开发中封装的一个弹窗管理工具——[CLPopoverManager](https://github.com/JmoVxia/CLPopoverManager),希望能为大家提供一些灵感和帮助。 + +## 概述 + +在移动应用开发中,弹窗作为一种重要的用户交互方式,使用频率非常高。无论是提示信息、广告展示,还是操作确认,弹窗都扮演着重要角色。然而,如果弹窗的显示逻辑缺乏合理控制,可能会出现弹窗重叠、顺序混乱等问题,极大影响用户体验。因此,我开发了[CLPopoverManager](https://github.com/JmoVxia/CLPopoverManager),旨在为弹窗显示提供一个统一、可控的管理方案。 + +## 功能 + +- 支持`排队`、`插队`、`替换`、`唯一`模式 +- 支持优先级设置 +- 支持去重标记 +- 支持手势穿透 +- 支持手势穿透时自动隐藏 +- 支持自动旋转 +- 支持隐藏状态栏 +- 支持状态栏样式 +- 支持设置界面方向 +- 支持夜间模式 + +## 原理 + +弹窗采用伪单例模式管理`UIWindow`,内部采用自定义队列控制显示顺序,对外使用`UIViewController`。 + +## 使用 + +自定义`UIViewController`继承`CLPopoverController`并且遵守`CLPopoverProtocol`协议即可,内部你可以自行实现弹窗相关动画和UI。 + +### 示例代码 + +```swift +Swift +Copy code +class CustomPopoverController: CLPopoverController, CLPopoverProtocol { + // 实现弹窗相关逻辑 + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + } + + private func setupUI() { + // 配置弹窗UI + } + + func showAnimation(completion: (() -> Void)? = nil) { + // 显示动画 + } + + func dismissAnimation(completion: (() -> Void)? = nil) { + // 隐藏动画 + } +} + +/// 弹出 +let popover = CustomPopoverController() +popover.config.popoverMode = .queue +let key = CLPopoverManager.show(popover: popover) + +/// 隐藏单个弹窗 +CLPopoverManager.dismiss(key) +/// 隐藏所有弹窗 +CLPopoverManager.dismissAll() +``` + +## 模式和优先级 + +### 模式 + +1. **排队模式**:如果当前没有弹窗显示,则立即显示;如果有弹窗正在显示,会进入到等待队列,后续按照优先级显示。 +2. **插队模式**:无视当前显示的弹窗,立即显示,会多个弹窗重叠。 +3. **替换模式**:替换当前显示的弹窗,立即显示,会隐藏之前的所有弹窗。 +4. **唯一模式**:替换当前显示的弹窗,独占显示,会隐藏之前的所有弹窗并且阻止后续所有弹窗。 + +### 优先级 + +弹窗可以设置优先级,高优先级的弹窗将优先显示。只对进入到等待队列中的弹窗生效,前面弹窗消失后,会在等待队列中查找优先级高的弹窗优先显示。 + +## 常见问题解答(QA) + +### 为什么使用 `UIViewController` 而不是 `UIView`? + +`UIViewController` 相比 `UIView` 能够提供生命周期相关方法,管理起来更加方便。 + +### 为什么使用 `UIWindow`? + +`UIWindow` 可以不入侵项目 `UI`,保障不扰乱当前项目的同时,可以实现横竖屏切换、状态栏样式等。 + +### 为什么是伪单例模式? + +弹窗管理在所有弹窗都销毁后,会自动销毁管理者的单例。 + +### 为什么有优先级的情况还需要这么多模式? + +需求多种多样,为保障灵活性的同时,还能够保障弹窗的顺序。 + +## 结语 + +通过封装 [CLPopoverManager](https://github.com/JmoVxia/CLPopoverManager),我们能够更好地管理 iOS 应用中的弹窗显示逻辑,提升用户体验,保障应用的稳定性。希望这个工具能够帮助到大家,同时也欢迎各位提出宝贵的意见和建议。 + +开发是一种艺术,不仅需要技术的积累,更需要灵感和创造力。愿我们在追逐技术之巅的路上,能够彼此激励,共同成长。愿所有的开发者都能在自己的代码世界中找到那一片属于自己的净土。 + +**PS**:心中感慨良多,奈何腹中无墨,一个字总结——懒。 + +## cocoapods + +```swift +pod ' CLPopoverManager' +``` + diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADXChaCha20Poly1305.swift b/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADXChaCha20Poly1305.swift new file mode 100644 index 00000000..7204baf7 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADXChaCha20Poly1305.swift @@ -0,0 +1,83 @@ +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +/// This class implements the XChaCha20-Poly1305 Authenticated Encryption with +/// Associated Data (AEAD_XCHACHA20_POLY1305) construction, providing both encryption and authentication. +/// +/// For more information about the XChaCha20-Poly1305 algorithm, refer to the IETF draft: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha +public final class AEADXChaCha20Poly1305: AEAD { + + /// The key length (in bytes) required for the XChaCha20 cipher (32 bytes). + public static let kLen = 32 // key length + + /// The valid range of initialization vector lengths for the XChaCha20 cipher (12 bytes). + public static var ivRange = Range(12...12) + + /// Encrypts the given plaintext using the XChaCha20 cipher and generates an authentication + /// tag using the Poly1305 MAC. + /// + /// - Parameters: + /// - plainText: The plaintext to be encrypted. + /// - key: The encryption key. + /// - iv: The initialization vector. + /// - authenticationHeader: The authentication header. + /// - Returns: A tuple containing the ciphertext and authentication tag. + /// - Throws: An error if encryption fails. + public static func encrypt( + _ plainText: Array, + key: Array, + iv: Array, + authenticationHeader: Array + ) throws -> (cipherText: Array, authenticationTag: Array) { + try AEADChaCha20Poly1305.encrypt( + cipher: XChaCha20(key: key, iv: iv), + plainText, + key: key, + iv: iv, + authenticationHeader: authenticationHeader + ) + } + + /// Decrypts the given ciphertext using the XChaCha20 cipher and verifies the authentication + /// tag using the Poly1305 MAC. + /// + /// - Parameters: + /// - cipherText: The ciphertext to be decrypted. + /// - key: The decryption key. + /// - iv: The initialization vector. + /// - authenticationHeader: The authentication header. + /// - authenticationTag: The authentication tag. + /// - Returns: A tuple containing the decrypted plaintext and a boolean value indicating + /// the success of the decryption and authentication process. + /// - Throws: An error if decryption fails. + public static func decrypt( + _ cipherText: Array, + key: Array, + iv: Array, + authenticationHeader: Array, + authenticationTag: Array + ) throws -> (plainText: Array, success: Bool) { + try AEADChaCha20Poly1305.decrypt( + cipher: XChaCha20(key: key, iv: iv), + cipherText: cipherText, + key: key, + iv: iv, + authenticationHeader: authenticationHeader, + authenticationTag: authenticationTag + ) + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BitwiseOps.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BitwiseOps.swift new file mode 100644 index 00000000..d0ca3158 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BitwiseOps.swift @@ -0,0 +1,121 @@ +// +// BitwiseOps.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Bitwise Operations + +extension CS.BigUInt { + /// Return the ones' complement of `a`. + /// + /// - Complexity: O(a.count) + public static prefix func ~(a: CS.BigUInt) -> CS.BigUInt { + return CS.BigUInt(words: a.words.map { ~$0 }) + } + + /// Calculate the bitwise OR of `a` and `b`, and store the result in `a`. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func |= (a: inout CS.BigUInt, b: CS.BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] |= b[i] + } + } + + /// Calculate the bitwise AND of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func &= (a: inout CS.BigUInt, b: CS.BigUInt) { + for i in 0 ..< Swift.max(a.count, b.count) { + a[i] &= b[i] + } + } + + /// Calculate the bitwise XOR of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func ^= (a: inout CS.BigUInt, b: CS.BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] ^= b[i] + } + } +} + +extension CS.BigInt { + public static prefix func ~(x: CS.BigInt) -> CS.BigInt { + switch x.sign { + case .plus: + return CS.BigInt(sign: .minus, magnitude: x.magnitude + 1) + case .minus: + return CS.BigInt(sign: .plus, magnitude: x.magnitude - 1) + } + } + + public static func &(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] & right[i]) + } + if lhs.sign == .minus && rhs.sign == .minus { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func |(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] | right[i]) + } + if lhs.sign == .minus || rhs.sign == .minus { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func ^(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] ^ right[i]) + } + if (lhs.sign == .minus) != (rhs.sign == .minus) { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func &=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs & rhs + } + + public static func |=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs | rhs + } + + public static func ^=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs ^ rhs + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/DataConversion.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/DataConversion.swift new file mode 100644 index 00000000..c1d8d958 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/DataConversion.swift @@ -0,0 +1,179 @@ +// +// DataConversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +import Foundation + +extension CS.BigUInt { + //MARK: NSData Conversion + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + + var word: Word = 0 + for byte in buffer { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + assert(c == 0 && word == 0 && index == -1) + } + + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order. + public init(_ data: Data) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = data.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + let word: Word = data.withUnsafeBytes { buffPtr in + var word: Word = 0 + let p = buffPtr.bindMemory(to: UInt8.self) + for byte in p { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + return word + } + assert(c == 0 && word == 0 && index == -1) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order. + public func serialize() -> Data { + // This assumes Digit is binary. + precondition(Word.bitWidth % 8 == 0) + + let byteCount = (self.bitWidth + 7) / 8 + + guard byteCount > 0 else { return Data() } + + var data = Data(count: byteCount) + data.withUnsafeMutableBytes { buffPtr in + let p = buffPtr.bindMemory(to: UInt8.self) + var i = byteCount - 1 + for var word in self.words { + for _ in 0 ..< Word.bitWidth / 8 { + p[i] = UInt8(word & 0xFF) + word >>= 8 + if i == 0 { + assert(word == 0) + break + } + i -= 1 + } + } + } + return data + } +} + +extension CS.BigInt { + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer, + /// where the first byte indicates sign (0 for positive, 1 for negative) + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard length > 1, let firstByte = buffer.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + self.magnitude = CS.BigUInt(UnsafeRawBufferPointer(rebasing: buffer.dropFirst(1))) + } + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order with a first + /// byte to represent the sign (0 for positive, 1 for negative) + public init(_ data: Data) { + // This assumes Word is binary. + // This is the same assumption made when initializing CS.BigUInt from Data + precondition(Word.bitWidth % 8 == 0) + + self.init() + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard data.count > 1, let firstByte = data.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + // The remaining bytes are read and stored as the magnitude + self.magnitude = CS.BigUInt(data.dropFirst(1)) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order and a prepended byte to indicate the sign (0 for positive, 1 for negative) + public func serialize() -> Data { + // Create a data object for the magnitude portion of the BigInt + let magnitudeData = self.magnitude.serialize() + + // Similar to CS.BigUInt, a value of 0 should return an initialized, empty Data struct + guard magnitudeData.count > 0 else { return magnitudeData } + + // Create a new Data struct for the signed BigInt value + var data = Data(capacity: magnitudeData.count + 1) + + // The first byte should be 0 for a positive value, or 1 for a negative value + // i.e., the sign bit is the LSB + data.append(self.sign == .plus ? 0 : 1) + + data.append(magnitudeData) + return data + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/FloatingPointConversion.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/FloatingPointConversion.swift new file mode 100644 index 00000000..9b97c440 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/FloatingPointConversion.swift @@ -0,0 +1,73 @@ +// +// FloatingPointConversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + public init?(exactly source: T) { + guard source.isFinite else { return nil } + guard !source.isZero else { self = 0; return } + guard source.sign == .plus else { return nil } + let value = source.rounded(.towardZero) + guard value == source else { return nil } + assert(value.floatingPointClass == .positiveNormal) + assert(value.exponent >= 0) + let significand = value.significandBitPattern + self = (CS.BigUInt(1) << value.exponent) + CS.BigUInt(significand) >> (T.significandBitCount - Int(value.exponent)) + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension CS.BigInt { + public init?(exactly source: T) { + switch source.sign{ + case .plus: + guard let magnitude = CS.BigUInt(exactly: source) else { return nil } + self = CS.BigInt(sign: .plus, magnitude: magnitude) + case .minus: + guard let magnitude = CS.BigUInt(exactly: -source) else { return nil } + self = CS.BigInt(sign: .minus, magnitude: magnitude) + } + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension BinaryFloatingPoint where RawExponent: FixedWidthInteger, RawSignificand: FixedWidthInteger { + public init(_ value: CS.BigInt) { + guard !value.isZero else { self = 0; return } + let v = value.magnitude + let bitWidth = v.bitWidth + var exponent = bitWidth - 1 + let shift = bitWidth - Self.significandBitCount - 1 + var significand = value.magnitude >> (shift - 1) + if significand[0] & 3 == 3 { // Handle rounding + significand >>= 1 + significand += 1 + if significand.trailingZeroBitCount >= Self.significandBitCount { + exponent += 1 + } + } + else { + significand >>= 1 + } + let bias = 1 << (Self.exponentBitCount - 1) - 1 + guard exponent <= bias else { self = Self.infinity; return } + significand &= 1 << Self.significandBitCount - 1 + self = Self.init(sign: value.sign == .plus ? .plus : .minus, + exponentBitPattern: RawExponent(bias + exponent), + significandBitPattern: RawSignificand(significand)) + } + + public init(_ value: CS.BigUInt) { + self.init(CS.BigInt(sign: .plus, magnitude: value)) + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/IntegerConversion.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/IntegerConversion.swift new file mode 100644 index 00000000..0ecd3c7c --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/IntegerConversion.swift @@ -0,0 +1,89 @@ +// +// IntegerConversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + public init?(exactly source: T) { + guard source >= (0 as T) else { return nil } + if source.bitWidth <= 2 * Word.bitWidth { + var it = source.words.makeIterator() + self.init(low: it.next() ?? 0, high: it.next() ?? 0) + precondition(it.next() == nil, "Length of BinaryInteger.words is greater than its bitWidth") + } + else { + self.init(words: source.words) + } + } + + public init(_ source: T) { + precondition(source >= (0 as T), "BigUInt cannot represent negative values") + self.init(exactly: source)! + } + + public init(truncatingIfNeeded source: T) { + self.init(words: source.words) + } + + public init(clamping source: T) { + if source <= (0 as T) { + self.init() + } + else { + self.init(words: source.words) + } + } +} + +extension CS.BigInt { + public init() { + self.init(sign: .plus, magnitude: 0) + } + + /// Initializes a new signed big integer with the same value as the specified unsigned big integer. + public init(_ integer: CS.BigUInt) { + self.magnitude = integer + self.sign = .plus + } + + public init(_ source: T) where T : BinaryInteger { + if source >= (0 as T) { + self.init(sign: .plus, magnitude: CS.BigUInt(source)) + } + else { + var words = Array(source.words) + words.twosComplement() + self.init(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + } + + public init?(exactly source: T) where T : BinaryInteger { + self.init(source) + } + + public init(clamping source: T) where T : BinaryInteger { + self.init(source) + } + + public init(truncatingIfNeeded source: T) where T : BinaryInteger { + self.init(source) + } +} + +extension CS.BigUInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: UInt64) { + self.init(value) + } +} + +extension CS.BigInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: Int64) { + self.init(value) + } +} + diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/PrimeTest.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/PrimeTest.swift new file mode 100644 index 00000000..4eb4a96b --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/PrimeTest.swift @@ -0,0 +1,153 @@ +// +// PrimeTest.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +/// The first several [prime numbers][primes]. +/// +/// [primes]: https://oeis.org/A000040 +let primes: [CS.BigUInt.Word] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] + +/// The ith element in this sequence is the smallest composite number that passes the strong probable prime test +/// for all of the first (i+1) primes. +/// +/// This is sequence [A014233](http://oeis.org/A014233) on the [Online Encyclopaedia of Integer Sequences](http://oeis.org). +let pseudoPrimes: [CS.BigUInt] = [ + /* 2 */ 2_047, + /* 3 */ 1_373_653, + /* 5 */ 25_326_001, + /* 7 */ 3_215_031_751, + /* 11 */ 2_152_302_898_747, + /* 13 */ 3_474_749_660_383, + /* 17 */ 341_550_071_728_321, + /* 19 */ 341_550_071_728_321, + /* 23 */ 3_825_123_056_546_413_051, + /* 29 */ 3_825_123_056_546_413_051, + /* 31 */ 3_825_123_056_546_413_051, + /* 37 */ "318665857834031151167461", + /* 41 */ "3317044064679887385961981", +] + +extension CS.BigUInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: CS.BigUInt) -> Bool { + precondition(base > (1 as CS.BigUInt)) + precondition(self > (0 as CS.BigUInt)) + let dec = self - 1 + + let r = dec.trailingZeroBitCount + let d = dec >> r + + var test = base.power(d, modulus: self) + if test == 1 || test == dec { return true } + + if r > 0 { + let shift = self.leadingZeroBitCount + let normalized = self << shift + for _ in 1 ..< r { + test *= test + test.formRemainder(dividingBy: normalized, normalizedBy: shift) + if test == 1 { + return false + } + if test == dec { return true } + } + } + return false + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if count <= 1 && self[0] < 2 { return false } + if count == 1 && self[0] < 4 { return true } + + // Even numbers above 2 aren't prime. + if self[0] & 1 == 0 { return false } + + // Quickly check for small primes. + for i in 1 ..< primes.count { + let p = primes[i] + if self.count == 1 && self[0] == p { + return true + } + if self.quotientAndRemainder(dividingByWord: p).remainder == 0 { + return false + } + } + + /// Give an exact answer when we can. + if self < pseudoPrimes.last! { + for i in 0 ..< pseudoPrimes.count { + guard isStrongProbablePrime(CS.BigUInt(primes[i])) else { + break + } + if self < pseudoPrimes[i] { + // `self` is below the lowest pseudoprime corresponding to the prime bases we tested. It's a prime! + return true + } + } + return false + } + + /// Otherwise do as many rounds of random SPPT as required. + for _ in 0 ..< rounds { + let random = CS.BigUInt.randomInteger(lessThan: self - 2) + 2 + guard isStrongProbablePrime(random) else { + return false + } + } + + // Well, it smells primey to me. + return true + } +} + +extension CS.BigInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: CS.BigInt) -> Bool { + precondition(base.sign == .plus) + if self.sign == .minus { return false } + return self.magnitude.isStrongProbablePrime(base.magnitude) + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if self.sign == .minus { return false } + return self.magnitude.isPrime(rounds: rounds) + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/SquareRoot.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/SquareRoot.swift new file mode 100644 index 00000000..ca4446ef --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/SquareRoot.swift @@ -0,0 +1,41 @@ +// +// SquareRoot.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Square Root + +extension CS.BigUInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> CS.BigUInt { + // This implementation uses Newton's method. + guard !self.isZero else { return CS.BigUInt() } + var x = CS.BigUInt(1) << ((self.bitWidth + 1) / 2) + var y: CS.BigUInt = 0 + while true { + y.load(self) + y /= x + y += x + y >>= 1 + if x == y || x == y - 1 { break } + x = y + } + return x + } +} + +extension CS.BigInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Requires: self >= 0 + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> CS.BigInt { + precondition(self.sign == .plus) + return CS.BigInt(sign: .plus, magnitude: self.magnitude.squareRoot()) + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/StringConversion.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/StringConversion.swift new file mode 100644 index 00000000..9ae72e95 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/StringConversion.swift @@ -0,0 +1,240 @@ +// +// StringConversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + + //MARK: String Conversion + + /// Calculates the number of numerals in a given radix that fit inside a single `Word`. + /// + /// - Returns: (chars, power) where `chars` is highest that satisfy `radix^chars <= 2^Word.bitWidth`. `power` is zero + /// if radix is a power of two; otherwise `power == radix^chars`. + fileprivate static func charsPerWord(forRadix radix: Int) -> (chars: Int, power: Word) { + var power: Word = 1 + var overflow = false + var count = 0 + while !overflow { + let (high,low) = power.multipliedFullWidth(by: Word(radix)) + if high > 0 { + overflow = true + } + + if !overflow || (high == 1 && low == 0) { + count += 1 + power = low + } + } + return (count, power) + } + + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string consisting of characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + precondition(radix > 1 && radix < 36) + guard !text.isEmpty else { return nil } + let (charsPerWord, power) = CS.BigUInt.charsPerWord(forRadix: radix) + + var words: [Word] = [] + var end = text.endIndex + var start = end + var count = 0 + while start != text.startIndex { + start = text.index(before: start) + count += 1 + if count == charsPerWord { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + end = start + count = 0 + } + } + if start != end { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + } + + if power == 0 { + self.init(words: words) + } + else { + self.init() + for d in words.reversed() { + self.multiply(byWord: power) + self.addWord(d) + } + } + } +} + +extension CS.BigInt { + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string optionally starting with "-" or "+" followed by characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + var magnitude: CS.BigUInt? + var sign: Sign = .plus + if text.first == "-" { + sign = .minus + let text = text.dropFirst() + magnitude = CS.BigUInt(text, radix: radix) + } + else if text.first == "+" { + let text = text.dropFirst() + magnitude = CS.BigUInt(text, radix: radix) + } + else { + magnitude = CS.BigUInt(text, radix: radix) + } + guard let m = magnitude else { return nil } + self.magnitude = m + self.sign = m.isZero ? .plus : sign + } +} + +extension String { + /// Initialize a new string with the base-10 representation of an unsigned big integer. + /// + /// - Complexity: O(v.count^2) + public init(_ v: CS.BigUInt) { self.init(v, radix: 10, uppercase: false) } + + /// Initialize a new string representing an unsigned big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ v: CS.BigUInt, radix: Int, uppercase: Bool = false) { + precondition(radix > 1) + let (charsPerWord, power) = CS.BigUInt.charsPerWord(forRadix: radix) + + guard !v.isZero else { self = "0"; return } + + var parts: [String] + if power == 0 { + parts = v.words.map { String($0, radix: radix, uppercase: uppercase) } + } + else { + parts = [] + var rest = v + while !rest.isZero { + let mod = rest.divide(byWord: power) + parts.append(String(mod, radix: radix, uppercase: uppercase)) + } + } + assert(!parts.isEmpty) + + self = "" + var first = true + for part in parts.reversed() { + let zeroes = charsPerWord - part.count + assert(zeroes >= 0) + if !first && zeroes > 0 { + // Insert leading zeroes for mid-Words + self += String(repeating: "0", count: zeroes) + } + first = false + self += part + } + } + + /// Initialize a new string representing a signed big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ value: CS.BigInt, radix: Int = 10, uppercase: Bool = false) { + self = String(value.magnitude, radix: radix, uppercase: uppercase) + if value.sign == .minus { + self = "-" + self + } + } +} + +extension CS.BigUInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = CS.BigUInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = CS.BigUInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = CS.BigUInt(value, radix: 10)! + } +} + +extension CS.BigInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = CS.BigInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = CS.BigInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = CS.BigInt(value, radix: 10)! + } +} + +extension CS.BigUInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension CS.BigInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension CS.BigUInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.bitWidth) bits)" + } +} + +extension CS.BigInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.magnitude.bitWidth) bits)" + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/WordsAndBits.swift b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/WordsAndBits.swift new file mode 100644 index 00000000..158937c6 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/WordsAndBits.swift @@ -0,0 +1,202 @@ +// +// WordsAndBits.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension Array where Element == UInt { + mutating func twosComplement() { + var increment = true + for i in 0 ..< self.count { + if increment { + (self[i], increment) = (~self[i]).addingReportingOverflow(1) + } + else { + self[i] = ~self[i] + } + } + } +} + +extension CS.BigUInt { + public subscript(bitAt index: Int) -> Bool { + get { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + return self[i] & (1 << j) != 0 + } + set { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + if newValue { + self[i] |= 1 << j + } + else { + self[i] &= ~(1 << j) + } + } + } +} + +extension CS.BigUInt { + /// The minimum number of bits required to represent this integer in binary. + /// + /// - Returns: floor(log2(2 * self + 1)) + /// - Complexity: O(1) + public var bitWidth: Int { + guard count > 0 else { return 0 } + return count * Word.bitWidth - self[count - 1].leadingZeroBitCount + } + + /// The number of leading zero bits in the binary representation of this integer in base `2^(Word.bitWidth)`. + /// This is useful when you need to normalize a `BigUInt` such that the top bit of its most significant word is 1. + /// + /// - Note: 0 is considered to have zero leading zero bits. + /// - Returns: A value in `0...(Word.bitWidth - 1)`. + /// - SeeAlso: width + /// - Complexity: O(1) + public var leadingZeroBitCount: Int { + guard count > 0 else { return 0 } + return self[count - 1].leadingZeroBitCount + } + + /// The number of trailing zero bits in the binary representation of this integer. + /// + /// - Note: 0 is considered to have zero trailing zero bits. + /// - Returns: A value in `0...width`. + /// - Complexity: O(count) + public var trailingZeroBitCount: Int { + guard count > 0 else { return 0 } + let i = self.words.firstIndex { $0 != 0 }! + return i * Word.bitWidth + self[i].trailingZeroBitCount + } +} + +extension CS.BigInt { + public var bitWidth: Int { + guard !magnitude.isZero else { return 0 } + return magnitude.bitWidth + 1 + } + + public var trailingZeroBitCount: Int { + // Amazingly, this works fine for negative numbers + return magnitude.trailingZeroBitCount + } +} + +extension CS.BigUInt { + public struct Words: RandomAccessCollection { + private let value: CS.BigUInt + + fileprivate init(_ value: CS.BigUInt) { self.value = value } + + public var startIndex: Int { return 0 } + public var endIndex: Int { return value.count } + + public subscript(_ index: Int) -> Word { + return value[index] + } + } + + public var words: Words { return Words(self) } + + public init(words: Words) where Words.Element == Word { + let uc = words.underestimatedCount + if uc > 2 { + self.init(words: Array(words)) + } + else { + var it = words.makeIterator() + guard let w0 = it.next() else { + self.init() + return + } + guard let w1 = it.next() else { + self.init(word: w0) + return + } + if let w2 = it.next() { + var words: [UInt] = [] + words.reserveCapacity(Swift.max(3, uc)) + words.append(w0) + words.append(w1) + words.append(w2) + while let word = it.next() { + words.append(word) + } + self.init(words: words) + } + else { + self.init(low: w0, high: w1) + } + } + } +} + +extension CS.BigInt { + public struct Words: RandomAccessCollection { + public typealias Indices = CountableRange + + private let value: CS.BigInt + private let decrementLimit: Int + + fileprivate init(_ value: CS.BigInt) { + self.value = value + switch value.sign { + case .plus: + self.decrementLimit = 0 + case .minus: + assert(!value.magnitude.isZero) + self.decrementLimit = value.magnitude.words.firstIndex(where: { $0 != 0 })! + } + } + + public var count: Int { + switch value.sign { + case .plus: + if let high = value.magnitude.words.last, high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + case .minus: + let high = value.magnitude.words.last! + if high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + } + } + + public var indices: Indices { return 0 ..< count } + public var startIndex: Int { return 0 } + public var endIndex: Int { return count } + + public subscript(_ index: Int) -> UInt { + // Note that indices above `endIndex` are accepted. + if value.sign == .plus { + return value.magnitude[index] + } + if index <= decrementLimit { + return ~(value.magnitude[index] &- 1) + } + return ~value.magnitude[index] + } + } + + public var words: Words { + return Words(self) + } + + public init(words: S) where S.Element == Word { + var words = Array(words) + if (words.last ?? 0) >> (Word.bitWidth - 1) == 0 { + self.init(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + else { + words.twosComplement() + self.init(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/XChaCha20+Foundation.swift b/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/XChaCha20+Foundation.swift new file mode 100644 index 00000000..b9f052e9 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/XChaCha20+Foundation.swift @@ -0,0 +1,29 @@ +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension XChaCha20 { + /// Convenience initializer that creates an XChaCha20 instance with the given key and IV + /// represented as hex-encoded strings. + /// + /// - Parameters: + /// - key: The encryption/decryption key as a hex-encoded string. + /// - iv: The initialization vector as a hex-encoded string. + /// - Throws: An error if the provided key or IV are of invalid length, format, or not hex-encoded. + public convenience init(key: String, iv: String) throws { + try self.init(key: key.bytes, iv: iv.bytes) + } +} diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/PrivacyInfo.xcprivacy b/Pods/CryptoSwift/Sources/CryptoSwift/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..e08a130b --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/Pods/CryptoSwift/Sources/CryptoSwift/XChaCha20.swift b/Pods/CryptoSwift/Sources/CryptoSwift/XChaCha20.swift new file mode 100644 index 00000000..71b902d7 --- /dev/null +++ b/Pods/CryptoSwift/Sources/CryptoSwift/XChaCha20.swift @@ -0,0 +1,232 @@ +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// XChaCha20 is a Swift implementation of the XChaCha20 stream cipher, which is an extension of the ChaCha20 cipher +/// that uses a 192-bit nonce instead of the original 64-bit nonce. XChaCha20 provides a higher security level by +/// allowing a larger number of safe random nonces, reducing the risk of nonce reuse. +/// +/// For more information about the XChaCha20 algorithm, refer to the IETF draft: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha +public final class XChaCha20: BlockCipher, BlockMode { + + public enum Error: Swift.Error { + case invalidKeyOrInitializationVector + case notSupported + } + + fileprivate var chacha20: ChaCha20 + + // MARK: BlockCipher + + public static let blockSize = 64 // 512 / 8 + + // MARK: Cipher + + public let keySize: Int + + /// Initializes a new instance of XChaCha20 with the provided key, nonce, and optional block counter. + /// - Parameters: + /// - key: A 256-bit (32-byte) key for the XChaCha20 cipher. + /// - nonce: A 192-bit (24-byte) nonce for the XChaCha20 cipher. + /// - blockCounter: An optional initial block counter value, defaulting to 0. + /// - Throws: Error.invalidKeyOrInitializationVector if the key or nonce lengths are not valid. + public init(key: Array, iv nonce: Array, blockCounter: UInt32 = 0) throws { + guard key.count == 32 && nonce.count == 24 else { + throw Error.invalidKeyOrInitializationVector + } + + self.keySize = key.count + + // From https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#section-2.3 + // XChaCha20 can be constructed from an existing ChaCha20 implementation + // and HChaCha20. All one needs to do is: + // + // 1. Pass the key and the first 16 bytes of the 24-byte nonce to + // HChaCha20 to obtain the subkey. + // + // 2. Use the subkey and remaining 8 byte nonce with ChaCha20 as normal + // (prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte + // nonce). + self.chacha20 = try .init( + key: XChaCha20.hChaCha20(key: key, nonce: Array(nonce[0..<16])), + iv: [0, 0, 0, 0] + Array(nonce[16..<24]), + blockCounter: blockCounter + ) + } + + // MARK: BlockMode + + /// Options specific to the block mode. + public let options: BlockModeOption = [.none] + /// The custom block size for the block mode, if any. XChaCha20 does not have a custom block size. + public let customBlockSize: Int? = nil + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + return XChaCha20Worker( + blockSize: blockSize, + cipherOperation: cipherOperation, + xChaCha20: self + ) + } + + /// Computes the HChaCha20 function on the provided key and nonce. + /// + /// See: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#section-2.2 + /// + /// - Parameters: + /// - key: A 256-bit (32-byte) key. + /// - nonce: A 128-bit (16-byte) nonce. + /// - Returns: A 256-bit (32-byte) derived key. + static func hChaCha20(key: [UInt8], nonce: [UInt8]) -> [UInt8] { + precondition(key.count == 32) + precondition(nonce.count == 16) + + // HChaCha20 is initialized the same way as the ChaCha cipher, except + // that HChaCha20 uses a 128-bit nonce and has no counter. Instead, the + // block counter is replaced by the first 32 bits of the nonce. + + var state = Array(repeating: 0, count: 16) + + state[0] = 0x61707865 + state[1] = 0x3320646e + state[2] = 0x79622d32 + state[3] = 0x6b206574 + for i in 0..<8 { + state[4 + i] = UInt32(bytes: key[i * 4..<(i + 1) * 4]).bigEndian + } + for i in 0..<4 { + state[12 + i] = UInt32(bytes: nonce[i * 4..<(i + 1) * 4]).bigEndian + } + + // After initialization, proceed through the ChaCha rounds as usual. + + for _ in 1...10 { + self.innerBlock(&state) + } + + // Once the 20 ChaCha rounds have been completed, the first 128 bits and + // last 128 bits of the ChaCha state (both little-endian) are + // concatenated, and this 256-bit subkey is returned. + + var output = Array() + for i in 0..<4 { + output += state[i].bigEndian.bytes() + } + for i in 0..<4 { + output += state[12 + i].bigEndian.bytes() + } + + return output + } + + /// Performs the "quarter round" operation on the provided state at the specified indices. + /// - Parameters: + /// - state: The state on which to perform the operation. + /// - a: The index of the first element in the state. + /// - b: The index of the second element in the state. + /// - c: The index of the third element in the state. + /// - d: The index of the fourth element in the state. + static func qRound(_ state: inout [UInt32], _ a: Int, _ b: Int, _ c: Int, _ d: Int) { + state[a] = state[a] &+ state[b] + state[d] ^= state[a] + state[d] = (state[d] << 16) | (state[d] >> 16) + state[c] = state[c] &+ state[d] + state[b] ^= state[c] + state[b] = (state[b] << 12) | (state[b] >> 20) + state[a] = state[a] &+ state[b] + state[d] ^= state[a] + state[d] = (state[d] << 8) | (state[d] >> 24) + state[c] = state[c] &+ state[d] + state[b] ^= state[c] + state[b] = (state[b] << 7) | (state[b] >> 25) + } + + /// Performs the inner block operation on the provided state. + /// - Parameter state: The state on which to perform the operation. + static func innerBlock(_ state: inout [UInt32]) { + self.qRound(&state, 0, 4, 8, 12) + self.qRound(&state, 1, 5, 9, 13) + self.qRound(&state, 2, 6, 10, 14) + self.qRound(&state, 3, 7, 11, 15) + self.qRound(&state, 0, 5, 10, 15) + self.qRound(&state, 1, 6, 11, 12) + self.qRound(&state, 2, 7, 8, 13) + self.qRound(&state, 3, 4, 9, 14) + } +} + +// MARK: Cipher + +extension XChaCha20: Cipher { + public func encrypt(_ bytes: ArraySlice) throws -> Array { + try self.chacha20.encrypt(bytes) + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + try self.encrypt(bytes) + } +} + +// MARK: Cryptors + +extension XChaCha20: Cryptors { + + public func makeEncryptor() throws -> Cryptor & Updatable { + return try BlockEncryptor( + blockSize: XChaCha20.blockSize, + padding: .noPadding, + self.worker( + blockSize: XChaCha20.blockSize, + cipherOperation: { _ in nil }, + encryptionOperation: { _ in nil } + ) + ) + } + + public func makeDecryptor() throws -> Cryptor & Updatable { + return try BlockDecryptor( + blockSize: XChaCha20.blockSize, + padding: .noPadding, + self.worker( + blockSize: XChaCha20.blockSize, + cipherOperation: { _ in nil }, + encryptionOperation: { _ in nil } + ) + ) + } +} + +class XChaCha20Worker: CipherModeWorker { + let blockSize: Int + let cipherOperation: CipherOperationOnBlock + let xChaCha20: XChaCha20 + + init(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, xChaCha20: XChaCha20) { + self.blockSize = blockSize + self.cipherOperation = cipherOperation + self.xChaCha20 = xChaCha20 + } + + var additionalBufferSize: Int { + return 0 + } + + func encrypt(block plaintext: ArraySlice) -> Array { + return (try? self.xChaCha20.encrypt(plaintext)) ?? .init() + } + + func decrypt(block ciphertext: ArraySlice) -> Array { + return (try? self.xChaCha20.decrypt(ciphertext)) ?? .init() + } +} diff --git a/Pods/Headers/Private/LookinServer/CALayer+Lookin.h b/Pods/Headers/Private/LookinServer/CALayer+Lookin.h new file mode 120000 index 00000000..1fb4d3b5 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/CALayer+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/CALayer+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/CALayer+LookinServer.h b/Pods/Headers/Private/LookinServer/CALayer+LookinServer.h new file mode 120000 index 00000000..9e6c27f5 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/CALayer+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/CALayer+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Color+Lookin.h b/Pods/Headers/Private/LookinServer/Color+Lookin.h new file mode 120000 index 00000000..c43a4a03 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Color+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/Color+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Image+Lookin.h b/Pods/Headers/Private/LookinServer/Image+Lookin.h new file mode 120000 index 00000000..6adea58c --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Image+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/Image+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKSConfigManager.h b/Pods/Headers/Private/LookinServer/LKSConfigManager.h new file mode 120000 index 00000000..3897f082 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKSConfigManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKSConfigManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_AttrGroupsMaker.h b/Pods/Headers/Private/LookinServer/LKS_AttrGroupsMaker.h new file mode 120000 index 00000000..119c09e9 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_AttrGroupsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_AttrModificationPatchHandler.h b/Pods/Headers/Private/LookinServer/LKS_AttrModificationPatchHandler.h new file mode 120000 index 00000000..62267200 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_AttrModificationPatchHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_ConnectionManager.h b/Pods/Headers/Private/LookinServer/LKS_ConnectionManager.h new file mode 120000 index 00000000..1a09cbc8 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_ConnectionManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_CustomAttrGroupsMaker.h b/Pods/Headers/Private/LookinServer/LKS_CustomAttrGroupsMaker.h new file mode 120000 index 00000000..0945019e --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_CustomAttrGroupsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_CustomAttrModificationHandler.h b/Pods/Headers/Private/LookinServer/LKS_CustomAttrModificationHandler.h new file mode 120000 index 00000000..97c4ec96 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_CustomAttrModificationHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_CustomAttrSetterManager.h b/Pods/Headers/Private/LookinServer/LKS_CustomAttrSetterManager.h new file mode 120000 index 00000000..b962ddae --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_CustomAttrSetterManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_CustomDisplayItemsMaker.h b/Pods/Headers/Private/LookinServer/LKS_CustomDisplayItemsMaker.h new file mode 120000 index 00000000..d758ffa7 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_CustomDisplayItemsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_EventHandlerMaker.h b/Pods/Headers/Private/LookinServer/LKS_EventHandlerMaker.h new file mode 120000 index 00000000..21c02dbf --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_EventHandlerMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_ExportManager.h b/Pods/Headers/Private/LookinServer/LKS_ExportManager.h new file mode 120000 index 00000000..e558781c --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_ExportManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_ExportManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_GestureTargetActionsSearcher.h b/Pods/Headers/Private/LookinServer/LKS_GestureTargetActionsSearcher.h new file mode 120000 index 00000000..f1c91dd0 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_GestureTargetActionsSearcher.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_Helper.h b/Pods/Headers/Private/LookinServer/LKS_Helper.h new file mode 120000 index 00000000..048399e9 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_Helper.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_Helper.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_HierarchyDetailsHandler.h b/Pods/Headers/Private/LookinServer/LKS_HierarchyDetailsHandler.h new file mode 120000 index 00000000..e4f47cc5 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_HierarchyDetailsHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_HierarchyDisplayItemsMaker.h b/Pods/Headers/Private/LookinServer/LKS_HierarchyDisplayItemsMaker.h new file mode 120000 index 00000000..0d6eae17 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_HierarchyDisplayItemsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_InbuiltAttrModificationHandler.h b/Pods/Headers/Private/LookinServer/LKS_InbuiltAttrModificationHandler.h new file mode 120000 index 00000000..93e611c5 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_InbuiltAttrModificationHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_MultiplatformAdapter.h b/Pods/Headers/Private/LookinServer/LKS_MultiplatformAdapter.h new file mode 120000 index 00000000..528d9dec --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_MultiplatformAdapter.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_ObjectRegistry.h b/Pods/Headers/Private/LookinServer/LKS_ObjectRegistry.h new file mode 120000 index 00000000..c24f674e --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_ObjectRegistry.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_RequestHandler.h b/Pods/Headers/Private/LookinServer/LKS_RequestHandler.h new file mode 120000 index 00000000..b176ecdb --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_RequestHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LKS_TraceManager.h b/Pods/Headers/Private/LookinServer/LKS_TraceManager.h new file mode 120000 index 00000000..776c4d34 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LKS_TraceManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_TraceManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAppInfo.h b/Pods/Headers/Private/LookinServer/LookinAppInfo.h new file mode 120000 index 00000000..e1804d9a --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAppInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAppInfo.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttrIdentifiers.h b/Pods/Headers/Private/LookinServer/LookinAttrIdentifiers.h new file mode 120000 index 00000000..91f0a8d8 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttrIdentifiers.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttrIdentifiers.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttrType.h b/Pods/Headers/Private/LookinServer/LookinAttrType.h new file mode 120000 index 00000000..1b32f48f --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttrType.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttrType.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttribute.h b/Pods/Headers/Private/LookinServer/LookinAttribute.h new file mode 120000 index 00000000..4aa2bd42 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttribute.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttribute.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttributeModification.h b/Pods/Headers/Private/LookinServer/LookinAttributeModification.h new file mode 120000 index 00000000..837d0e2f --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttributeModification.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributeModification.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttributesGroup.h b/Pods/Headers/Private/LookinServer/LookinAttributesGroup.h new file mode 120000 index 00000000..80dbc433 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttributesGroup.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributesGroup.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAttributesSection.h b/Pods/Headers/Private/LookinServer/LookinAttributesSection.h new file mode 120000 index 00000000..b315eef4 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAttributesSection.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributesSection.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinAutoLayoutConstraint.h b/Pods/Headers/Private/LookinServer/LookinAutoLayoutConstraint.h new file mode 120000 index 00000000..92375f87 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinAutoLayoutConstraint.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinCodingValueType.h b/Pods/Headers/Private/LookinServer/LookinCodingValueType.h new file mode 120000 index 00000000..0d9a1a72 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinCodingValueType.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCodingValueType.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinConnectionAttachment.h b/Pods/Headers/Private/LookinServer/LookinConnectionAttachment.h new file mode 120000 index 00000000..0dc19c20 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinConnectionAttachment.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinConnectionAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinConnectionResponseAttachment.h b/Pods/Headers/Private/LookinServer/LookinConnectionResponseAttachment.h new file mode 120000 index 00000000..58e8941c --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinConnectionResponseAttachment.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinCustomAttrModification.h b/Pods/Headers/Private/LookinServer/LookinCustomAttrModification.h new file mode 120000 index 00000000..60e8b02e --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinCustomAttrModification.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCustomAttrModification.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinCustomDisplayItemInfo.h b/Pods/Headers/Private/LookinServer/LookinCustomDisplayItemInfo.h new file mode 120000 index 00000000..0e9b289b --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinCustomDisplayItemInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinDashboardBlueprint.h b/Pods/Headers/Private/LookinServer/LookinDashboardBlueprint.h new file mode 120000 index 00000000..6d626836 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinDashboardBlueprint.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDashboardBlueprint.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinDefines.h b/Pods/Headers/Private/LookinServer/LookinDefines.h new file mode 120000 index 00000000..e1ca4d2a --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinDefines.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDefines.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinDisplayItem.h b/Pods/Headers/Private/LookinServer/LookinDisplayItem.h new file mode 120000 index 00000000..1f17d761 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinDisplayItem.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDisplayItem.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinDisplayItemDetail.h b/Pods/Headers/Private/LookinServer/LookinDisplayItemDetail.h new file mode 120000 index 00000000..4710c9cb --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinDisplayItemDetail.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDisplayItemDetail.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinEventHandler.h b/Pods/Headers/Private/LookinServer/LookinEventHandler.h new file mode 120000 index 00000000..89539242 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinEventHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinEventHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinHierarchyFile.h b/Pods/Headers/Private/LookinServer/LookinHierarchyFile.h new file mode 120000 index 00000000..94a58b83 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinHierarchyFile.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinHierarchyFile.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinHierarchyInfo.h b/Pods/Headers/Private/LookinServer/LookinHierarchyInfo.h new file mode 120000 index 00000000..9511ff68 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinHierarchyInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinHierarchyInfo.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinIvarTrace.h b/Pods/Headers/Private/LookinServer/LookinIvarTrace.h new file mode 120000 index 00000000..9049ab07 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinIvarTrace.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Base/LookinIvarTrace.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinObject.h b/Pods/Headers/Private/LookinServer/LookinObject.h new file mode 120000 index 00000000..cf8241af --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinObject.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinObject.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinServer.h b/Pods/Headers/Private/LookinServer/LookinServer.h new file mode 120000 index 00000000..e9db4c37 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinServerDefines.h b/Pods/Headers/Private/LookinServer/LookinServerDefines.h new file mode 120000 index 00000000..dbfa8133 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinServerDefines.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LookinServerDefines.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinStaticAsyncUpdateTask.h b/Pods/Headers/Private/LookinServer/LookinStaticAsyncUpdateTask.h new file mode 120000 index 00000000..4e93a9cd --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinStaticAsyncUpdateTask.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinTuple.h b/Pods/Headers/Private/LookinServer/LookinTuple.h new file mode 120000 index 00000000..c0d394bf --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinTuple.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinTuple.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/LookinWeakContainer.h b/Pods/Headers/Private/LookinServer/LookinWeakContainer.h new file mode 120000 index 00000000..ddd4ef30 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/LookinWeakContainer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinWeakContainer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Lookin_PTChannel.h b/Pods/Headers/Private/LookinServer/Lookin_PTChannel.h new file mode 120000 index 00000000..ba83c7a8 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Lookin_PTChannel.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Lookin_PTPrivate.h b/Pods/Headers/Private/LookinServer/Lookin_PTPrivate.h new file mode 120000 index 00000000..180b02d0 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Lookin_PTPrivate.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTPrivate.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Lookin_PTProtocol.h b/Pods/Headers/Private/LookinServer/Lookin_PTProtocol.h new file mode 120000 index 00000000..104f6f4e --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Lookin_PTProtocol.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Lookin_PTUSBHub.h b/Pods/Headers/Private/LookinServer/Lookin_PTUSBHub.h new file mode 120000 index 00000000..46b7ae05 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Lookin_PTUSBHub.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/NSArray+Lookin.h b/Pods/Headers/Private/LookinServer/NSArray+Lookin.h new file mode 120000 index 00000000..43fe2ddf --- /dev/null +++ b/Pods/Headers/Private/LookinServer/NSArray+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSArray+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/NSObject+Lookin.h b/Pods/Headers/Private/LookinServer/NSObject+Lookin.h new file mode 120000 index 00000000..3d1227ec --- /dev/null +++ b/Pods/Headers/Private/LookinServer/NSObject+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSObject+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/NSObject+LookinServer.h b/Pods/Headers/Private/LookinServer/NSObject+LookinServer.h new file mode 120000 index 00000000..9ffa84d9 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/NSObject+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/NSObject+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/NSSet+Lookin.h b/Pods/Headers/Private/LookinServer/NSSet+Lookin.h new file mode 120000 index 00000000..172bd142 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/NSSet+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSSet+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/NSString+Lookin.h b/Pods/Headers/Private/LookinServer/NSString+Lookin.h new file mode 120000 index 00000000..5fc3c763 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/NSString+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSString+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/Peertalk.h b/Pods/Headers/Private/LookinServer/Peertalk.h new file mode 120000 index 00000000..4c14ff46 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/Peertalk.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Peertalk.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIBlurEffect+LookinServer.h b/Pods/Headers/Private/LookinServer/UIBlurEffect+LookinServer.h new file mode 120000 index 00000000..9abcb3c2 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIBlurEffect+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIColor+LookinServer.h b/Pods/Headers/Private/LookinServer/UIColor+LookinServer.h new file mode 120000 index 00000000..14d7befe --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIColor+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIColor+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIImage+LookinServer.h b/Pods/Headers/Private/LookinServer/UIImage+LookinServer.h new file mode 120000 index 00000000..96b81aa4 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIImage+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIImage+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIImageView+LookinServer.h b/Pods/Headers/Private/LookinServer/UIImageView+LookinServer.h new file mode 120000 index 00000000..5731be2b --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIImageView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UILabel+LookinServer.h b/Pods/Headers/Private/LookinServer/UILabel+LookinServer.h new file mode 120000 index 00000000..09c42193 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UILabel+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UILabel+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UITableView+LookinServer.h b/Pods/Headers/Private/LookinServer/UITableView+LookinServer.h new file mode 120000 index 00000000..eb499d69 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UITableView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITableView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UITextField+LookinServer.h b/Pods/Headers/Private/LookinServer/UITextField+LookinServer.h new file mode 120000 index 00000000..f6164408 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UITextField+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITextField+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UITextView+LookinServer.h b/Pods/Headers/Private/LookinServer/UITextView+LookinServer.h new file mode 120000 index 00000000..820df2b3 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UITextView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITextView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIView+LookinServer.h b/Pods/Headers/Private/LookinServer/UIView+LookinServer.h new file mode 120000 index 00000000..7dd72a26 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIViewController+LookinServer.h b/Pods/Headers/Private/LookinServer/UIViewController+LookinServer.h new file mode 120000 index 00000000..89ce70c6 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIViewController+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/LookinServer/UIVisualEffectView+LookinServer.h b/Pods/Headers/Private/LookinServer/UIVisualEffectView+LookinServer.h new file mode 120000 index 00000000..a2fd9817 --- /dev/null +++ b/Pods/Headers/Private/LookinServer/UIVisualEffectView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Private/SDWebImage/SDCallbackQueue.h b/Pods/Headers/Private/SDWebImage/SDCallbackQueue.h new file mode 120000 index 00000000..b49fa7a4 --- /dev/null +++ b/Pods/Headers/Private/SDWebImage/SDCallbackQueue.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/Core/SDCallbackQueue.h \ No newline at end of file diff --git a/Pods/Headers/Private/SDWebImage/SDImageFramePool.h b/Pods/Headers/Private/SDWebImage/SDImageFramePool.h new file mode 120000 index 00000000..67e3c5f6 --- /dev/null +++ b/Pods/Headers/Private/SDWebImage/SDImageFramePool.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/Private/SDImageFramePool.h \ No newline at end of file diff --git a/Pods/Headers/Private/SDWebImage/UIView+WebCacheState.h b/Pods/Headers/Private/SDWebImage/UIView+WebCacheState.h new file mode 120000 index 00000000..6d1d2f54 --- /dev/null +++ b/Pods/Headers/Private/SDWebImage/UIView+WebCacheState.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/Core/UIView+WebCacheState.h \ No newline at end of file diff --git a/Pods/Headers/Private/SDWebImageWebPCoder/SDInternalMacros.h b/Pods/Headers/Private/SDWebImageWebPCoder/SDInternalMacros.h new file mode 120000 index 00000000..4cdc55af --- /dev/null +++ b/Pods/Headers/Private/SDWebImageWebPCoder/SDInternalMacros.h @@ -0,0 +1 @@ +../../../SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h \ No newline at end of file diff --git a/Pods/Headers/Private/SDWebImageWebPCoder/SDmetamacros.h b/Pods/Headers/Private/SDWebImageWebPCoder/SDmetamacros.h new file mode 120000 index 00000000..6af61d94 --- /dev/null +++ b/Pods/Headers/Private/SDWebImageWebPCoder/SDmetamacros.h @@ -0,0 +1 @@ +../../../SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h \ No newline at end of file diff --git a/Pods/Headers/Private/libwebp/sharpyuv_cpu.h b/Pods/Headers/Private/libwebp/sharpyuv_cpu.h new file mode 120000 index 00000000..589caac4 --- /dev/null +++ b/Pods/Headers/Private/libwebp/sharpyuv_cpu.h @@ -0,0 +1 @@ +../../../libwebp/sharpyuv/sharpyuv_cpu.h \ No newline at end of file diff --git a/Pods/Headers/Public/CLCamera/CLCamera-umbrella.h b/Pods/Headers/Public/CLCamera/CLCamera-umbrella.h new file mode 120000 index 00000000..063272b7 --- /dev/null +++ b/Pods/Headers/Public/CLCamera/CLCamera-umbrella.h @@ -0,0 +1 @@ +../../../Target Support Files/CLCamera/CLCamera-umbrella.h \ No newline at end of file diff --git a/Pods/Headers/Public/CLCamera/CLCamera.modulemap b/Pods/Headers/Public/CLCamera/CLCamera.modulemap new file mode 120000 index 00000000..4722b28e --- /dev/null +++ b/Pods/Headers/Public/CLCamera/CLCamera.modulemap @@ -0,0 +1 @@ +../../../Target Support Files/CLCamera/CLCamera.modulemap \ No newline at end of file diff --git a/Pods/Headers/Public/CLPopoverManager/CLPopoverManager-umbrella.h b/Pods/Headers/Public/CLPopoverManager/CLPopoverManager-umbrella.h new file mode 120000 index 00000000..5b8560dc --- /dev/null +++ b/Pods/Headers/Public/CLPopoverManager/CLPopoverManager-umbrella.h @@ -0,0 +1 @@ +../../../Target Support Files/CLPopoverManager/CLPopoverManager-umbrella.h \ No newline at end of file diff --git a/Pods/Headers/Public/CLPopoverManager/CLPopoverManager.modulemap b/Pods/Headers/Public/CLPopoverManager/CLPopoverManager.modulemap new file mode 120000 index 00000000..4acce242 --- /dev/null +++ b/Pods/Headers/Public/CLPopoverManager/CLPopoverManager.modulemap @@ -0,0 +1 @@ +../../../Target Support Files/CLPopoverManager/CLPopoverManager.modulemap \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/CALayer+Lookin.h b/Pods/Headers/Public/LookinServer/CALayer+Lookin.h new file mode 120000 index 00000000..1fb4d3b5 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/CALayer+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/CALayer+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/CALayer+LookinServer.h b/Pods/Headers/Public/LookinServer/CALayer+LookinServer.h new file mode 120000 index 00000000..9e6c27f5 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/CALayer+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/CALayer+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Color+Lookin.h b/Pods/Headers/Public/LookinServer/Color+Lookin.h new file mode 120000 index 00000000..c43a4a03 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Color+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/Color+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Image+Lookin.h b/Pods/Headers/Public/LookinServer/Image+Lookin.h new file mode 120000 index 00000000..6adea58c --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Image+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/Image+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKSConfigManager.h b/Pods/Headers/Public/LookinServer/LKSConfigManager.h new file mode 120000 index 00000000..3897f082 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKSConfigManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKSConfigManager.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_AttrGroupsMaker.h b/Pods/Headers/Public/LookinServer/LKS_AttrGroupsMaker.h new file mode 120000 index 00000000..119c09e9 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_AttrGroupsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_AttrModificationPatchHandler.h b/Pods/Headers/Public/LookinServer/LKS_AttrModificationPatchHandler.h new file mode 120000 index 00000000..62267200 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_AttrModificationPatchHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_ConnectionManager.h b/Pods/Headers/Public/LookinServer/LKS_ConnectionManager.h new file mode 120000 index 00000000..1a09cbc8 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_ConnectionManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_CustomAttrGroupsMaker.h b/Pods/Headers/Public/LookinServer/LKS_CustomAttrGroupsMaker.h new file mode 120000 index 00000000..0945019e --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_CustomAttrGroupsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_CustomAttrModificationHandler.h b/Pods/Headers/Public/LookinServer/LKS_CustomAttrModificationHandler.h new file mode 120000 index 00000000..97c4ec96 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_CustomAttrModificationHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_CustomAttrSetterManager.h b/Pods/Headers/Public/LookinServer/LKS_CustomAttrSetterManager.h new file mode 120000 index 00000000..b962ddae --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_CustomAttrSetterManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_CustomDisplayItemsMaker.h b/Pods/Headers/Public/LookinServer/LKS_CustomDisplayItemsMaker.h new file mode 120000 index 00000000..d758ffa7 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_CustomDisplayItemsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_EventHandlerMaker.h b/Pods/Headers/Public/LookinServer/LKS_EventHandlerMaker.h new file mode 120000 index 00000000..21c02dbf --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_EventHandlerMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_ExportManager.h b/Pods/Headers/Public/LookinServer/LKS_ExportManager.h new file mode 120000 index 00000000..e558781c --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_ExportManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_ExportManager.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_GestureTargetActionsSearcher.h b/Pods/Headers/Public/LookinServer/LKS_GestureTargetActionsSearcher.h new file mode 120000 index 00000000..f1c91dd0 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_GestureTargetActionsSearcher.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_Helper.h b/Pods/Headers/Public/LookinServer/LKS_Helper.h new file mode 120000 index 00000000..048399e9 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_Helper.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_Helper.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_HierarchyDetailsHandler.h b/Pods/Headers/Public/LookinServer/LKS_HierarchyDetailsHandler.h new file mode 120000 index 00000000..e4f47cc5 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_HierarchyDetailsHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_HierarchyDisplayItemsMaker.h b/Pods/Headers/Public/LookinServer/LKS_HierarchyDisplayItemsMaker.h new file mode 120000 index 00000000..0d6eae17 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_HierarchyDisplayItemsMaker.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_InbuiltAttrModificationHandler.h b/Pods/Headers/Public/LookinServer/LKS_InbuiltAttrModificationHandler.h new file mode 120000 index 00000000..93e611c5 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_InbuiltAttrModificationHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_MultiplatformAdapter.h b/Pods/Headers/Public/LookinServer/LKS_MultiplatformAdapter.h new file mode 120000 index 00000000..528d9dec --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_MultiplatformAdapter.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_ObjectRegistry.h b/Pods/Headers/Public/LookinServer/LKS_ObjectRegistry.h new file mode 120000 index 00000000..c24f674e --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_ObjectRegistry.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_RequestHandler.h b/Pods/Headers/Public/LookinServer/LKS_RequestHandler.h new file mode 120000 index 00000000..b176ecdb --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_RequestHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LKS_TraceManager.h b/Pods/Headers/Public/LookinServer/LKS_TraceManager.h new file mode 120000 index 00000000..776c4d34 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LKS_TraceManager.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LKS_TraceManager.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAppInfo.h b/Pods/Headers/Public/LookinServer/LookinAppInfo.h new file mode 120000 index 00000000..e1804d9a --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAppInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAppInfo.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttrIdentifiers.h b/Pods/Headers/Public/LookinServer/LookinAttrIdentifiers.h new file mode 120000 index 00000000..91f0a8d8 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttrIdentifiers.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttrIdentifiers.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttrType.h b/Pods/Headers/Public/LookinServer/LookinAttrType.h new file mode 120000 index 00000000..1b32f48f --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttrType.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttrType.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttribute.h b/Pods/Headers/Public/LookinServer/LookinAttribute.h new file mode 120000 index 00000000..4aa2bd42 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttribute.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttribute.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttributeModification.h b/Pods/Headers/Public/LookinServer/LookinAttributeModification.h new file mode 120000 index 00000000..837d0e2f --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttributeModification.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributeModification.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttributesGroup.h b/Pods/Headers/Public/LookinServer/LookinAttributesGroup.h new file mode 120000 index 00000000..80dbc433 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttributesGroup.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributesGroup.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAttributesSection.h b/Pods/Headers/Public/LookinServer/LookinAttributesSection.h new file mode 120000 index 00000000..b315eef4 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAttributesSection.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAttributesSection.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinAutoLayoutConstraint.h b/Pods/Headers/Public/LookinServer/LookinAutoLayoutConstraint.h new file mode 120000 index 00000000..92375f87 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinAutoLayoutConstraint.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinCodingValueType.h b/Pods/Headers/Public/LookinServer/LookinCodingValueType.h new file mode 120000 index 00000000..0d9a1a72 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinCodingValueType.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCodingValueType.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinConnectionAttachment.h b/Pods/Headers/Public/LookinServer/LookinConnectionAttachment.h new file mode 120000 index 00000000..0dc19c20 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinConnectionAttachment.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinConnectionAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinConnectionResponseAttachment.h b/Pods/Headers/Public/LookinServer/LookinConnectionResponseAttachment.h new file mode 120000 index 00000000..58e8941c --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinConnectionResponseAttachment.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinCustomAttrModification.h b/Pods/Headers/Public/LookinServer/LookinCustomAttrModification.h new file mode 120000 index 00000000..60e8b02e --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinCustomAttrModification.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCustomAttrModification.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinCustomDisplayItemInfo.h b/Pods/Headers/Public/LookinServer/LookinCustomDisplayItemInfo.h new file mode 120000 index 00000000..0e9b289b --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinCustomDisplayItemInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinDashboardBlueprint.h b/Pods/Headers/Public/LookinServer/LookinDashboardBlueprint.h new file mode 120000 index 00000000..6d626836 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinDashboardBlueprint.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDashboardBlueprint.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinDefines.h b/Pods/Headers/Public/LookinServer/LookinDefines.h new file mode 120000 index 00000000..e1ca4d2a --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinDefines.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDefines.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinDisplayItem.h b/Pods/Headers/Public/LookinServer/LookinDisplayItem.h new file mode 120000 index 00000000..1f17d761 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinDisplayItem.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDisplayItem.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinDisplayItemDetail.h b/Pods/Headers/Public/LookinServer/LookinDisplayItemDetail.h new file mode 120000 index 00000000..4710c9cb --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinDisplayItemDetail.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinDisplayItemDetail.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinEventHandler.h b/Pods/Headers/Public/LookinServer/LookinEventHandler.h new file mode 120000 index 00000000..89539242 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinEventHandler.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinEventHandler.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinHierarchyFile.h b/Pods/Headers/Public/LookinServer/LookinHierarchyFile.h new file mode 120000 index 00000000..94a58b83 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinHierarchyFile.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinHierarchyFile.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinHierarchyInfo.h b/Pods/Headers/Public/LookinServer/LookinHierarchyInfo.h new file mode 120000 index 00000000..9511ff68 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinHierarchyInfo.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinHierarchyInfo.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinIvarTrace.h b/Pods/Headers/Public/LookinServer/LookinIvarTrace.h new file mode 120000 index 00000000..9049ab07 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinIvarTrace.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Base/LookinIvarTrace.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinObject.h b/Pods/Headers/Public/LookinServer/LookinObject.h new file mode 120000 index 00000000..cf8241af --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinObject.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinObject.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinServer-umbrella.h b/Pods/Headers/Public/LookinServer/LookinServer-umbrella.h new file mode 120000 index 00000000..c37ae361 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinServer-umbrella.h @@ -0,0 +1 @@ +../../../Target Support Files/LookinServer/LookinServer-umbrella.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinServer.h b/Pods/Headers/Public/LookinServer/LookinServer.h new file mode 120000 index 00000000..e9db4c37 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinServer.modulemap b/Pods/Headers/Public/LookinServer/LookinServer.modulemap new file mode 120000 index 00000000..0e3c0cd0 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinServer.modulemap @@ -0,0 +1 @@ +../../../Target Support Files/LookinServer/LookinServer.modulemap \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinServerDefines.h b/Pods/Headers/Public/LookinServer/LookinServerDefines.h new file mode 120000 index 00000000..dbfa8133 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinServerDefines.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Others/LookinServerDefines.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinStaticAsyncUpdateTask.h b/Pods/Headers/Public/LookinServer/LookinStaticAsyncUpdateTask.h new file mode 120000 index 00000000..4e93a9cd --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinStaticAsyncUpdateTask.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinTuple.h b/Pods/Headers/Public/LookinServer/LookinTuple.h new file mode 120000 index 00000000..c0d394bf --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinTuple.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinTuple.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/LookinWeakContainer.h b/Pods/Headers/Public/LookinServer/LookinWeakContainer.h new file mode 120000 index 00000000..ddd4ef30 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/LookinWeakContainer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/LookinWeakContainer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Lookin_PTChannel.h b/Pods/Headers/Public/LookinServer/Lookin_PTChannel.h new file mode 120000 index 00000000..ba83c7a8 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Lookin_PTChannel.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Lookin_PTPrivate.h b/Pods/Headers/Public/LookinServer/Lookin_PTPrivate.h new file mode 120000 index 00000000..180b02d0 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Lookin_PTPrivate.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTPrivate.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Lookin_PTProtocol.h b/Pods/Headers/Public/LookinServer/Lookin_PTProtocol.h new file mode 120000 index 00000000..104f6f4e --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Lookin_PTProtocol.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Lookin_PTUSBHub.h b/Pods/Headers/Public/LookinServer/Lookin_PTUSBHub.h new file mode 120000 index 00000000..46b7ae05 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Lookin_PTUSBHub.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/NSArray+Lookin.h b/Pods/Headers/Public/LookinServer/NSArray+Lookin.h new file mode 120000 index 00000000..43fe2ddf --- /dev/null +++ b/Pods/Headers/Public/LookinServer/NSArray+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSArray+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/NSObject+Lookin.h b/Pods/Headers/Public/LookinServer/NSObject+Lookin.h new file mode 120000 index 00000000..3d1227ec --- /dev/null +++ b/Pods/Headers/Public/LookinServer/NSObject+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSObject+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/NSObject+LookinServer.h b/Pods/Headers/Public/LookinServer/NSObject+LookinServer.h new file mode 120000 index 00000000..9ffa84d9 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/NSObject+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/NSObject+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/NSSet+Lookin.h b/Pods/Headers/Public/LookinServer/NSSet+Lookin.h new file mode 120000 index 00000000..172bd142 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/NSSet+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSSet+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/NSString+Lookin.h b/Pods/Headers/Public/LookinServer/NSString+Lookin.h new file mode 120000 index 00000000..5fc3c763 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/NSString+Lookin.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Category/NSString+Lookin.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/Peertalk.h b/Pods/Headers/Public/LookinServer/Peertalk.h new file mode 120000 index 00000000..4c14ff46 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/Peertalk.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Shared/Peertalk/Peertalk.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIBlurEffect+LookinServer.h b/Pods/Headers/Public/LookinServer/UIBlurEffect+LookinServer.h new file mode 120000 index 00000000..9abcb3c2 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIBlurEffect+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIColor+LookinServer.h b/Pods/Headers/Public/LookinServer/UIColor+LookinServer.h new file mode 120000 index 00000000..14d7befe --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIColor+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIColor+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIImage+LookinServer.h b/Pods/Headers/Public/LookinServer/UIImage+LookinServer.h new file mode 120000 index 00000000..96b81aa4 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIImage+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIImage+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIImageView+LookinServer.h b/Pods/Headers/Public/LookinServer/UIImageView+LookinServer.h new file mode 120000 index 00000000..5731be2b --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIImageView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UILabel+LookinServer.h b/Pods/Headers/Public/LookinServer/UILabel+LookinServer.h new file mode 120000 index 00000000..09c42193 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UILabel+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UILabel+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UITableView+LookinServer.h b/Pods/Headers/Public/LookinServer/UITableView+LookinServer.h new file mode 120000 index 00000000..eb499d69 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UITableView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITableView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UITextField+LookinServer.h b/Pods/Headers/Public/LookinServer/UITextField+LookinServer.h new file mode 120000 index 00000000..f6164408 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UITextField+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITextField+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UITextView+LookinServer.h b/Pods/Headers/Public/LookinServer/UITextView+LookinServer.h new file mode 120000 index 00000000..820df2b3 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UITextView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UITextView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIView+LookinServer.h b/Pods/Headers/Public/LookinServer/UIView+LookinServer.h new file mode 120000 index 00000000..7dd72a26 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIViewController+LookinServer.h b/Pods/Headers/Public/LookinServer/UIViewController+LookinServer.h new file mode 120000 index 00000000..89ce70c6 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIViewController+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/LookinServer/UIVisualEffectView+LookinServer.h b/Pods/Headers/Public/LookinServer/UIVisualEffectView+LookinServer.h new file mode 120000 index 00000000..a2fd9817 --- /dev/null +++ b/Pods/Headers/Public/LookinServer/UIVisualEffectView+LookinServer.h @@ -0,0 +1 @@ +../../../LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.h \ No newline at end of file diff --git a/Pods/Headers/Public/SDWebImage/SDCallbackQueue.h b/Pods/Headers/Public/SDWebImage/SDCallbackQueue.h new file mode 120000 index 00000000..b49fa7a4 --- /dev/null +++ b/Pods/Headers/Public/SDWebImage/SDCallbackQueue.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/Core/SDCallbackQueue.h \ No newline at end of file diff --git a/Pods/Headers/Public/SDWebImage/UIView+WebCacheState.h b/Pods/Headers/Public/SDWebImage/UIView+WebCacheState.h new file mode 120000 index 00000000..6d1d2f54 --- /dev/null +++ b/Pods/Headers/Public/SDWebImage/UIView+WebCacheState.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/Core/UIView+WebCacheState.h \ No newline at end of file diff --git a/Pods/Headers/Public/libwebp/sharpyuv.h b/Pods/Headers/Public/libwebp/sharpyuv.h new file mode 120000 index 00000000..1bb7ae46 --- /dev/null +++ b/Pods/Headers/Public/libwebp/sharpyuv.h @@ -0,0 +1 @@ +../../../libwebp/sharpyuv/sharpyuv.h \ No newline at end of file diff --git a/Pods/Kingfisher/Sources/General/ImageSource/PHPickerResultImageDataProvider.swift b/Pods/Kingfisher/Sources/General/ImageSource/PHPickerResultImageDataProvider.swift new file mode 100644 index 00000000..c743a10a --- /dev/null +++ b/Pods/Kingfisher/Sources/General/ImageSource/PHPickerResultImageDataProvider.swift @@ -0,0 +1,84 @@ +// +// PHPickerResultImageDataProvider.swift +// Kingfisher +// +// Created by nuomi1 on 2024-04-17. +// +// Copyright (c) 2024 Wei Wang +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +#if os(iOS) || os(macOS) || os(visionOS) + +import PhotosUI + +/// A data provider to provide image data from a given `PHPickerResult`. +@available(iOS 14.0, macOS 13.0, *) +public struct PHPickerResultImageDataProvider: ImageDataProvider { + + /// The possible error might be caused by the `PHPickerResultImageDataProvider`. + /// - invalidImage: The retrieved image is invalid. + public enum PHPickerResultImageDataProviderError: Error { + /// The retrieved image is invalid. + case invalidImage + } + + /// The picker result bound to `self`. + public let pickerResult: PHPickerResult + + /// The content type of the image. + public let contentType: UTType + + private var internalKey: String { + pickerResult.assetIdentifier ?? UUID().uuidString + } + + public var cacheKey: String { + "\(internalKey)_\(contentType.identifier)" + } + + /// Creates an image data provider from a given `PHPickerResult`. + /// - Parameters: + /// - pickerResult: The picker result to provide image data. + /// - contentType: The content type of the image. Default is `UTType.image`. + public init(pickerResult: PHPickerResult, contentType: UTType = UTType.image) { + self.pickerResult = pickerResult + self.contentType = contentType + } + + public func data(handler: @escaping (Result) -> Void) { + pickerResult.itemProvider.loadDataRepresentation(forTypeIdentifier: contentType.identifier) { data, error in + if let error { + handler(.failure(error)) + return + } + + guard let data else { + handler(.failure(PHPickerResultImageDataProviderError.invalidImage)) + return + } + + handler(.success(data)) + } + } +} + +#endif diff --git a/Pods/Kingfisher/Sources/PrivacyInfo.xcprivacy b/Pods/Kingfisher/Sources/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..993e1f60 --- /dev/null +++ b/Pods/Kingfisher/Sources/PrivacyInfo.xcprivacy @@ -0,0 +1,25 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + + diff --git a/Pods/Kingfisher/Sources/Utility/DisplayLink.swift b/Pods/Kingfisher/Sources/Utility/DisplayLink.swift new file mode 100644 index 00000000..801b342c --- /dev/null +++ b/Pods/Kingfisher/Sources/Utility/DisplayLink.swift @@ -0,0 +1,163 @@ +// +// DisplayLink.swift +// Kingfisher +// +// Created by yeatse on 2024/1/9. +// +// Copyright (c) 2024 Wei Wang +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !os(watchOS) +#if canImport(UIKit) +import UIKit +#else +import AppKit +import CoreVideo +#endif + +protocol DisplayLinkCompatible: AnyObject { + var isPaused: Bool { get set } + + var preferredFramesPerSecond: NSInteger { get } + var timestamp: CFTimeInterval { get } + var duration: CFTimeInterval { get } + + func add(to runLoop: RunLoop, forMode mode: RunLoop.Mode) + func remove(from runLoop: RunLoop, forMode mode: RunLoop.Mode) + + func invalidate() +} + +#if !os(macOS) +extension UIView { + func compatibleDisplayLink(target: Any, selector: Selector) -> DisplayLinkCompatible { + return CADisplayLink(target: target, selector: selector) + } +} + +extension CADisplayLink: DisplayLinkCompatible {} + +#else +extension NSView { + func compatibleDisplayLink(target: Any, selector: Selector) -> DisplayLinkCompatible { +#if swift(>=5.9) // macOS 14 SDK is included in Xcode 15, which comes with swift 5.9. Add this check to make old compilers happy. + if #available(macOS 14.0, *) { + return displayLink(target: target, selector: selector) + } else { + return DisplayLink(target: target, selector: selector) + } +#else + return DisplayLink(target: target, selector: selector) +#endif + } +} + +#if swift(>=5.9) +@available(macOS 14.0, *) +extension CADisplayLink: DisplayLinkCompatible { + var preferredFramesPerSecond: NSInteger { return 0 } +} +#endif + +class DisplayLink: DisplayLinkCompatible { + private var link: CVDisplayLink? + private var target: Any? + private var selector: Selector? + + private var schedulers: [RunLoop: [RunLoop.Mode]] = [:] + + init(target: Any, selector: Selector) { + self.target = target + self.selector = selector + CVDisplayLinkCreateWithActiveCGDisplays(&link) + if let link = link { + CVDisplayLinkSetOutputHandler(link, displayLinkCallback(_:inNow:inOutputTime:flagsIn:flagsOut:)) + } + } + + deinit { + self.invalidate() + } + + private func displayLinkCallback(_ link: CVDisplayLink, + inNow: UnsafePointer, + inOutputTime: UnsafePointer, + flagsIn: CVOptionFlags, + flagsOut: UnsafeMutablePointer) -> CVReturn + { + let outputTime = inOutputTime.pointee + DispatchQueue.main.async { + guard let selector = self.selector, let target = self.target else { return } + if outputTime.videoTimeScale != 0 { + self.duration = CFTimeInterval(Double(outputTime.videoRefreshPeriod) / Double(outputTime.videoTimeScale)) + } + if self.timestamp != 0 { + for scheduler in self.schedulers { + scheduler.key.perform(selector, target: target, argument: nil, order: 0, modes: scheduler.value) + } + } + self.timestamp = CFTimeInterval(Double(outputTime.hostTime) / 1_000_000_000) + } + return kCVReturnSuccess + } + + var isPaused: Bool = true { + didSet { + guard let link = link else { return } + if isPaused { + if CVDisplayLinkIsRunning(link) { + CVDisplayLinkStop(link) + } + } else { + if !CVDisplayLinkIsRunning(link) { + CVDisplayLinkStart(link) + } + } + } + } + + var preferredFramesPerSecond: NSInteger = 0 + var timestamp: CFTimeInterval = 0 + var duration: CFTimeInterval = 0 + + func add(to runLoop: RunLoop, forMode mode: RunLoop.Mode) { + assert(runLoop == .main) + schedulers[runLoop, default: []].append(mode) + } + + func remove(from runLoop: RunLoop, forMode mode: RunLoop.Mode) { + schedulers[runLoop]?.removeAll { $0 == mode } + if let modes = schedulers[runLoop], modes.isEmpty { + schedulers.removeValue(forKey: runLoop) + } + } + + func invalidate() { + schedulers = [:] + isPaused = true + target = nil + selector = nil + if let link = link { + CVDisplayLinkSetOutputHandler(link) { _, _, _, _, _ in kCVReturnSuccess } + } + } +} +#endif +#endif diff --git a/Pods/Local Podspecs/CLCamera.podspec.json b/Pods/Local Podspecs/CLCamera.podspec.json new file mode 100644 index 00000000..228dfb10 --- /dev/null +++ b/Pods/Local Podspecs/CLCamera.podspec.json @@ -0,0 +1,36 @@ +{ + "name": "CLCamera", + "version": "1.0.2", + "summary": "Swift版自定义相机", + "description": "CLCarmera是自定义相机的封装.", + "homepage": "https://github.com/JmoVxia/CLCamera", + "license": { + "type": "MIT", + "file": "LICENSE" + }, + "authors": { + "JmoVxia": "JmoVxia@gmail.com" + }, + "social_media_url": "https://github.com/JmoVxia", + "swift_versions": [ + "5.0" + ], + "platforms": { + "ios": "12.0" + }, + "source": { + "git": "https://github.com/JmoVxia/CLCamera.git", + "tag": "1.0.2" + }, + "source_files": [ + "Camera/**/*.swift" + ], + "resources": "Camera/Resource/CLCamera.bundle", + "requires_arc": true, + "dependencies": { + "SnapKit": [ + + ] + }, + "swift_version": "5.0" +} diff --git a/Pods/Local Podspecs/CLPopoverManager.podspec.json b/Pods/Local Podspecs/CLPopoverManager.podspec.json new file mode 100644 index 00000000..666e2d0e --- /dev/null +++ b/Pods/Local Podspecs/CLPopoverManager.podspec.json @@ -0,0 +1,28 @@ +{ + "name": "CLPopoverManager", + "version": "0.0.1", + "summary": "CLPopoverManager", + "homepage": "https://github.com/JmoVxia/CLPopoverManager", + "license": { + "type": "MIT", + "file": "LICENSE" + }, + "authors": { + "JmoVxia": "JmoVxia@gmail.com" + }, + "platforms": { + "ios": "11.0" + }, + "source": { + "git": "https://github.com/JmoVxia/CLPopoverManager", + "tag": "0.0.1" + }, + "source_files": [ + "CLPopoverManager/**/*" + ], + "swift_versions": [ + "5.0" + ], + "requires_arc": true, + "swift_version": "5.0" +} diff --git a/Pods/LookinServer/LICENSE b/Pods/LookinServer/LICENSE new file mode 100644 index 00000000..eeb2b2b0 --- /dev/null +++ b/Pods/LookinServer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2023] [LI KAI] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Pods/LookinServer/README.md b/Pods/LookinServer/README.md new file mode 100644 index 00000000..548ceff5 --- /dev/null +++ b/Pods/LookinServer/README.md @@ -0,0 +1,73 @@ +![Preview](https://cdn.lookin.work/public/style/images/independent/homepage/preview_en_1x.jpg "Preview") + +# Introduction +You can inspect and modify views in iOS app via Lookin, just like UI Inspector in Xcode, or another app called Reveal. + +Official Website:https://lookin.work/ + +# Integration Guide +To use Lookin macOS app, you need to integrate LookinServer (iOS Framework of Lookin) into your iOS project. + +> **Warning** +> 1. Never integrate LookinServer in Release building configuration. +> 2. Do not use versions earlier than 1.0.6, as it contains a critical bug that could lead to online incidents in your project: https://qxh1ndiez2w.feishu.cn/wiki/Z9SpwT7zWiqvYvkBe7Lc6Disnab + +## via CocoaPods: +### Swift Project +`pod 'LookinServer', :subspecs => ['Swift'], :configurations => ['Debug']` +### Objective-C Project +`pod 'LookinServer', :configurations => ['Debug']` +## via Swift Package Manager: +`https://github.com/QMUI/LookinServer/` + +# Repository +LookinServer: https://github.com/QMUI/LookinServer + +macOS app: https://github.com/hughkli/Lookin/ + +# Tips +- How to display custom information in Lookin: https://bytedance.larkoffice.com/docx/TRridRXeUoErMTxs94bcnGchnlb +- How to display more member variables in Lookin: https://bytedance.larkoffice.com/docx/CKRndHqdeoub11xSqUZcMlFhnWe +- How to turn on Swift optimization for Lookin: https://bytedance.larkoffice.com/docx/GFRLdzpeKoakeyxvwgCcZ5XdnTb +- Documentation Collection: https://bytedance.larkoffice.com/docx/Yvv1d57XQoe5l0xZ0ZRc0ILfnWb + +# Acknowledgements +https://qxh1ndiez2w.feishu.cn/docx/YIFjdE4gIolp3hxn1tGckiBxnWf + +--- +# 简介 +Lookin 可以查看与修改 iOS App 里的 UI 对象,类似于 Xcode 自带的 UI Inspector 工具,或另一款叫做 Reveal 的软件。 + +官网:https://lookin.work/ + +# 安装 LookinServer Framework +如果这是你的 iOS 项目第一次使用 Lookin,则需要先把 LookinServer 这款 iOS Framework 集成到你的 iOS 项目中。 + +> **Warning** +> +> 1. 不要在 AppStore 模式下集成 LookinServer。 +> 2. 不要使用早于 1.0.6 的版本,因为它包含一个严重 Bug,可能导致线上事故: https://qxh1ndiez2w.feishu.cn/wiki/Z9SpwT7zWiqvYvkBe7Lc6Disnab +## 通过 CocoaPods: + +### Swift 项目 +`pod 'LookinServer', :subspecs => ['Swift'], :configurations => ['Debug']` +### Objective-C 项目 +`pod 'LookinServer', :configurations => ['Debug']` + +## 通过 Swift Package Manager: +`https://github.com/QMUI/LookinServer/` + +# 源代码仓库 + +iOS 端 LookinServer:https://github.com/QMUI/LookinServer + +macOS 端软件:https://github.com/hughkli/Lookin/ + +# 技巧 +- 如何在 Lookin 中展示自定义信息: https://bytedance.larkoffice.com/docx/TRridRXeUoErMTxs94bcnGchnlb +- 如何在 Lookin 中展示更多成员变量: https://bytedance.larkoffice.com/docx/CKRndHqdeoub11xSqUZcMlFhnWe +- 如何为 Lookin 开启 Swift 优化: https://bytedance.larkoffice.com/docx/GFRLdzpeKoakeyxvwgCcZ5XdnTb +- 文档汇总:https://bytedance.larkoffice.com/docx/Yvv1d57XQoe5l0xZ0ZRc0ILfnWb + +# 鸣谢 +https://qxh1ndiez2w.feishu.cn/docx/YIFjdE4gIolp3hxn1tGckiBxnWf diff --git a/Pods/LookinServer/Src/Base/LookinIvarTrace.h b/Pods/LookinServer/Src/Base/LookinIvarTrace.h new file mode 100644 index 00000000..39043850 --- /dev/null +++ b/Pods/LookinServer/Src/Base/LookinIvarTrace.h @@ -0,0 +1,40 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinIvarTrace.h +// Lookin +// +// Created by Li Kai on 2019/4/30. +// https://lookin.work +// + +#import + +extern NSString *const LookinIvarTraceRelationValue_Self; + +/// 如果 hostClassName 和 ivarName 均 equal,则认为两个 LookinIvarTrace 对象彼此 equal +/// 比如 A 是 B 的 superview,且 A 的 "_stageView" 指向 B,则 B 会有一个 LookinIvarTrace:hostType 为 “superview”,hostClassName 为 A 的 class,ivarName 为 “_stageView” +@interface LookinIvarTrace : NSObject + +/// 该值可能是 "superview"、"superlayer"、“self” 或 nil +@property(nonatomic, copy) NSString *relation; + +@property(nonatomic, copy) NSString *hostClassName; + +@property(nonatomic, copy) NSString *ivarName; + +#pragma mark - No Coding + +#if TARGET_OS_IPHONE +@property(nonatomic, weak) id hostObject; +#endif + +@end + +@interface NSObject (LookinServerTrace) + +@property(nonatomic, copy) NSArray *lks_ivarTraces; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Base/LookinIvarTrace.m b/Pods/LookinServer/Src/Base/LookinIvarTrace.m new file mode 100644 index 00000000..e272d474 --- /dev/null +++ b/Pods/LookinServer/Src/Base/LookinIvarTrace.m @@ -0,0 +1,70 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinIvarTrace.m +// Lookin +// +// Created by Li Kai on 2019/4/30. +// https://lookin.work +// + +#import "LookinIvarTrace.h" + +NSString *const LookinIvarTraceRelationValue_Self = @"self"; + +@implementation LookinIvarTrace + +#pragma mark - Equal + +- (NSUInteger)hash { + return self.hostClassName.hash ^ self.ivarName.hash; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinIvarTrace class]]) { + return NO; + } + LookinIvarTrace *comparedObj = object; + if ([self.hostClassName isEqualToString:comparedObj.hostClassName] && [self.ivarName isEqualToString:comparedObj.ivarName]) { + return YES; + } + return NO; +} + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinIvarTrace *newTrace = [[LookinIvarTrace allocWithZone:zone] init]; + newTrace.relation = self.relation; + newTrace.hostClassName = self.hostClassName; + newTrace.ivarName = self.ivarName; + return newTrace; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.relation forKey:@"relation"]; + [aCoder encodeObject:self.hostClassName forKey:@"hostClassName"]; + [aCoder encodeObject:self.ivarName forKey:@"ivarName"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.relation = [aDecoder decodeObjectForKey:@"relation"]; + self.hostClassName = [aDecoder decodeObjectForKey:@"hostClassName"]; + self.ivarName = [aDecoder decodeObjectForKey:@"ivarName"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.h new file mode 100644 index 00000000..83584a9a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.h @@ -0,0 +1,41 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIView+LookinMobile.h +// WeRead +// +// Created by Li Kai on 2018/11/30. +// Copyright © 2018 tencent. All rights reserved. +// + +#import "LookinDefines.h" +#import "TargetConditionals.h" +#import + +@interface CALayer (LookinServer) + +/// 如果 myView.layer == myLayer,则 myLayer.lks_hostView 会返回 myView +@property(nonatomic, readonly, weak) UIView *lks_hostView; + +- (UIWindow *)lks_window; + +- (CGRect)lks_frameInWindow:(UIWindow *)window; + +- (UIImage *)lks_groupScreenshotWithLowQuality:(BOOL)lowQuality; +/// 当没有 sublayers 时,该方法返回 nil +- (UIImage *)lks_soloScreenshotWithLowQuality:(BOOL)lowQuality; + +/// 获取和该对象有关的对象的 Class 层级树 +- (NSArray *> *)lks_relatedClassChainList; + +- (NSArray *)lks_selfRelation; + +@property(nonatomic, strong) UIColor *lks_backgroundColor; +@property(nonatomic, strong) UIColor *lks_borderColor; +@property(nonatomic, strong) UIColor *lks_shadowColor; +@property(nonatomic, assign) CGFloat lks_shadowOffsetWidth; +@property(nonatomic, assign) CGFloat lks_shadowOffsetHeight; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.m new file mode 100644 index 00000000..233734df --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/CALayer+LookinServer.m @@ -0,0 +1,233 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIView+LookinMobile.m +// WeRead +// +// Created by Li Kai on 2018/11/30. +// Copyright © 2018 tencent. All rights reserved. +// + +#import "CALayer+LookinServer.h" +#import "LKS_HierarchyDisplayItemsMaker.h" +#import "LookinDisplayItem.h" +#import +#import "LKS_ConnectionManager.h" +#import "LookinIvarTrace.h" +#import "LookinServerDefines.h" +#import "UIColor+LookinServer.h" +#import "LKS_MultiplatformAdapter.h" + +@implementation CALayer (LookinServer) + +- (UIWindow *)lks_window { + CALayer *layer = self; + while (layer) { + UIView *hostView = layer.lks_hostView; + if (hostView.window) { + return hostView.window; + } else if ([hostView isKindOfClass:[UIWindow class]]) { + return (UIWindow *)hostView; + } + layer = layer.superlayer; + } + return nil; +} + +- (CGRect)lks_frameInWindow:(UIWindow *)window { + UIWindow *selfWindow = [self lks_window]; + if (!selfWindow) { + return CGRectZero; + } + + CGRect rectInSelfWindow = [selfWindow.layer convertRect:self.frame fromLayer:self.superlayer]; + CGRect rectInWindow = [window convertRect:rectInSelfWindow fromWindow:selfWindow]; + return rectInWindow; +} + +#pragma mark - Host View + +- (UIView *)lks_hostView { + if (self.delegate && [self.delegate isKindOfClass:UIView.class]) { + UIView *view = (UIView *)self.delegate; + if (view.layer == self) { + return view; + } + } + return nil; +} + +#pragma mark - Screenshot + +- (UIImage *)lks_groupScreenshotWithLowQuality:(BOOL)lowQuality { + + CGFloat screenScale = [LKS_MultiplatformAdapter mainScreenScale]; + CGFloat pixelWidth = self.frame.size.width * screenScale; + CGFloat pixelHeight = self.frame.size.height * screenScale; + if (pixelWidth <= 0 || pixelHeight <= 0) { + return nil; + } + + CGFloat renderScale = lowQuality ? 1 : 0; + CGFloat maxLength = MAX(pixelWidth, pixelHeight); + if (maxLength > LookinNodeImageMaxLengthInPx) { + // 确保最终绘制出的图片长和宽都不能超过 LookinNodeImageMaxLengthInPx + // 如果算出的 renderScale 大于 1 则取 1,因为似乎用 1 渲染的速度要比一个别的奇怪的带小数点的数字要更快 + renderScale = MIN(screenScale * LookinNodeImageMaxLengthInPx / maxLength, 1); + } + + CGSize contextSize = self.frame.size; + if (contextSize.width <= 0 || contextSize.height <= 0 || contextSize.width > 20000 || contextSize.height > 20000) { + NSLog(@"LookinServer - Failed to capture screenshot. Invalid context size: %@ x %@", @(contextSize.width), @(contextSize.height)); + return nil; + } + UIGraphicsBeginImageContextWithOptions(contextSize, NO, renderScale); + CGContextRef context = UIGraphicsGetCurrentContext(); + if (self.lks_hostView && !self.lks_hostView.lks_isChildrenViewOfTabBar) { + [self.lks_hostView drawViewHierarchyInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) afterScreenUpdates:YES]; + } else { + [self renderInContext:context]; + } + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; +} + +- (UIImage *)lks_soloScreenshotWithLowQuality:(BOOL)lowQuality { + if (!self.sublayers.count) { + return nil; + } + + CGFloat screenScale = [LKS_MultiplatformAdapter mainScreenScale]; + CGFloat pixelWidth = self.frame.size.width * screenScale; + CGFloat pixelHeight = self.frame.size.height * screenScale; + if (pixelWidth <= 0 || pixelHeight <= 0) { + return nil; + } + + CGFloat renderScale = lowQuality ? 1 : 0; + CGFloat maxLength = MAX(pixelWidth, pixelHeight); + if (maxLength > LookinNodeImageMaxLengthInPx) { + // 确保最终绘制出的图片长和宽都不能超过 LookinNodeImageMaxLengthInPx + // 如果算出的 renderScale 大于 1 则取 1,因为似乎用 1 渲染的速度要比一个别的奇怪的带小数点的数字要更快 + renderScale = MIN(screenScale * LookinNodeImageMaxLengthInPx / maxLength, 1); + } + + if (self.sublayers.count) { + NSArray *sublayers = [self.sublayers copy]; + NSMutableArray *visibleSublayers = [NSMutableArray arrayWithCapacity:sublayers.count]; + [sublayers enumerateObjectsUsingBlock:^(__kindof CALayer * _Nonnull sublayer, NSUInteger idx, BOOL * _Nonnull stop) { + if (!sublayer.hidden) { + sublayer.hidden = YES; + [visibleSublayers addObject:sublayer]; + } + }]; + + CGSize contextSize = self.frame.size; + if (contextSize.width <= 0 || contextSize.height <= 0 || contextSize.width > 20000 || contextSize.height > 20000) { + NSLog(@"LookinServer - Failed to capture screenshot. Invalid context size: %@ x %@", @(contextSize.width), @(contextSize.height)); + return nil; + } + + UIGraphicsBeginImageContextWithOptions(contextSize, NO, renderScale); + CGContextRef context = UIGraphicsGetCurrentContext(); + if (self.lks_hostView && !self.lks_hostView.lks_isChildrenViewOfTabBar) { + [self.lks_hostView drawViewHierarchyInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) afterScreenUpdates:YES]; + } else { + [self renderInContext:context]; + } + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + [visibleSublayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull sublayer, NSUInteger idx, BOOL * _Nonnull stop) { + sublayer.hidden = NO; + }]; + + return image; + } + return nil; +} + +- (NSArray *> *)lks_relatedClassChainList { + NSMutableArray *array = [NSMutableArray arrayWithCapacity:2]; + if (self.lks_hostView) { + [array addObject:[CALayer lks_getClassListOfObject:self.lks_hostView endingClass:@"UIView"]]; + UIViewController* vc = [self.lks_hostView lks_findHostViewController]; + if (vc) { + [array addObject:[CALayer lks_getClassListOfObject:vc endingClass:@"UIViewController"]]; + } + } else { + [array addObject:[CALayer lks_getClassListOfObject:self endingClass:@"CALayer"]]; + } + return array.copy; +} + ++ (NSArray *)lks_getClassListOfObject:(id)object endingClass:(NSString *)endingClass { + NSArray *completedList = [object lks_classChainList]; + NSUInteger endingIdx = [completedList indexOfObject:endingClass]; + if (endingIdx != NSNotFound) { + completedList = [completedList subarrayWithRange:NSMakeRange(0, endingIdx + 1)]; + } + return completedList; +} + +- (NSArray *)lks_selfRelation { + NSMutableArray *array = [NSMutableArray array]; + NSMutableArray *ivarTraces = [NSMutableArray array]; + if (self.lks_hostView) { + UIViewController* vc = [self.lks_hostView lks_findHostViewController]; + if (vc) { + [array addObject:[NSString stringWithFormat:@"(%@ *).view", NSStringFromClass(vc.class)]]; + + [ivarTraces addObjectsFromArray:vc.lks_ivarTraces]; + } + [ivarTraces addObjectsFromArray:self.lks_hostView.lks_ivarTraces]; + } else { + [ivarTraces addObjectsFromArray:self.lks_ivarTraces]; + } + if (ivarTraces.count) { + [array addObjectsFromArray:[ivarTraces lookin_map:^id(NSUInteger idx, LookinIvarTrace *value) { + return [NSString stringWithFormat:@"(%@ *) -> %@", value.hostClassName, value.ivarName]; + }]]; + } + return array.count ? array.copy : nil; +} + +- (UIColor *)lks_backgroundColor { + return [UIColor lks_colorWithCGColor:self.backgroundColor]; +} +- (void)setLks_backgroundColor:(UIColor *)lks_backgroundColor { + self.backgroundColor = lks_backgroundColor.CGColor; +} + +- (UIColor *)lks_borderColor { + return [UIColor lks_colorWithCGColor:self.borderColor]; +} +- (void)setLks_borderColor:(UIColor *)lks_borderColor { + self.borderColor = lks_borderColor.CGColor; +} + +- (UIColor *)lks_shadowColor { + return [UIColor lks_colorWithCGColor:self.shadowColor]; +} +- (void)setLks_shadowColor:(UIColor *)lks_shadowColor { + self.shadowColor = lks_shadowColor.CGColor; +} + +- (CGFloat)lks_shadowOffsetWidth { + return self.shadowOffset.width; +} +- (void)setLks_shadowOffsetWidth:(CGFloat)lks_shadowOffsetWidth { + self.shadowOffset = CGSizeMake(lks_shadowOffsetWidth, self.shadowOffset.height); +} + +- (CGFloat)lks_shadowOffsetHeight { + return self.shadowOffset.height; +} +- (void)setLks_shadowOffsetHeight:(CGFloat)lks_shadowOffsetHeight { + self.shadowOffset = CGSizeMake(self.shadowOffset.width, lks_shadowOffsetHeight); +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.h new file mode 100644 index 00000000..94d40f53 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.h @@ -0,0 +1,41 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSObject+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/4/21. +// https://lookin.work +// + +#import "LookinDefines.h" +#import + +@class LookinIvarTrace; + +@interface NSObject (LookinServer) + +#pragma mark - oid + +/// 如果 oid 不存在则会创建新的 oid +- (unsigned long)lks_registerOid; + +/// 0 表示不存在 +@property(nonatomic, assign) unsigned long lks_oid; + ++ (NSObject *)lks_objectWithOid:(unsigned long)oid; + +#pragma mark - trace + +@property(nonatomic, copy) NSString *lks_specialTrace; + ++ (void)lks_clearAllObjectsTraces; + +/** + 获取当前对象的 Class 层级树,如 @[@"UIView", @"UIResponder", @"NSObject"]。未 demangle,有 Swift Module Name + */ +- (NSArray *)lks_classChainList; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.m new file mode 100644 index 00000000..c8e170b4 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/NSObject+LookinServer.m @@ -0,0 +1,99 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSObject+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/4/21. +// https://lookin.work +// + +#import "NSObject+Lookin.h" +#import "NSObject+LookinServer.h" +#import "LookinServerDefines.h" +#import "LKS_ObjectRegistry.h" +#import + +@implementation NSObject (LookinServer) + +#pragma mark - oid + +- (unsigned long)lks_registerOid { + if (!self.lks_oid) { + unsigned long oid = [[LKS_ObjectRegistry sharedInstance] addObject:self]; + self.lks_oid = oid; + } + return self.lks_oid; +} + +- (void)setLks_oid:(unsigned long)lks_oid { + [self lookin_bindObject:@(lks_oid) forKey:@"lks_oid"]; +} + +- (unsigned long)lks_oid { + NSNumber *number = [self lookin_getBindObjectForKey:@"lks_oid"]; + return [number unsignedLongValue]; +} + ++ (NSObject *)lks_objectWithOid:(unsigned long)oid { + return [[LKS_ObjectRegistry sharedInstance] objectWithOid:oid]; +} + +#pragma mark - trace + +- (void)setLks_ivarTraces:(NSArray *)lks_ivarTraces { + [self lookin_bindObject:lks_ivarTraces.copy forKey:@"lks_ivarTraces"]; + + if (lks_ivarTraces) { + [[NSObject lks_allObjectsWithTraces] addPointer:(void *)self]; + } +} + +- (NSArray *)lks_ivarTraces { + return [self lookin_getBindObjectForKey:@"lks_ivarTraces"]; +} + +- (void)setLks_specialTrace:(NSString *)lks_specialTrace { + [self lookin_bindObject:lks_specialTrace forKey:@"lks_specialTrace"]; + if (lks_specialTrace) { + [[NSObject lks_allObjectsWithTraces] addPointer:(void *)self]; + } +} +- (NSString *)lks_specialTrace { + return [self lookin_getBindObjectForKey:@"lks_specialTrace"]; +} + ++ (void)lks_clearAllObjectsTraces { + [[[NSObject lks_allObjectsWithTraces] allObjects] enumerateObjectsUsingBlock:^(NSObject * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + obj.lks_ivarTraces = nil; + obj.lks_specialTrace = nil; + }]; + [NSObject lks_allObjectsWithTraces].count = 0; +} + ++ (NSPointerArray *)lks_allObjectsWithTraces { + static dispatch_once_t onceToken; + static NSPointerArray *lks_allObjectsWithTraces = nil; + dispatch_once(&onceToken,^{ + lks_allObjectsWithTraces = [NSPointerArray weakObjectsPointerArray]; + }); + return lks_allObjectsWithTraces; +} + +- (NSArray *)lks_classChainList { + NSMutableArray *classChainList = [NSMutableArray array]; + Class currentClass = self.class; + + while (currentClass) { + NSString *currentClassName = NSStringFromClass(currentClass); + if (currentClassName) { + [classChainList addObject:currentClassName]; + } + currentClass = [currentClass superclass]; + } + return classChainList.copy; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.h new file mode 100644 index 00000000..1623a8d1 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIBlurEffect+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/10/8. +// https://lookin.work +// + +#import + +@interface UIBlurEffect (LookinServer) + +/// 该 number 包装的对象是 UIBlurEffectStyle,之所以用 NSNumber 是因为想把 0 和 nil 区分开,毕竟这里是在 hook 系统,稳一点好。 +/// 该方法的实现需要 Hook,因此若定义了 LOOKIN_SERVER_DISABLE_HOOK 宏,则属性会返回 nil +@property(nonatomic, strong) NSNumber *lks_effectStyleNumber; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.m new file mode 100644 index 00000000..ddc36ac5 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIBlurEffect+LookinServer.m @@ -0,0 +1,57 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIBlurEffect+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/10/8. +// https://lookin.work +// + +#import "UIBlurEffect+LookinServer.h" +#import "NSObject+Lookin.h" +#import + +@implementation UIBlurEffect (LookinServer) + +#ifdef LOOKIN_SERVER_DISABLE_HOOK + +- (void)setLks_effectStyleNumber:(NSNumber *)lks_effectStyleNumber { +} + +- (NSNumber *)lks_effectStyleNumber { + return nil; +} + +#else + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Method oriMethod = class_getClassMethod([self class], @selector(effectWithStyle:)); + Method newMethod = class_getClassMethod([self class], @selector(lks_effectWithStyle:)); + method_exchangeImplementations(oriMethod, newMethod); + }); +} + ++ (UIBlurEffect *)lks_effectWithStyle:(UIBlurEffectStyle)style { + id effect = [self lks_effectWithStyle:style]; + if ([effect respondsToSelector:@selector(setLks_effectStyleNumber:)]) { + [effect setLks_effectStyleNumber:@(style)]; + } + return effect; +} + +- (void)setLks_effectStyleNumber:(NSNumber *)lks_effectStyleNumber { + [self lookin_bindObject:lks_effectStyleNumber forKey:@"lks_effectStyleNumber"]; +} + +- (NSNumber *)lks_effectStyleNumber { + return [self lookin_getBindObjectForKey:@"lks_effectStyleNumber"]; +} + +#endif /* LOOKIN_SERVER_DISABLE_HOOK */ + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.h new file mode 100644 index 00000000..9b4133fd --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.h @@ -0,0 +1,26 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIColor+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/6/5. +// https://lookin.work +// + +#import + +@interface UIColor (LookinServer) + +- (NSArray *)lks_rgbaComponents; ++ (instancetype)lks_colorFromRGBAComponents:(NSArray *)components; + +- (NSString *)lks_rgbaString; +- (NSString *)lks_hexString; + +/// will check if the argument is a real CGColor ++ (UIColor *)lks_colorWithCGColor:(CGColorRef)cgColor; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.m new file mode 100644 index 00000000..ce1aea93 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIColor+LookinServer.m @@ -0,0 +1,183 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIColor+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/6/5. +// https://lookin.work +// + +#import "UIColor+LookinServer.h" + +@implementation UIColor (LookinServer) + +- (NSArray *)lks_rgbaComponents { + CGFloat r, g, b, a; + CGColorRef cgColor = [self CGColor]; + const CGFloat *components = CGColorGetComponents(cgColor); + if (CGColorGetNumberOfComponents(cgColor) == 4) { + r = components[0]; + g = components[1]; + b = components[2]; + a = components[3]; + } else if (CGColorGetNumberOfComponents(cgColor) == 2) { + r = components[0]; + g = components[0]; + b = components[0]; + a = components[1]; + } else if (CGColorGetNumberOfComponents(cgColor) == 1) { + r = components[0]; + g = components[0]; + b = components[0]; + a = components[0]; + } else { + r = 0; + g = 0; + b = 0; + a = 0; + NSAssert(NO, @""); + } + NSArray *rgba = @[@(r), @(g), @(b), @(a)]; + return rgba; +} + ++ (instancetype)lks_colorFromRGBAComponents:(NSArray *)components { + if (!components) { + return nil; + } + if (components.count != 4) { + NSAssert(NO, @""); + return nil; + } + UIColor *color = [UIColor colorWithRed:components[0].doubleValue green:components[1].doubleValue blue:components[2].doubleValue alpha:components[3].doubleValue]; + return color; +} + +- (NSString *)lks_rgbaString { + CGFloat r, g, b, a; + CGColorRef cgColor = [self CGColor]; + const CGFloat *components = CGColorGetComponents(cgColor); + if (CGColorGetNumberOfComponents(cgColor) == 4) { + r = components[0]; + g = components[1]; + b = components[2]; + a = components[3]; + } else if (CGColorGetNumberOfComponents(cgColor) == 2) { + r = components[0]; + g = components[0]; + b = components[0]; + a = components[1]; + } else { + r = 0; + g = 0; + b = 0; + a = 0; + NSAssert(NO, @""); + } + + if (a >= 1) { + return [NSString stringWithFormat:@"(%.0f, %.0f, %.0f)", r * 255, g * 255, b * 255]; + } else { + return [NSString stringWithFormat:@"(%.0f, %.0f, %.0f, %.2f)", r * 255, g * 255, b * 255, a]; + } +} + +- (NSString *)lks_hexString { + CGFloat r, g, b, a; + CGColorRef cgColor = [self CGColor]; + const CGFloat *components = CGColorGetComponents(cgColor); + if (CGColorGetNumberOfComponents(cgColor) == 4) { + r = components[0]; + g = components[1]; + b = components[2]; + a = components[3]; + } else if (CGColorGetNumberOfComponents(cgColor) == 2) { + r = components[0]; + g = components[0]; + b = components[0]; + a = components[1]; + } else { + r = 0; + g = 0; + b = 0; + a = 0; + NSAssert(NO, @""); + } + + NSInteger red = r * 255; + NSInteger green = g * 255; + NSInteger blue = b * 255; + NSInteger alpha = a * 255; + + return [[NSString stringWithFormat:@"#%@%@%@%@", + [UIColor _alignColorHexStringLength:[UIColor _hexStringWithInteger:alpha]], + [UIColor _alignColorHexStringLength:[UIColor _hexStringWithInteger:red]], + [UIColor _alignColorHexStringLength:[UIColor _hexStringWithInteger:green]], + [UIColor _alignColorHexStringLength:[UIColor _hexStringWithInteger:blue]]] lowercaseString]; +} + +// 对于色值只有单位数的,在前面补一个0,例如“F”会补齐为“0F” ++ (NSString *)_alignColorHexStringLength:(NSString *)hexString { + return hexString.length < 2 ? [@"0" stringByAppendingString:hexString] : hexString; +} + ++ (NSString *)_hexStringWithInteger:(NSInteger)integer { + NSString *hexString = @""; + NSInteger remainder = 0; + for (NSInteger i = 0; i < 9; i++) { + remainder = integer % 16; + integer = integer / 16; + NSString *letter = [self _hexLetterStringWithInteger:remainder]; + hexString = [letter stringByAppendingString:hexString]; + if (integer == 0) { + break; + } + + } + return hexString; +} + ++ (NSString *)_hexLetterStringWithInteger:(NSInteger)integer { + NSAssert(integer < 16, @"要转换的数必须是16进制里的个位数,也即小于16,但你传给我是%@", @(integer)); + + NSString *letter = nil; + switch (integer) { + case 10: + letter = @"A"; + break; + case 11: + letter = @"B"; + break; + case 12: + letter = @"C"; + break; + case 13: + letter = @"D"; + break; + case 14: + letter = @"E"; + break; + case 15: + letter = @"F"; + break; + default: + letter = [[NSString alloc]initWithFormat:@"%@", @(integer)]; + break; + } + return letter; +} + ++ (UIColor *)lks_colorWithCGColor:(CGColorRef)cgColor { + if (!cgColor) { + return nil; + } + if (CFGetTypeID(cgColor) != CGColorGetTypeID()) { + return nil; + } + return [UIColor colorWithCGColor:cgColor]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.h new file mode 100644 index 00000000..cf7f6ff9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.h @@ -0,0 +1,22 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIImage+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/5/14. +// https://lookin.work +// + +#import + +@interface UIImage (LookinServer) + +/// 该方法的实现需要 Hook,因此若定义了 LOOKIN_SERVER_DISABLE_HOOK 宏,则属性会返回 nil +@property(nonatomic, copy) NSString *lks_imageSourceName; + +- (NSData *)lookin_data; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.m new file mode 100644 index 00000000..97f8264a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIImage+LookinServer.m @@ -0,0 +1,95 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIImage+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/5/14. +// https://lookin.work +// + +#import +#import "UIImage+LookinServer.h" +#import "LookinServerDefines.h" + +@implementation UIImage (LookinServer) + +#ifdef LOOKIN_SERVER_DISABLE_HOOK + +- (void)setLks_imageSourceName:(NSString *)lks_imageSourceName { +} + +- (NSString *)lks_imageSourceName { + return nil; +} + +#else + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Method oriMethod = class_getClassMethod([self class], @selector(imageNamed:)); + Method newMethod = class_getClassMethod([self class], @selector(lks_imageNamed:)); + method_exchangeImplementations(oriMethod, newMethod); + + oriMethod = class_getClassMethod([self class], @selector(imageWithContentsOfFile:)); + newMethod = class_getClassMethod([self class], @selector(lks_imageWithContentsOfFile:)); + method_exchangeImplementations(oriMethod, newMethod); + + oriMethod = class_getClassMethod([self class], @selector(imageNamed:inBundle:compatibleWithTraitCollection:)); + newMethod = class_getClassMethod([self class], @selector(lks_imageNamed:inBundle:compatibleWithTraitCollection:)); + method_exchangeImplementations(oriMethod, newMethod); + + if (@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) { + oriMethod = class_getClassMethod([self class], @selector(imageNamed:inBundle:withConfiguration:)); + newMethod = class_getClassMethod([self class], @selector(lks_imageNamed:inBundle:withConfiguration:)); + method_exchangeImplementations(oriMethod, newMethod); + } + }); +} + ++ (nullable UIImage *)lks_imageNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle withConfiguration:(nullable UIImageConfiguration *)configuration API_AVAILABLE(ios(13.0),tvos(13.0),watchos(6.0)) +{ + UIImage *image = [self lks_imageNamed:name inBundle:bundle withConfiguration:configuration]; + image.lks_imageSourceName = name; + return image; +} + ++ (nullable UIImage *)lks_imageNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection API_AVAILABLE(ios(8.0)) +{ + UIImage *image = [self lks_imageNamed:name inBundle:bundle compatibleWithTraitCollection:traitCollection]; + image.lks_imageSourceName = name; + return image; +} + ++ (UIImage *)lks_imageNamed:(NSString *)name { + UIImage *image = [self lks_imageNamed:name]; + image.lks_imageSourceName = name; + return image; +} + ++ (UIImage *)lks_imageWithContentsOfFile:(NSString *)path { + UIImage *image = [self lks_imageWithContentsOfFile:path]; + + NSString *fileName = [[path componentsSeparatedByString:@"/"].lastObject componentsSeparatedByString:@"."].firstObject; + image.lks_imageSourceName = fileName; + return image; +} + +- (void)setLks_imageSourceName:(NSString *)lks_imageSourceName { + [self lookin_bindObject:lks_imageSourceName.copy forKey:@"lks_imageSourceName"]; +} + +- (NSString *)lks_imageSourceName { + return [self lookin_getBindObjectForKey:@"lks_imageSourceName"]; +} + +#endif /* LOOKIN_SERVER_DISABLE_HOOK */ + +- (NSData *)lookin_data { + return UIImagePNGRepresentation(self); +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.h new file mode 100644 index 00000000..6da90285 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.h @@ -0,0 +1,20 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIImageView+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/9/18. +// https://lookin.work +// + +#import + +@interface UIImageView (LookinServer) + +- (NSString *)lks_imageSourceName; +- (NSNumber *)lks_imageViewOidIfHasImage; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.m new file mode 100644 index 00000000..76e83cfb --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIImageView+LookinServer.m @@ -0,0 +1,31 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIImageView+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/9/18. +// https://lookin.work +// + +#import "UIImageView+LookinServer.h" +#import "UIImage+LookinServer.h" +#import "NSObject+LookinServer.h" + +@implementation UIImageView (LookinServer) + +- (NSString *)lks_imageSourceName { + return self.image.lks_imageSourceName; +} + +- (NSNumber *)lks_imageViewOidIfHasImage { + if (!self.image) { + return nil; + } + unsigned long oid = [self lks_registerOid]; + return @(oid); +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.h new file mode 100644 index 00000000..92c9294d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UILabel+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import + +@interface UILabel (LookinServer) + +@property(nonatomic, assign) CGFloat lks_fontSize; + +- (NSString *)lks_fontName; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.m new file mode 100644 index 00000000..b7b9f70a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UILabel+LookinServer.m @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UILabel+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import "UILabel+LookinServer.h" + +@implementation UILabel (LookinServer) + +- (CGFloat)lks_fontSize { + return self.font.pointSize; +} +- (void)setLks_fontSize:(CGFloat)lks_fontSize { + UIFont *font = [self.font fontWithSize:lks_fontSize]; + self.font = font; +} + +- (NSString *)lks_fontName { + return self.font.fontName; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.h new file mode 100644 index 00000000..881fa367 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.h @@ -0,0 +1,19 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITableView+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/9/5. +// https://lookin.work +// + +#import + +@interface UITableView (LookinServer) + +- (NSArray *)lks_numberOfRows; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.m new file mode 100644 index 00000000..3788e3fe --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITableView+LookinServer.m @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITableView+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/9/5. +// https://lookin.work +// + +#import "UITableView+LookinServer.h" +#import "LookinServerDefines.h" + +@implementation UITableView (LookinServer) + +- (NSArray *)lks_numberOfRows { + NSUInteger sectionsCount = MIN(self.numberOfSections, 10); + NSArray *rowsCount = [NSArray lookin_arrayWithCount:sectionsCount block:^id(NSUInteger idx) { + return @([self numberOfRowsInSection:idx]); + }]; + if (rowsCount.count == 0) { + return nil; + } + return rowsCount; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.h new file mode 100644 index 00000000..429c30b1 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITextField+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import + +@interface UITextField (LookinServer) + +@property(nonatomic, assign) CGFloat lks_fontSize; + +- (NSString *)lks_fontName; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.m new file mode 100644 index 00000000..9e07a761 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITextField+LookinServer.m @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITextField+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import "UITextField+LookinServer.h" + +@implementation UITextField (LookinServer) + +- (CGFloat)lks_fontSize { + return self.font.pointSize; +} +- (void)setLks_fontSize:(CGFloat)lks_fontSize { + UIFont *font = [self.font fontWithSize:lks_fontSize]; + self.font = font; +} + +- (NSString *)lks_fontName { + return self.font.fontName; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.h new file mode 100644 index 00000000..e36b2ab4 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITextView+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import + +@interface UITextView (LookinServer) + +@property(nonatomic, assign) CGFloat lks_fontSize; + +- (NSString *)lks_fontName; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.m new file mode 100644 index 00000000..bd81a8b0 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UITextView+LookinServer.m @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UITextView+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/2/26. +// https://lookin.work +// + +#import "UITextView+LookinServer.h" + +@implementation UITextView (LookinServer) + +- (CGFloat)lks_fontSize { + return self.font.pointSize; +} +- (void)setLks_fontSize:(CGFloat)lks_fontSize { + UIFont *font = [self.font fontWithSize:lks_fontSize]; + self.font = font; +} + +- (NSString *)lks_fontName { + return self.font.fontName; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.h new file mode 100644 index 00000000..eca36a15 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.h @@ -0,0 +1,44 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIView+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/3/19. +// https://lookin.work +// + +#import "LookinDefines.h" +#import + +@interface UIView (LookinServer) + +/// 如果 myViewController.view = myView,则可以通过 myView 的 lks_findHostViewController 方法找到 myViewController +- (UIViewController *)lks_findHostViewController; + +/// 是否是 UITabBar 的 childrenView,如果是的话,则截图时需要强制使用 renderInContext: 的方式而非 drawViewHierarchyInRect:afterScreenUpdates: 否则在 iOS 13 上获取到的图像是空的不知道为什么 +@property(nonatomic, assign) BOOL lks_isChildrenViewOfTabBar; + +/// point 是相对于 receiver 自身的坐标系 +- (UIView *)lks_subviewAtPoint:(CGPoint)point preferredClasses:(NSArray *)preferredClasses; + +- (CGFloat)lks_bestWidth; +- (CGFloat)lks_bestHeight; +- (CGSize)lks_bestSize; + +@property(nonatomic, assign) float lks_horizontalContentHuggingPriority; +@property(nonatomic, assign) float lks_verticalContentHuggingPriority; + +@property(nonatomic, assign) float lks_horizontalContentCompressionResistancePriority; +@property(nonatomic, assign) float lks_verticalContentCompressionResistancePriority; + +/// 遍历全局的 view 并给他们设置 lks_involvedRawConstraints 属性 ++ (void)lks_rebuildGlobalInvolvedRawConstraints; +/// 该属性保存了牵扯到当前 view 的所有 constraints,包括那些没有生效的 +@property(nonatomic, strong) NSMutableArray *lks_involvedRawConstraints; + +- (NSArray *> *)lks_constraints; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.m new file mode 100644 index 00000000..9cfa5f39 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIView+LookinServer.m @@ -0,0 +1,215 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIView+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/3/19. +// https://lookin.work +// + +#import "UIView+LookinServer.h" +#import +#import "LookinObject.h" +#import "LookinAutoLayoutConstraint.h" +#import "LookinServerDefines.h" +#import "LKS_MultiplatformAdapter.h" + +@implementation UIView (LookinServer) + +- (UIViewController *)lks_findHostViewController { + UIResponder *responder = [self nextResponder]; + if (!responder) { + return nil; + } + if (![responder isKindOfClass:[UIViewController class]]) { + return nil; + } + UIViewController *viewController = (UIViewController *)responder; + if (viewController.view != self) { + return nil; + } + return viewController; +} + +- (UIView *)lks_subviewAtPoint:(CGPoint)point preferredClasses:(NSArray *)preferredClasses { + BOOL isPreferredClassForSelf = [preferredClasses lookin_any:^BOOL(Class obj) { + return [self isKindOfClass:obj]; + }]; + if (isPreferredClassForSelf) { + return self; + } + + UIView *targetView = [self.subviews lookin_lastFiltered:^BOOL(__kindof UIView *obj) { + if (obj.hidden || obj.alpha <= 0.01) { + return NO; + } + BOOL contains = CGRectContainsPoint(obj.frame, point); + return contains; + }]; + + if (!targetView) { + return self; + } + + CGPoint newPoint = [targetView convertPoint:point fromView:self]; + targetView = [targetView lks_subviewAtPoint:newPoint preferredClasses:preferredClasses]; + return targetView; +} + +- (CGSize)lks_bestSize { + return [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; +} + +- (CGFloat)lks_bestWidth { + return self.lks_bestSize.width; +} + +- (CGFloat)lks_bestHeight { + return self.lks_bestSize.height; +} + +- (void)setLks_isChildrenViewOfTabBar:(BOOL)lks_isChildrenViewOfTabBar { + [self lookin_bindBOOL:lks_isChildrenViewOfTabBar forKey:@"lks_isChildrenViewOfTabBar"]; +} +- (BOOL)lks_isChildrenViewOfTabBar { + return [self lookin_getBindBOOLForKey:@"lks_isChildrenViewOfTabBar"]; +} + +- (void)setLks_verticalContentHuggingPriority:(float)lks_verticalContentHuggingPriority { + [self setContentHuggingPriority:lks_verticalContentHuggingPriority forAxis:UILayoutConstraintAxisVertical]; +} +- (float)lks_verticalContentHuggingPriority { + return [self contentHuggingPriorityForAxis:UILayoutConstraintAxisVertical]; +} + +- (void)setLks_horizontalContentHuggingPriority:(float)lks_horizontalContentHuggingPriority { + [self setContentHuggingPriority:lks_horizontalContentHuggingPriority forAxis:UILayoutConstraintAxisHorizontal]; +} +- (float)lks_horizontalContentHuggingPriority { + return [self contentHuggingPriorityForAxis:UILayoutConstraintAxisHorizontal]; +} + +- (void)setLks_verticalContentCompressionResistancePriority:(float)lks_verticalContentCompressionResistancePriority { + [self setContentCompressionResistancePriority:lks_verticalContentCompressionResistancePriority forAxis:UILayoutConstraintAxisVertical]; +} +- (float)lks_verticalContentCompressionResistancePriority { + return [self contentCompressionResistancePriorityForAxis:UILayoutConstraintAxisVertical]; +} + +- (void)setLks_horizontalContentCompressionResistancePriority:(float)lks_horizontalContentCompressionResistancePriority { + [self setContentCompressionResistancePriority:lks_horizontalContentCompressionResistancePriority forAxis:UILayoutConstraintAxisHorizontal]; +} +- (float)lks_horizontalContentCompressionResistancePriority { + return [self contentCompressionResistancePriorityForAxis:UILayoutConstraintAxisHorizontal]; +} + ++ (void)lks_rebuildGlobalInvolvedRawConstraints { + [[LKS_MultiplatformAdapter allWindows] enumerateObjectsUsingBlock:^(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) { + [self lks_removeInvolvedRawConstraintsForViewsRootedByView:window]; + }]; + [[LKS_MultiplatformAdapter allWindows] enumerateObjectsUsingBlock:^(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) { + [self lks_addInvolvedRawConstraintsForViewsRootedByView:window]; + }]; +} + ++ (void)lks_addInvolvedRawConstraintsForViewsRootedByView:(UIView *)rootView { + [rootView.constraints enumerateObjectsUsingBlock:^(__kindof NSLayoutConstraint * _Nonnull constraint, NSUInteger idx, BOOL * _Nonnull stop) { + UIView *firstView = constraint.firstItem; + if ([firstView isKindOfClass:[UIView class]] && ![firstView.lks_involvedRawConstraints containsObject:constraint]) { + if (!firstView.lks_involvedRawConstraints) { + firstView.lks_involvedRawConstraints = [NSMutableArray array]; + } + [firstView.lks_involvedRawConstraints addObject:constraint]; + } + + UIView *secondView = constraint.secondItem; + if ([secondView isKindOfClass:[UIView class]] && ![secondView.lks_involvedRawConstraints containsObject:constraint]) { + if (!secondView.lks_involvedRawConstraints) { + secondView.lks_involvedRawConstraints = [NSMutableArray array]; + } + [secondView.lks_involvedRawConstraints addObject:constraint]; + } + }]; + + [rootView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull subview, NSUInteger idx, BOOL * _Nonnull stop) { + [self lks_addInvolvedRawConstraintsForViewsRootedByView:subview]; + }]; +} + ++ (void)lks_removeInvolvedRawConstraintsForViewsRootedByView:(UIView *)rootView { + [rootView.lks_involvedRawConstraints removeAllObjects]; + [rootView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull subview, NSUInteger idx, BOOL * _Nonnull stop) { + [self lks_removeInvolvedRawConstraintsForViewsRootedByView:subview]; + }]; +} + +- (void)setLks_involvedRawConstraints:(NSMutableArray *)lks_involvedRawConstraints { + [self lookin_bindObject:lks_involvedRawConstraints forKey:@"lks_involvedRawConstraints"]; +} + +- (NSMutableArray *)lks_involvedRawConstraints { + return [self lookin_getBindObjectForKey:@"lks_involvedRawConstraints"]; +} + +- (NSArray *)lks_constraints { + /** + - lks_involvedRawConstraints 保存了牵扯到了 self 的所有的 constraints(包括未生效的,但不包括 inactive 的,整个产品逻辑都是直接忽略 inactive 的 constraints) + - 通过 constraintsAffectingLayoutForAxis 可以拿到会影响 self 布局的所有已生效的 constraints(这里称之为 effectiveConstraints) + - 很多情况下,一条 constraint 会出现在 effectiveConstraints 里但不会出现在 lks_involvedRawConstraints 里,比如: + · UIWindow 拥有 minX, minY, width, height 四个 effectiveConstraints,但 lks_involvedRawConstraints 为空,因为它的 constraints 属性为空(这一点不知道为啥,但 Xcode Inspector 和 Reveal 确实也不会显示这四个 constraints) + · 如果设置了 View1 的 center 和 superview 的 center 保持一致,则 superview 的 width 和 height 也会出现在 effectiveConstraints 里,但不会出现在 lks_involvedRawConstraints 里(这点可以理解,毕竟这种场景下 superview 的 width 和 height 确实会影响到 View1) + */ + NSMutableArray *effectiveConstraints = [NSMutableArray array]; + [effectiveConstraints addObjectsFromArray:[self constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal]]; + [effectiveConstraints addObjectsFromArray:[self constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical]]; + + NSArray *lookinConstraints = [self.lks_involvedRawConstraints lookin_map:^id(NSUInteger idx, __kindof NSLayoutConstraint *constraint) { + BOOL isEffective = [effectiveConstraints containsObject:constraint]; + if ([constraint isActive]) { + // trying to get firstItem or secondItem of an inactive constraint may cause dangling-pointer crash + // https://github.com/QMUI/LookinServer/issues/86 + LookinConstraintItemType firstItemType = [self _lks_constraintItemTypeForItem:constraint.firstItem]; + LookinConstraintItemType secondItemType = [self _lks_constraintItemTypeForItem:constraint.secondItem]; + LookinAutoLayoutConstraint *lookinConstraint = [LookinAutoLayoutConstraint instanceFromNSConstraint:constraint isEffective:isEffective firstItemType:firstItemType secondItemType:secondItemType]; + return lookinConstraint; + } + return nil; + }]; + return lookinConstraints.count ? lookinConstraints : nil; +} + +- (LookinConstraintItemType)_lks_constraintItemTypeForItem:(id)item { + if (!item) { + return LookinConstraintItemTypeNil; + } + if (item == self) { + return LookinConstraintItemTypeSelf; + } + if (item == self.superview) { + return LookinConstraintItemTypeSuper; + } + + // 在 runtime 时,这里会遇到的 UILayoutGuide 和 _UILayoutGuide 居然是 UIView 的子类,不知道是看错了还是有什么玄机,所以在判断是否是 UIView 之前要先判断这个 + if (@available(iOS 9.0, *)) { + if ([item isKindOfClass:[UILayoutGuide class]]) { + return LookinConstraintItemTypeLayoutGuide; + } + } + + NSString *className = NSStringFromClass([item class]); + if ([className hasSuffix:@"_UILayoutGuide"]) { + return LookinConstraintItemTypeLayoutGuide; + } + + if ([item isKindOfClass:[UIView class]]) { + return LookinConstraintItemTypeView; + } + + NSAssert(NO, @""); + return LookinConstraintItemTypeUnknown; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.h new file mode 100644 index 00000000..1cab2a64 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.h @@ -0,0 +1,19 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIViewController+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/4/22. +// https://lookin.work +// + +#import + +@interface UIViewController (LookinServer) + ++ (UIViewController *)lks_visibleViewController; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.m new file mode 100644 index 00000000..2833eab2 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIViewController+LookinServer.m @@ -0,0 +1,48 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIViewController+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/4/22. +// https://lookin.work +// + +#import "UIViewController+LookinServer.h" +#import "UIView+LookinServer.h" +#import +#import "LKS_MultiplatformAdapter.h" + +@implementation UIViewController (LookinServer) + ++ (nullable UIViewController *)lks_visibleViewController { + + UIViewController *rootViewController = [LKS_MultiplatformAdapter keyWindow].rootViewController; + UIViewController *visibleViewController = [rootViewController lks_visibleViewControllerIfExist]; + return visibleViewController; +} + +- (UIViewController *)lks_visibleViewControllerIfExist { + + if (self.presentedViewController) { + return [self.presentedViewController lks_visibleViewControllerIfExist]; + } + + if ([self isKindOfClass:[UINavigationController class]]) { + return [((UINavigationController *)self).visibleViewController lks_visibleViewControllerIfExist]; + } + + if ([self isKindOfClass:[UITabBarController class]]) { + return [((UITabBarController *)self).selectedViewController lks_visibleViewControllerIfExist]; + } + + if (self.isViewLoaded && !self.view.hidden && self.view.alpha > 0.01) { + return self; + } else { + return nil; + } +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.h b/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.h new file mode 100644 index 00000000..697d840c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIVisualEffectView+LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/10/8. +// https://lookin.work +// + +#import + +@interface UIVisualEffectView (LookinServer) + +- (void)setLks_blurEffectStyleNumber:(NSNumber *)lks_blurEffectStyleNumber; + +- (NSNumber *)lks_blurEffectStyleNumber; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.m b/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.m new file mode 100644 index 00000000..df06b10c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Category/UIVisualEffectView+LookinServer.m @@ -0,0 +1,33 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// UIVisualEffectView+LookinServer.m +// LookinServer +// +// Created by Li Kai on 2019/10/8. +// https://lookin.work +// + +#import "UIVisualEffectView+LookinServer.h" +#import "UIBlurEffect+LookinServer.h" + +@implementation UIVisualEffectView (LookinServer) + +- (void)setLks_blurEffectStyleNumber:(NSNumber *)lks_blurEffectStyleNumber { + UIBlurEffectStyle style = [lks_blurEffectStyleNumber integerValue]; + UIBlurEffect *effect = [UIBlurEffect effectWithStyle:style]; + self.effect = effect; +} + +- (NSNumber *)lks_blurEffectStyleNumber { + UIVisualEffect *effect = self.effect; + if (![effect isKindOfClass:[UIBlurEffect class]]) { + return nil; + } + UIBlurEffect *blurEffect = (UIBlurEffect *)effect; + return blurEffect.lks_effectStyleNumber; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.h b/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.h new file mode 100644 index 00000000..684127b9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.h @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Lookin.h +// Lookin +// +// Created by Li Kai on 2018/8/5. +// https://lookin.work +// + +#import + +extern NSString *const LKS_ConnectionDidEndNotificationName; + +@class LookinConnectionResponseAttachment; + +@interface LKS_ConnectionManager : NSObject + ++ (instancetype)sharedInstance; + +@property(nonatomic, assign) BOOL applicationIsActive; + +- (void)respond:(LookinConnectionResponseAttachment *)data requestType:(uint32_t)requestType tag:(uint32_t)tag; + +- (void)pushData:(NSObject *)data type:(uint32_t)type; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.m b/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.m new file mode 100644 index 00000000..c992c7ff --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/LKS_ConnectionManager.m @@ -0,0 +1,268 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinServer.m +// LookinServer +// +// Created by Li Kai on 2018/8/5. +// https://lookin.work +// + +#import "LKS_ConnectionManager.h" +#import "Lookin_PTChannel.h" +#import "LKS_RequestHandler.h" +#import "LookinConnectionResponseAttachment.h" +#import "LKS_ExportManager.h" +#import "LookinServerDefines.h" +#import "LKS_TraceManager.h" +#import "LKS_MultiplatformAdapter.h" + +NSString *const LKS_ConnectionDidEndNotificationName = @"LKS_ConnectionDidEndNotificationName"; + +@interface LKS_ConnectionManager () + +@property(nonatomic, weak) Lookin_PTChannel *peerChannel_; + +@property(nonatomic, strong) LKS_RequestHandler *requestHandler; + +@end + +@implementation LKS_ConnectionManager + ++ (instancetype)sharedInstance { + static LKS_ConnectionManager *sharedInstance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[LKS_ConnectionManager alloc] init]; + }); + return sharedInstance; +} + ++ (void)load { + // 触发 init 方法 + [LKS_ConnectionManager sharedInstance]; +} + +- (instancetype)init { + if (self = [super init]) { + NSLog(@"LookinServer - Will launch. Framework version: %@", LOOKIN_SERVER_READABLE_VERSION); + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleApplicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleWillResignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleLocalInspect:) name:@"Lookin_2D" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleLocalInspect:) name:@"Lookin_3D" object:nil]; + [[NSNotificationCenter defaultCenter] addObserverForName:@"Lookin_Export" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { + [[LKS_ExportManager sharedInstance] exportAndShare]; + }]; + [[NSNotificationCenter defaultCenter] addObserverForName:@"Lookin_RelationSearch" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { + [[LKS_TraceManager sharedInstance] addSearchTarger:note.object]; + }]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleGetLookinInfo:) name:@"GetLookinInfo" object:nil]; + + self.requestHandler = [LKS_RequestHandler new]; + } + return self; +} + +- (void)_handleWillResignActiveNotification { + self.applicationIsActive = NO; + + if (self.peerChannel_ && ![self.peerChannel_ isConnected]) { + [self.peerChannel_ close]; + self.peerChannel_ = nil; + } +} + +- (void)_handleApplicationDidBecomeActive { + self.applicationIsActive = YES; + [self searchPortToListenIfNoConnection]; +} + +- (void)searchPortToListenIfNoConnection { + if ([self.peerChannel_ isConnected]) { + NSLog(@"LookinServer - Abort to search ports. Already has connected channel."); + return; + } + NSLog(@"LookinServer - Searching port to listen..."); + [self.peerChannel_ close]; + self.peerChannel_ = nil; + + if ([self isiOSAppOnMac]) { + [self _tryToListenOnPortFrom:LookinSimulatorIPv4PortNumberStart to:LookinSimulatorIPv4PortNumberEnd current:LookinSimulatorIPv4PortNumberStart]; + } else { + [self _tryToListenOnPortFrom:LookinUSBDeviceIPv4PortNumberStart to:LookinUSBDeviceIPv4PortNumberEnd current:LookinUSBDeviceIPv4PortNumberStart]; + } +} + +- (BOOL)isiOSAppOnMac { +#if TARGET_OS_SIMULATOR + return YES; +#else + if (@available(iOS 14.0, *)) { + // isiOSAppOnMac 这个 API 看似在 iOS 14.0 上可用,但其实在 iOS 14 beta 上是不存在的、有 unrecognized selector 问题,因此这里要用 respondsToSelector 做一下保护 + NSProcessInfo *info = [NSProcessInfo processInfo]; + if ([info respondsToSelector:@selector(isiOSAppOnMac)]) { + return [info isiOSAppOnMac]; + } else if ([info respondsToSelector:@selector(isMacCatalystApp)]) { + return [info isMacCatalystApp]; + } else { + return NO; + } + } + if (@available(iOS 13.0, tvOS 13.0, *)) { + return [NSProcessInfo processInfo].isMacCatalystApp; + } + return NO; +#endif +} + +- (void)_tryToListenOnPortFrom:(int)fromPort to:(int)toPort current:(int)currentPort { + Lookin_PTChannel *channel = [Lookin_PTChannel channelWithDelegate:self]; + channel.targetPort = currentPort; + [channel listenOnPort:currentPort IPv4Address:INADDR_LOOPBACK callback:^(NSError *error) { + if (error) { + if (error.code == 48) { + // 该地址已被占用 + } else { + // 未知失败 + } + + if (currentPort < toPort) { + // 尝试下一个端口 + NSLog(@"LookinServer - 127.0.0.1:%d is unavailable(%@). Will try anothor address ...", currentPort, error); + [self _tryToListenOnPortFrom:fromPort to:toPort current:(currentPort + 1)]; + } else { + // 所有端口都尝试完毕,全部失败 + NSLog(@"LookinServer - 127.0.0.1:%d is unavailable(%@).", currentPort, error); + NSLog(@"LookinServer - Connect failed in the end."); + } + + } else { + // 成功 + NSLog(@"LookinServer - Connected successfully on 127.0.0.1:%d", currentPort); + // 此时 peerChannel_ 状态为 listening + self.peerChannel_ = channel; + } + }]; +} + +- (void)dealloc { + if (self.peerChannel_) { + [self.peerChannel_ close]; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)respond:(LookinConnectionResponseAttachment *)data requestType:(uint32_t)requestType tag:(uint32_t)tag { + [self _sendData:data frameOfType:requestType tag:tag]; +} + +- (void)pushData:(NSObject *)data type:(uint32_t)type { + [self _sendData:data frameOfType:type tag:0]; +} + +- (void)_sendData:(NSObject *)data frameOfType:(uint32_t)frameOfType tag:(uint32_t)tag { + if (self.peerChannel_) { + NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:data]; + dispatch_data_t payload = [archivedData createReferencingDispatchData]; + + [self.peerChannel_ sendFrameOfType:frameOfType tag:tag withPayload:payload callback:^(NSError *error) { + if (error) { + } + }]; + } +} + +#pragma mark - Lookin_PTChannelDelegate + +- (BOOL)ioFrameChannel:(Lookin_PTChannel*)channel shouldAcceptFrameOfType:(uint32_t)type tag:(uint32_t)tag payloadSize:(uint32_t)payloadSize { + if (channel != self.peerChannel_) { + return NO; + } else if ([self.requestHandler canHandleRequestType:type]) { + return YES; + } else { + [channel close]; + return NO; + } +} + +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(Lookin_PTData*)payload { + id object = nil; + if (payload) { + id unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfDispatchData:payload.dispatchData]]; + if ([unarchivedObject isKindOfClass:[LookinConnectionAttachment class]]) { + LookinConnectionAttachment *attachment = (LookinConnectionAttachment *)unarchivedObject; + object = attachment.data; + } else { + object = unarchivedObject; + } + } + [self.requestHandler handleRequestType:type tag:tag object:object]; +} + +/// 当 Client 端链接成功时,该方法会被调用,然后 channel 的状态会变成 connected +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didAcceptConnection:(Lookin_PTChannel*)otherChannel fromAddress:(Lookin_PTAddress*)address { + NSLog(@"LookinServer - channel:%@, acceptConnection:%@", channel.debugTag, otherChannel.debugTag); + + Lookin_PTChannel *previousChannel = self.peerChannel_; + + otherChannel.targetPort = address.port; + self.peerChannel_ = otherChannel; + + [previousChannel cancel]; +} + +/// 当连接过 Lookin 客户端,然后 Lookin 客户端又被关闭时,会走到这里 +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didEndWithError:(NSError*)error { + if (self.peerChannel_ != channel) { + // Client 端第一次连接上时,之前 listen 的 port 会被 Peertalk 内部 cancel(并在 didAcceptConnection 方法里给业务抛一个新建的 connected 状态的 channel),那个被 cancel 的 channel 会走到这里 + NSLog(@"LookinServer - Ignore channel%@ end.", channel.debugTag); + return; + } + // Client 端关闭时,会走到这里 + NSLog(@"LookinServer - channel%@ DidEndWithError:%@", channel.debugTag, error); + + [[NSNotificationCenter defaultCenter] postNotificationName:LKS_ConnectionDidEndNotificationName object:self]; + [self searchPortToListenIfNoConnection]; +} + +#pragma mark - Handler + +- (void)_handleLocalInspect:(NSNotification *)note { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Lookin" message:@"Failed to run local inspection. The feature has been removed. Please use the computer version of Lookin or consider SDKs like FLEX for similar functionality." preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; + [alertController addAction:okAction]; + UIWindow *keyWindow = [LKS_MultiplatformAdapter keyWindow]; + UIViewController *rootViewController = [keyWindow rootViewController]; + [rootViewController presentViewController:alertController animated:YES completion:nil]; + + NSLog(@"LookinServer - Failed to run local inspection. The feature has been removed. Please use the computer version of Lookin or consider SDKs like FLEX for similar functionality."); +} + +- (void)handleGetLookinInfo:(NSNotification *)note { + NSDictionary* userInfo = note.userInfo; + if (!userInfo) { + return; + } + NSMutableDictionary* infoWrapper = userInfo[@"infos"]; + if (![infoWrapper isKindOfClass:[NSMutableDictionary class]]) { + NSLog(@"LookinServer - GetLookinInfo failed. Params invalid."); + return; + } + infoWrapper[@"lookinServerVersion"] = LOOKIN_SERVER_READABLE_VERSION; +} + +@end + +/// 这个类使得用户可以通过 NSClassFromString(@"Lookin") 来判断 LookinServer 是否被编译进了项目里 + +@interface Lookin : NSObject + +@end + +@implementation Lookin + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.h b/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.h new file mode 100644 index 00000000..52ebe712 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_RequestHandler.h +// LookinServer +// +// Created by Li Kai on 2019/1/15. +// https://lookin.work +// + +#import + +@interface LKS_RequestHandler : NSObject + +- (BOOL)canHandleRequestType:(uint32_t)requestType; + +- (void)handleRequestType:(uint32_t)requestType tag:(uint32_t)tag object:(id)object; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.m b/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.m new file mode 100644 index 00000000..c9d1572d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/LKS_RequestHandler.m @@ -0,0 +1,558 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_RequestHandler.m +// LookinServer +// +// Created by Li Kai on 2019/1/15. +// https://lookin.work +// + +#import "LKS_RequestHandler.h" +#import "NSObject+LookinServer.h" +#import "UIImage+LookinServer.h" +#import "LKS_ConnectionManager.h" +#import "LookinConnectionResponseAttachment.h" +#import "LookinAttributeModification.h" +#import "LookinDisplayItemDetail.h" +#import "LookinHierarchyInfo.h" +#import "LookinServerDefines.h" +#import +#import "LookinObject.h" +#import "LookinAppInfo.h" +#import "LKS_AttrGroupsMaker.h" +#import "LKS_InbuiltAttrModificationHandler.h" +#import "LKS_CustomAttrModificationHandler.h" +#import "LKS_AttrModificationPatchHandler.h" +#import "LKS_HierarchyDetailsHandler.h" +#import "LookinStaticAsyncUpdateTask.h" + +@interface LKS_RequestHandler () + +@property(nonatomic, strong) NSMutableSet *activeDetailHandlers; + +@end + +@implementation LKS_RequestHandler { + NSSet *_validRequestTypes; +} + +- (instancetype)init { + if (self = [super init]) { + _validRequestTypes = [NSSet setWithObjects:@(LookinRequestTypePing), + @(LookinRequestTypeApp), + @(LookinRequestTypeHierarchy), + @(LookinRequestTypeInbuiltAttrModification), + @(LookinRequestTypeCustomAttrModification), + @(LookinRequestTypeAttrModificationPatch), + @(LookinRequestTypeHierarchyDetails), + @(LookinRequestTypeFetchObject), + @(LookinRequestTypeAllAttrGroups), + @(LookinRequestTypeAllSelectorNames), + @(LookinRequestTypeInvokeMethod), + @(LookinRequestTypeFetchImageViewImage), + @(LookinRequestTypeModifyRecognizerEnable), + @(LookinPush_CanceHierarchyDetails), + nil]; + + self.activeDetailHandlers = [NSMutableSet set]; + } + return self; +} + +- (BOOL)canHandleRequestType:(uint32_t)requestType { + if ([_validRequestTypes containsObject:@(requestType)]) { + return YES; + } + return NO; +} + +- (void)handleRequestType:(uint32_t)requestType tag:(uint32_t)tag object:(id)object { + if (requestType == LookinRequestTypePing) { + LookinConnectionResponseAttachment *responseAttachment = [LookinConnectionResponseAttachment new]; + // 当 app 处于后台时,可能可以执行代码也可能不能执行代码,如果运气好了可以执行代码,则这里直接主动使用 appIsInBackground 标识 app 处于后台,不要让 Lookin 客户端傻傻地等待超时了 + if (![LKS_ConnectionManager sharedInstance].applicationIsActive) { + responseAttachment.appIsInBackground = YES; + } + [[LKS_ConnectionManager sharedInstance] respond:responseAttachment requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeApp) { + // 请求可用设备信息 + if (![object isKindOfClass:[NSDictionary class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + NSDictionary *params = object; + BOOL needImages = ((NSNumber *)params[@"needImages"]).boolValue; + NSArray *localIdentifiers = params[@"local"]; + + LookinAppInfo *appInfo = [LookinAppInfo currentInfoWithScreenshot:needImages icon:needImages localIdentifiers:localIdentifiers]; + + LookinConnectionResponseAttachment *responseAttachment = [LookinConnectionResponseAttachment new]; + responseAttachment.data = appInfo; + [[LKS_ConnectionManager sharedInstance] respond:responseAttachment requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeHierarchy) { + // 从 LookinClient 1.0.4 开始有这个参数,之前是 nil + NSString *clientVersion = nil; + if ([object isKindOfClass:[NSDictionary class]]) { + NSDictionary *params = object; + NSString *version = params[@"clientVersion"]; + if ([version isKindOfClass:[NSString class]]) { + clientVersion = version; + } + } + + LookinConnectionResponseAttachment *responseAttachment = [LookinConnectionResponseAttachment new]; + responseAttachment.data = [LookinHierarchyInfo staticInfoWithLookinVersion:clientVersion]; + [[LKS_ConnectionManager sharedInstance] respond:responseAttachment requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeInbuiltAttrModification) { + // 请求修改某个属性 + [LKS_InbuiltAttrModificationHandler handleModification:object completion:^(LookinDisplayItemDetail *data, NSError *error) { + LookinConnectionResponseAttachment *attachment = [LookinConnectionResponseAttachment new]; + if (error) { + attachment.error = error; + } else { + attachment.data = data; + } + [[LKS_ConnectionManager sharedInstance] respond:attachment requestType:requestType tag:tag]; + }]; + + } else if (requestType == LookinRequestTypeCustomAttrModification) { + BOOL succ = [LKS_CustomAttrModificationHandler handleModification:object]; + if (succ) { + [self _submitResponseWithData:nil requestType:requestType tag:tag]; + } else { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + } + + } else if (requestType == LookinRequestTypeAttrModificationPatch) { + NSArray *tasks = object; + NSUInteger dataTotalCount = tasks.count; + [LKS_InbuiltAttrModificationHandler handlePatchWithTasks:tasks block:^(LookinDisplayItemDetail *data) { + LookinConnectionResponseAttachment *attrAttachment = [LookinConnectionResponseAttachment new]; + attrAttachment.data = data; + attrAttachment.dataTotalCount = dataTotalCount; + attrAttachment.currentDataCount = 1; + [[LKS_ConnectionManager sharedInstance] respond:attrAttachment requestType:LookinRequestTypeAttrModificationPatch tag:tag]; + }]; + + } else if (requestType == LookinRequestTypeHierarchyDetails) { + NSArray *packages = object; + NSUInteger responsesDataTotalCount = [packages lookin_reduceInteger:^NSInteger(NSInteger accumulator, NSUInteger idx, LookinStaticAsyncUpdateTasksPackage *package) { + accumulator += package.tasks.count; + return accumulator; + } initialAccumlator:0]; + + LKS_HierarchyDetailsHandler *handler = [LKS_HierarchyDetailsHandler new]; + [self.activeDetailHandlers addObject:handler]; + + [handler startWithPackages:packages block:^(NSArray *details) { + LookinConnectionResponseAttachment *attachment = [LookinConnectionResponseAttachment new]; + attachment.data = details; + attachment.dataTotalCount = responsesDataTotalCount; + attachment.currentDataCount = details.count; + [[LKS_ConnectionManager sharedInstance] respond:attachment requestType:LookinRequestTypeHierarchyDetails tag:tag]; + + } finishedBlock:^{ + [self.activeDetailHandlers removeObject:handler]; + }]; + + } else if (requestType == LookinRequestTypeFetchObject) { + unsigned long oid = ((NSNumber *)object).unsignedLongValue; + NSObject *object = [NSObject lks_objectWithOid:oid]; + LookinObject *lookinObj = [LookinObject instanceWithObject:object]; + + LookinConnectionResponseAttachment *attach = [LookinConnectionResponseAttachment new]; + attach.data = lookinObj; + [[LKS_ConnectionManager sharedInstance] respond:attach requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeAllAttrGroups) { + unsigned long oid = ((NSNumber *)object).unsignedLongValue; + CALayer *layer = (CALayer *)[NSObject lks_objectWithOid:oid]; + if (![layer isKindOfClass:[CALayer class]]) { + [self _submitResponseWithError:LookinErr_ObjNotFound requestType:LookinRequestTypeAllAttrGroups tag:tag]; + return; + } + + NSArray *list = [LKS_AttrGroupsMaker attrGroupsForLayer:layer]; + [self _submitResponseWithData:list requestType:LookinRequestTypeAllAttrGroups tag:tag]; + + } else if (requestType == LookinRequestTypeAllSelectorNames) { + if (![object isKindOfClass:[NSDictionary class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + NSDictionary *params = object; + Class targetClass = NSClassFromString(params[@"className"]); + BOOL hasArg = [(NSNumber *)params[@"hasArg"] boolValue]; + if (!targetClass) { + NSString *errorMsg = [NSString stringWithFormat:LKS_Localized(@"Didn't find the class named \"%@\". Please input another class and try again."), object]; + [self _submitResponseWithError:LookinErrorMake(errorMsg, @"") requestType:requestType tag:tag]; + return; + } + + NSArray *selNames = [self _methodNameListForClass:targetClass hasArg:hasArg]; + [self _submitResponseWithData:selNames requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeInvokeMethod) { + if (![object isKindOfClass:[NSDictionary class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + NSDictionary *param = object; + unsigned long oid = [param[@"oid"] unsignedLongValue]; + NSString *text = param[@"text"]; + if (!text.length) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + NSObject *targerObj = [NSObject lks_objectWithOid:oid]; + if (!targerObj) { + [self _submitResponseWithError:LookinErr_ObjNotFound requestType:requestType tag:tag]; + return; + } + + SEL targetSelector = NSSelectorFromString(text); + if (targetSelector && [targerObj respondsToSelector:targetSelector]) { + NSString *resultDescription; + NSObject *resultObject; + NSError *error; + [self _handleInvokeWithObject:targerObj selector:targetSelector resultDescription:&resultDescription resultObject:&resultObject error:&error]; + if (error) { + [self _submitResponseWithError:error requestType:requestType tag:tag]; + return; + } + NSMutableDictionary *responseData = [NSMutableDictionary dictionaryWithCapacity:2]; + if (resultDescription) { + responseData[@"description"] = resultDescription; + } + if (resultObject) { + responseData[@"object"] = resultObject; + } + [self _submitResponseWithData:responseData requestType:requestType tag:tag]; + } else { + NSString *errMsg = [NSString stringWithFormat:LKS_Localized(@"%@ doesn't have an instance method called \"%@\"."), NSStringFromClass(targerObj.class), text]; + [self _submitResponseWithError:LookinErrorMake(errMsg, @"") requestType:requestType tag:tag]; + } + + } else if (requestType == LookinPush_CanceHierarchyDetails) { + [self.activeDetailHandlers enumerateObjectsUsingBlock:^(LKS_HierarchyDetailsHandler * _Nonnull handler, BOOL * _Nonnull stop) { + [handler cancel]; + }]; + [self.activeDetailHandlers removeAllObjects]; + + } else if (requestType == LookinRequestTypeFetchImageViewImage) { + if (![object isKindOfClass:[NSNumber class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + unsigned long imageViewOid = [(NSNumber *)object unsignedLongValue]; + UIImageView *imageView = (UIImageView *)[NSObject lks_objectWithOid:imageViewOid]; + if (!imageView) { + [self _submitResponseWithError:LookinErr_ObjNotFound requestType:requestType tag:tag]; + return; + } + if (![imageView isKindOfClass:[UIImageView class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + UIImage *image = imageView.image; + NSData *imageData = [image lookin_data]; + [self _submitResponseWithData:imageData requestType:requestType tag:tag]; + + } else if (requestType == LookinRequestTypeModifyRecognizerEnable) { + if (![object isKindOfClass:[NSDictionary class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + NSDictionary *params = object; + unsigned long recognizerOid = ((NSNumber *)params[@"oid"]).unsignedLongValue; + BOOL shouldBeEnabled = ((NSNumber *)params[@"enable"]).boolValue; + + UIGestureRecognizer *recognizer = (UIGestureRecognizer *)[NSObject lks_objectWithOid:recognizerOid]; + if (!recognizer) { + [self _submitResponseWithError:LookinErr_ObjNotFound requestType:requestType tag:tag]; + return; + } + if (![recognizer isKindOfClass:[UIGestureRecognizer class]]) { + [self _submitResponseWithError:LookinErr_Inner requestType:requestType tag:tag]; + return; + } + recognizer.enabled = shouldBeEnabled; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // dispatch 以确保拿到的 enabled 是比较新的 + [self _submitResponseWithData:@(recognizer.enabled) requestType:requestType tag:tag]; + }); + } +} + +- (NSArray *)_methodNameListForClass:(Class)aClass hasArg:(BOOL)hasArg { + NSSet *prefixesToVoid = [NSSet setWithObjects:@"_", @"CA_", @"cpl", @"mf_", @"vs_", @"pep_", @"isNS", @"avkit_", @"PG_", @"px_", @"pl_", @"nsli_", @"pu_", @"pxg_", nil]; + NSMutableArray *array = [NSMutableArray array]; + + Class currentClass = aClass; + while (currentClass) { + NSString *className = NSStringFromClass(currentClass); + BOOL isSystemClass = ([className hasPrefix:@"UI"] || [className hasPrefix:@"CA"] || [className hasPrefix:@"NS"]); + + unsigned int methodCount = 0; + Method *methods = class_copyMethodList(currentClass, &methodCount); + for (unsigned int i = 0; i < methodCount; i++) { + NSString *selName = NSStringFromSelector(method_getName(methods[i])); + + if (!hasArg && [selName containsString:@":"]) { + continue; + } + + if (isSystemClass) { + BOOL invalid = [prefixesToVoid lookin_any:^BOOL(NSString *prefix) { + return [selName hasPrefix:prefix]; + }]; + if (invalid) { + continue; + } + } + if (selName.length && ![array containsObject:selName]) { + [array addObject:selName]; + } + } + if (methods) free(methods); + currentClass = [currentClass superclass]; + } + + return [array lookin_sortedArrayByStringLength]; +} + +- (void)_handleInvokeWithObject:(NSObject *)obj selector:(SEL)selector resultDescription:(NSString **)description resultObject:(LookinObject **)resultObject error:(NSError **)error { + NSMethodSignature *signature = [obj methodSignatureForSelector:selector]; + if (signature.numberOfArguments > 2) { + *error = LookinErrorMake(LKS_Localized(@"Lookin doesn't support invoking methods with arguments yet."), @""); + return; + } + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:obj]; + [invocation setSelector:selector]; + [invocation invoke]; + + const char *returnType = [signature methodReturnType]; + + + if (strcmp(returnType, @encode(void)) == 0) { + //void, do nothing + *description = LookinStringFlag_VoidReturn; + + } else if (strcmp(returnType, @encode(char)) == 0) { + char charValue; + [invocation getReturnValue:&charValue]; + *description = [NSString stringWithFormat:@"%@", @(charValue)]; + + } else if (strcmp(returnType, @encode(int)) == 0) { + int intValue; + [invocation getReturnValue:&intValue]; + if (intValue == INT_MAX) { + *description = @"INT_MAX"; + } else if (intValue == INT_MIN) { + *description = @"INT_MIN"; + } else { + *description = [NSString stringWithFormat:@"%@", @(intValue)]; + } + + } else if (strcmp(returnType, @encode(short)) == 0) { + short shortValue; + [invocation getReturnValue:&shortValue]; + if (shortValue == SHRT_MAX) { + *description = @"SHRT_MAX"; + } else if (shortValue == SHRT_MIN) { + *description = @"SHRT_MIN"; + } else { + *description = [NSString stringWithFormat:@"%@", @(shortValue)]; + } + + } else if (strcmp(returnType, @encode(long)) == 0) { + long longValue; + [invocation getReturnValue:&longValue]; + if (longValue == NSNotFound) { + *description = @"NSNotFound"; + } else if (longValue == LONG_MAX) { + *description = @"LONG_MAX"; + } else if (longValue == LONG_MIN) { + *description = @"LONG_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(longValue)]; + } + + } else if (strcmp(returnType, @encode(long long)) == 0) { + long long longLongValue; + [invocation getReturnValue:&longLongValue]; + if (longLongValue == LLONG_MAX) { + *description = @"LLONG_MAX"; + } else if (longLongValue == LLONG_MIN) { + *description = @"LLONG_MIN"; + } else { + *description = [NSString stringWithFormat:@"%@", @(longLongValue)]; + } + + } else if (strcmp(returnType, @encode(unsigned char)) == 0) { + unsigned char ucharValue; + [invocation getReturnValue:&ucharValue]; + if (ucharValue == UCHAR_MAX) { + *description = @"UCHAR_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(ucharValue)]; + } + + } else if (strcmp(returnType, @encode(unsigned int)) == 0) { + unsigned int uintValue; + [invocation getReturnValue:&uintValue]; + if (uintValue == UINT_MAX) { + *description = @"UINT_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(uintValue)]; + } + + } else if (strcmp(returnType, @encode(unsigned short)) == 0) { + unsigned short ushortValue; + [invocation getReturnValue:&ushortValue]; + if (ushortValue == USHRT_MAX) { + *description = @"USHRT_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(ushortValue)]; + } + + } else if (strcmp(returnType, @encode(unsigned long)) == 0) { + unsigned long ulongValue; + [invocation getReturnValue:&ulongValue]; + if (ulongValue == ULONG_MAX) { + *description = @"ULONG_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(ulongValue)]; + } + + } else if (strcmp(returnType, @encode(unsigned long long)) == 0) { + unsigned long long ulongLongValue; + [invocation getReturnValue:&ulongLongValue]; + if (ulongLongValue == ULONG_LONG_MAX) { + *description = @"ULONG_LONG_MAX"; + } else { + *description = [NSString stringWithFormat:@"%@", @(ulongLongValue)]; + } + + } else if (strcmp(returnType, @encode(float)) == 0) { + float floatValue; + [invocation getReturnValue:&floatValue]; + if (floatValue == FLT_MAX) { + *description = @"FLT_MAX"; + } else if (floatValue == FLT_MIN) { + *description = @"FLT_MIN"; + } else { + *description = [NSString stringWithFormat:@"%@", @(floatValue)]; + } + + } else if (strcmp(returnType, @encode(double)) == 0) { + double doubleValue; + [invocation getReturnValue:&doubleValue]; + if (doubleValue == DBL_MAX) { + *description = @"DBL_MAX"; + } else if (doubleValue == DBL_MIN) { + *description = @"DBL_MIN"; + } else { + *description = [NSString stringWithFormat:@"%@", @(doubleValue)]; + } + + } else if (strcmp(returnType, @encode(BOOL)) == 0) { + BOOL boolValue; + [invocation getReturnValue:&boolValue]; + *description = boolValue ? @"YES" : @"NO"; + + } else if (strcmp(returnType, @encode(SEL)) == 0) { + SEL selValue; + [invocation getReturnValue:&selValue]; + *description = [NSString stringWithFormat:@"SEL(%@)", NSStringFromSelector(selValue)]; + + } else if (strcmp(returnType, @encode(Class)) == 0) { + Class classValue; + [invocation getReturnValue:&classValue]; + *description = [NSString stringWithFormat:@"<%@>", NSStringFromClass(classValue)]; + + } else if (strcmp(returnType, @encode(CGPoint)) == 0) { + CGPoint targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromCGPoint(targetValue); + + } else if (strcmp(returnType, @encode(CGVector)) == 0) { + CGVector targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromCGVector(targetValue); + + } else if (strcmp(returnType, @encode(CGSize)) == 0) { + CGSize targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromCGSize(targetValue); + + } else if (strcmp(returnType, @encode(CGRect)) == 0) { + CGRect rectValue; + [invocation getReturnValue:&rectValue]; + *description = NSStringFromCGRect(rectValue); + + } else if (strcmp(returnType, @encode(CGAffineTransform)) == 0) { + CGAffineTransform rectValue; + [invocation getReturnValue:&rectValue]; + *description = NSStringFromCGAffineTransform(rectValue); + + } else if (strcmp(returnType, @encode(UIEdgeInsets)) == 0) { + UIEdgeInsets targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromUIEdgeInsets(targetValue); + + } else if (strcmp(returnType, @encode(UIOffset)) == 0) { + UIOffset targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromUIOffset(targetValue); + + } else { + if (@available(iOS 11.0, tvOS 11.0, *)) { + if (strcmp(returnType, @encode(NSDirectionalEdgeInsets)) == 0) { + NSDirectionalEdgeInsets targetValue; + [invocation getReturnValue:&targetValue]; + *description = NSStringFromDirectionalEdgeInsets(targetValue); + return; + } + } + + NSString *argType_string = [[NSString alloc] lookin_safeInitWithUTF8String:returnType]; + if ([argType_string hasPrefix:@"@"] || [argType_string hasPrefix:@"^{"]) { + __unsafe_unretained id returnObjValue; + [invocation getReturnValue:&returnObjValue]; + + if (returnObjValue) { + *description = [NSString stringWithFormat:@"%@", returnObjValue]; + + LookinObject *parsedLookinObj = [LookinObject instanceWithObject:returnObjValue]; + *resultObject = parsedLookinObj; + } else { + *description = @"nil"; + } + } else { + *description = [NSString stringWithFormat:LKS_Localized(@"%@ was invoked successfully, but Lookin can't parse the return value:%@"), NSStringFromSelector(selector), argType_string]; + } + } +} + +- (void)_submitResponseWithError:(NSError *)error requestType:(uint32_t)requestType tag:(uint32_t)tag { + LookinConnectionResponseAttachment *attachment = [LookinConnectionResponseAttachment new]; + attachment.error = error; + [[LKS_ConnectionManager sharedInstance] respond:attachment requestType:requestType tag:tag]; +} + +- (void)_submitResponseWithData:(NSObject *)data requestType:(uint32_t)requestType tag:(uint32_t)tag { + LookinConnectionResponseAttachment *attachment = [LookinConnectionResponseAttachment new]; + attachment.data = data; + [[LKS_ConnectionManager sharedInstance] respond:attachment requestType:requestType tag:tag]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h new file mode 100644 index 00000000..d1b621b8 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h @@ -0,0 +1,26 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_AttrModificationPatchHandler.h +// LookinServer +// +// Created by Li Kai on 2019/6/12. +// https://lookin.work +// + +#import + +@class LookinDisplayItemDetail; + +@interface LKS_AttrModificationPatchHandler : NSObject + +/** + @param oids 数组内 idx 较小的应该为 displayItems 里的 subItem,idx 较大的应该为 superItem + @param lowImageQuality 是否采用低图像质量 + @param block 该 block 会被多次调用,其中 tasksTotalCount 是总的调用次数(即可被用来作为 TotalResponseCount) + */ ++ (void)handleLayerOids:(NSArray *)oids lowImageQuality:(BOOL)lowImageQuality block:(void (^)(LookinDisplayItemDetail *detail, NSUInteger tasksTotalCount, NSError *error))block; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.m b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.m new file mode 100644 index 00000000..bc1cbcd2 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.m @@ -0,0 +1,51 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_AttrModificationPatchHandler.m +// LookinServer +// +// Created by Li Kai on 2019/6/12. +// https://lookin.work +// + +#import "LKS_AttrModificationPatchHandler.h" +#import "LookinDisplayItemDetail.h" +#import "LookinServerDefines.h" + +@implementation LKS_AttrModificationPatchHandler + ++ (void)handleLayerOids:(NSArray *)oids lowImageQuality:(BOOL)lowImageQuality block:(void (^)(LookinDisplayItemDetail *detail, NSUInteger tasksTotalCount, NSError *error))block { + if (!block) { + NSAssert(NO, @""); + return; + } + if (![oids isKindOfClass:[NSArray class]]) { + block(nil, 1, LookinErr_Inner); + return; + } + + [oids enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + unsigned long oid = [obj unsignedLongValue]; + LookinDisplayItemDetail *detail = [LookinDisplayItemDetail new]; + detail.displayItemOid = oid; + + CALayer *layer = (CALayer *)[NSObject lks_objectWithOid:oid]; + if (![layer isKindOfClass:[CALayer class]]) { + block(nil, idx + 1, LookinErr_ObjNotFound); + *stop = YES; + return; + } + + if (idx == 0) { + detail.soloScreenshot = [layer lks_soloScreenshotWithLowQuality:lowImageQuality]; + detail.groupScreenshot = [layer lks_groupScreenshotWithLowQuality:lowImageQuality]; + } else { + detail.groupScreenshot = [layer lks_groupScreenshotWithLowQuality:lowImageQuality]; + } + block(detail, oids.count, nil); + }]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h new file mode 100644 index 00000000..a35c899a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h @@ -0,0 +1,19 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrModificationHandler.h +// LookinServer +// +// Created by likaimacbookhome on 2023/11/4. +// + +#import +#import "LookinCustomAttrModification.h" + +@interface LKS_CustomAttrModificationHandler : NSObject + +/// 返回值表示是否修改成功(有成功调用 setter block 就算成功) ++ (BOOL)handleModification:(LookinCustomAttrModification *)modification; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.m b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.m new file mode 100644 index 00000000..1935ef52 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.m @@ -0,0 +1,155 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrModificationHandler.m +// LookinServer +// +// Created by likaimacbookhome on 2023/11/4. +// + +#import "LKS_CustomAttrModificationHandler.h" +#import "LKS_CustomAttrSetterManager.h" +#import "UIColor+LookinServer.h" + +@implementation LKS_CustomAttrModificationHandler + ++ (BOOL)handleModification:(LookinCustomAttrModification *)modification { + if (!modification || modification.customSetterID.length == 0) { + return NO; + } + switch (modification.attrType) { + case LookinAttrTypeNSString: { + NSString *newValue = modification.value; + if (newValue != nil && ![newValue isKindOfClass:[NSString class]]) { + // nil 是合法的 + return NO; + } + LKS_StringSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getStringSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue); + return YES; + } + + case LookinAttrTypeDouble: { + NSNumber *newValue = modification.value; + if (![newValue isKindOfClass:[NSNumber class]]) { + return NO; + } + LKS_NumberSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getNumberSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue); + return YES; + } + + case LookinAttrTypeBOOL: { + NSNumber *newValue = modification.value; + if (![newValue isKindOfClass:[NSNumber class]]) { + return NO; + } + LKS_BoolSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getBoolSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue.boolValue); + return YES; + } + + case LookinAttrTypeUIColor: { + LKS_ColorSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getColorSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + + NSArray *newValue = modification.value; + if (newValue == nil) { + // nil 是合法的 + setter(nil); + return YES; + } + if (![newValue isKindOfClass:[NSArray class]]) { + return NO; + } + UIColor *color = [UIColor lks_colorFromRGBAComponents:newValue]; + if (!color) { + return NO; + } + setter(color); + return YES; + } + + case LookinAttrTypeEnumString: { + NSString *newValue = modification.value; + if (![newValue isKindOfClass:[NSString class]]) { + return NO; + } + LKS_EnumSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getEnumSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue); + return YES; + } + + case LookinAttrTypeCGRect: { + NSValue *newValue = modification.value; + if (![newValue isKindOfClass:[NSValue class]]) { + return NO; + } + LKS_RectSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getRectSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue.CGRectValue); + return YES; + } + + case LookinAttrTypeCGSize: { + NSValue *newValue = modification.value; + if (![newValue isKindOfClass:[NSValue class]]) { + return NO; + } + LKS_SizeSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getSizeSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue.CGSizeValue); + return YES; + } + + case LookinAttrTypeCGPoint: { + NSValue *newValue = modification.value; + if (![newValue isKindOfClass:[NSValue class]]) { + return NO; + } + LKS_PointSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getPointSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue.CGPointValue); + return YES; + } + + case LookinAttrTypeUIEdgeInsets: { + NSValue *newValue = modification.value; + if (![newValue isKindOfClass:[NSValue class]]) { + return NO; + } + LKS_InsetsSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getInsetsSetterWithID:modification.customSetterID]; + if (!setter) { + return NO; + } + setter(newValue.UIEdgeInsetsValue); + return YES; + } + + default: + return NO; + } +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h new file mode 100644 index 00000000..0f2c56fb --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h @@ -0,0 +1,30 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_HierarchyDetailsHandler.h +// LookinServer +// +// Created by Li Kai on 2019/6/20. +// https://lookin.work +// + +#import + +@class LookinDisplayItemDetail, LookinStaticAsyncUpdateTasksPackage; + +typedef void (^LKS_HierarchyDetailsHandler_ProgressBlock)(NSArray *details); +typedef void (^LKS_HierarchyDetailsHandler_FinishBlock)(void); + +@interface LKS_HierarchyDetailsHandler : NSObject + +/// packages 会按照 idx 从小到大的顺序被执行 +/// 全部任务完成时,finishBlock 会被调用 +/// 如果调用了 cancel,则 finishBlock 不会被执行 +- (void)startWithPackages:(NSArray *)packages block:(LKS_HierarchyDetailsHandler_ProgressBlock)progressBlock finishedBlock:(LKS_HierarchyDetailsHandler_FinishBlock)finishBlock; + +/// 取消所有任务 +- (void)cancel; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.m b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.m new file mode 100644 index 00000000..28999f9f --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.m @@ -0,0 +1,148 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_HierarchyDetailsHandler.m +// LookinServer +// +// Created by Li Kai on 2019/6/20. +// https://lookin.work +// + +#import "LKS_HierarchyDetailsHandler.h" +#import "LookinDisplayItemDetail.h" +#import "LKS_AttrGroupsMaker.h" +#import "LookinStaticAsyncUpdateTask.h" +#import "LKS_ConnectionManager.h" +#import "LookinServerDefines.h" +#import "LKS_CustomAttrGroupsMaker.h" +#import "LKS_HierarchyDisplayItemsMaker.h" + +@interface LKS_HierarchyDetailsHandler () + +@property(nonatomic, strong) NSMutableArray *taskPackages; +/// 标识哪些 oid 已经拉取过 attrGroups 了 +@property(nonatomic, strong) NSMutableSet *attrGroupsSyncedOids; + +@property(nonatomic, copy) LKS_HierarchyDetailsHandler_ProgressBlock progressBlock; +@property(nonatomic, copy) LKS_HierarchyDetailsHandler_FinishBlock finishBlock; + +@end + +@implementation LKS_HierarchyDetailsHandler + +- (instancetype)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleConnectionDidEnd:) name:LKS_ConnectionDidEndNotificationName object:nil]; + + self.attrGroupsSyncedOids = [NSMutableSet set]; + } + return self; +} + +- (void)startWithPackages:(NSArray *)packages block:(LKS_HierarchyDetailsHandler_ProgressBlock)progressBlock finishedBlock:(LKS_HierarchyDetailsHandler_FinishBlock)finishBlock { + if (!progressBlock || !finishBlock) { + NSAssert(NO, @""); + return; + } + if (!packages.count) { + finishBlock(); + return; + } + self.taskPackages = [packages mutableCopy]; + self.progressBlock = progressBlock; + self.finishBlock = finishBlock; + + [UIView lks_rebuildGlobalInvolvedRawConstraints]; + + [self _dequeueAndHandlePackage]; +} + +- (void)cancel { + [self.taskPackages removeAllObjects]; +} + +- (void)_dequeueAndHandlePackage { + dispatch_async(dispatch_get_main_queue(), ^{ + LookinStaticAsyncUpdateTasksPackage *package = self.taskPackages.firstObject; + if (!package) { + self.finishBlock(); + return; + } + // NSLog(@"LookinServer - will handle tasks, count: %@", @(tasks.count)); + NSArray *details = [package.tasks lookin_map:^id(NSUInteger idx, LookinStaticAsyncUpdateTask *task) { + LookinDisplayItemDetail *itemDetail = [LookinDisplayItemDetail new]; + itemDetail.displayItemOid = task.oid; + + id object = [NSObject lks_objectWithOid:task.oid]; + if (!object || ![object isKindOfClass:[CALayer class]]) { + itemDetail.failureCode = -1; + return itemDetail; + } + + CALayer *layer = object; + + if (task.taskType == LookinStaticAsyncUpdateTaskTypeSoloScreenshot) { + UIImage *image = [layer lks_soloScreenshotWithLowQuality:NO]; + itemDetail.soloScreenshot = image; + } else if (task.taskType == LookinStaticAsyncUpdateTaskTypeGroupScreenshot) { + UIImage *image = [layer lks_groupScreenshotWithLowQuality:NO]; + itemDetail.groupScreenshot = image; + } + + BOOL shouldMakeAttr = [self queryIfShouldMakeAttrsFromTask:task]; + if (shouldMakeAttr) { + itemDetail.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer]; + + NSString *version = task.clientReadableVersion; + if (version.length > 0 && [version lookin_numbericOSVersion] >= 10004) { + LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer]; + [maker execute]; + itemDetail.customAttrGroupList = [maker getGroups]; + itemDetail.customDisplayTitle = [maker getCustomDisplayTitle]; + itemDetail.danceUISource = [maker getDanceUISource]; + } + [self.attrGroupsSyncedOids addObject:@(task.oid)]; + } + + if (task.needBasisVisualInfo) { + itemDetail.frameValue = [NSValue valueWithCGRect:layer.frame]; + itemDetail.boundsValue = [NSValue valueWithCGRect:layer.bounds]; + itemDetail.hiddenValue = [NSNumber numberWithBool:layer.isHidden]; + itemDetail.alphaValue = @(layer.opacity); + } + + if (task.needSubitems) { + itemDetail.subitems = [LKS_HierarchyDisplayItemsMaker subitemsOfLayer:layer]; + } + + return itemDetail; + }]; + self.progressBlock(details); + + [self.taskPackages removeObjectAtIndex:0]; + [self _dequeueAndHandlePackage]; + }); +} + +- (BOOL)queryIfShouldMakeAttrsFromTask:(LookinStaticAsyncUpdateTask *)task { + switch (task.attrRequest) { + case LookinDetailUpdateTaskAttrRequest_Automatic: { + BOOL alreadyMadeBefore = [self.attrGroupsSyncedOids containsObject:@(task.oid)]; + return !alreadyMadeBefore; + } + case LookinDetailUpdateTaskAttrRequest_Need: + return YES; + case LookinDetailUpdateTaskAttrRequest_NotNeed: + return NO; + } + NSAssert(NO, @""); + return YES; +} + +- (void)_handleConnectionDidEnd:(id)obj { + [self cancel]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h new file mode 100644 index 00000000..481b4660 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h @@ -0,0 +1,23 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_InbuiltAttrModificationHandler.h +// LookinServer +// +// Created by Li Kai on 2019/6/12. +// https://lookin.work +// + +#import + +@class LookinAttributeModification, LookinDisplayItemDetail, LookinStaticAsyncUpdateTask; + +@interface LKS_InbuiltAttrModificationHandler : NSObject + ++ (void)handleModification:(LookinAttributeModification *)modification completion:(void (^)(LookinDisplayItemDetail *data, NSError *error))completion; + ++ (void)handlePatchWithTasks:(NSArray *)tasks block:(void (^)(LookinDisplayItemDetail *data))block; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.m b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.m new file mode 100644 index 00000000..79116099 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.m @@ -0,0 +1,255 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_InbuiltAttrModificationHandler.m +// LookinServer +// +// Created by Li Kai on 2019/6/12. +// https://lookin.work +// + +#import "LKS_InbuiltAttrModificationHandler.h" +#import "UIColor+LookinServer.h" +#import "LookinAttributeModification.h" +#import "LKS_AttrGroupsMaker.h" +#import "LookinDisplayItemDetail.h" +#import "LookinStaticAsyncUpdateTask.h" +#import "LookinServerDefines.h" +#import "LKS_CustomAttrGroupsMaker.h" + +@implementation LKS_InbuiltAttrModificationHandler + ++ (void)handleModification:(LookinAttributeModification *)modification completion:(void (^)(LookinDisplayItemDetail *data, NSError *error))completion { + if (!completion) { + NSAssert(NO, @""); + return; + } + if (!modification || ![modification isKindOfClass:[LookinAttributeModification class]]) { + completion(nil, LookinErr_Inner); + return; + } + + NSObject *receiver = [NSObject lks_objectWithOid:modification.targetOid]; + if (!receiver) { + completion(nil, LookinErr_ObjNotFound); + return; + } + + NSMethodSignature *setterSignature = [receiver methodSignatureForSelector:modification.setterSelector]; + NSInvocation *setterInvocation = [NSInvocation invocationWithMethodSignature:setterSignature]; + setterInvocation.target = receiver; + setterInvocation.selector = modification.setterSelector; + + if (setterSignature.numberOfArguments != 3 || ![receiver respondsToSelector:modification.setterSelector]) { + completion(nil, LookinErr_Inner); + return; + } + + switch (modification.attrType) { + case LookinAttrTypeNone: + case LookinAttrTypeVoid: { + completion(nil, LookinErr_Inner); + return; + } + case LookinAttrTypeChar: { + char expectedValue = [(NSNumber *)modification.value charValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeInt: + case LookinAttrTypeEnumInt: { + int expectedValue = [(NSNumber *)modification.value intValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeShort: { + short expectedValue = [(NSNumber *)modification.value shortValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeLong: + case LookinAttrTypeEnumLong: { + long expectedValue = [(NSNumber *)modification.value longValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeLongLong: { + long long expectedValue = [(NSNumber *)modification.value longLongValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUnsignedChar: { + unsigned char expectedValue = [(NSNumber *)modification.value unsignedCharValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUnsignedInt: { + unsigned int expectedValue = [(NSNumber *)modification.value unsignedIntValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUnsignedShort: { + unsigned short expectedValue = [(NSNumber *)modification.value unsignedShortValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUnsignedLong: { + unsigned long expectedValue = [(NSNumber *)modification.value unsignedLongValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUnsignedLongLong: { + unsigned long long expectedValue = [(NSNumber *)modification.value unsignedLongLongValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeFloat: { + float expectedValue = [(NSNumber *)modification.value floatValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeDouble: { + double expectedValue = [(NSNumber *)modification.value doubleValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeBOOL: { + BOOL expectedValue = [(NSNumber *)modification.value boolValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeSel: { + SEL expectedValue = NSSelectorFromString(modification.value); + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeClass: { + Class expectedValue = NSClassFromString(modification.value); + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCGPoint: { + CGPoint expectedValue = [(NSValue *)modification.value CGPointValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCGVector: { + CGVector expectedValue = [(NSValue *)modification.value CGVectorValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCGSize: { + CGSize expectedValue = [(NSValue *)modification.value CGSizeValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCGRect: { + CGRect expectedValue = [(NSValue *)modification.value CGRectValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCGAffineTransform: { + CGAffineTransform expectedValue = [(NSValue *)modification.value CGAffineTransformValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUIEdgeInsets: { + UIEdgeInsets expectedValue = [(NSValue *)modification.value UIEdgeInsetsValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeUIOffset: { + UIOffset expectedValue = [(NSValue *)modification.value UIOffsetValue]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + break; + } + case LookinAttrTypeCustomObj: + case LookinAttrTypeNSString: { + NSObject *expectedValue = modification.value; + [setterInvocation setArgument:&expectedValue atIndex:2]; + [setterInvocation retainArguments]; + break; + } + case LookinAttrTypeUIColor: { + NSArray *rgba = modification.value; + UIColor *expectedValue = [UIColor lks_colorFromRGBAComponents:rgba]; + [setterInvocation setArgument:&expectedValue atIndex:2]; + [setterInvocation retainArguments]; + break; + } + default: { + completion(nil, LookinErr_Inner); + return; + } + } + + NSError *error = nil; + @try { + [setterInvocation invoke]; + } @catch (NSException *exception) { + NSString *errorMsg = [NSString stringWithFormat:LKS_Localized(@"<%@: %p>: an exception was raised when invoking %@. (%@)"), NSStringFromClass(receiver.class), receiver, NSStringFromSelector(modification.setterSelector), exception.reason]; + error = [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_Exception userInfo:@{NSLocalizedDescriptionKey:LKS_Localized(@"The modification may failed."), NSLocalizedRecoverySuggestionErrorKey:errorMsg}]; + } @finally { + + } + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + CALayer *layer = nil; + if ([receiver isKindOfClass:[CALayer class]]) { + layer = (CALayer *)receiver; + } else if ([receiver isKindOfClass:[UIView class]]) { + layer = ((UIView *)receiver).layer; + } else { + completion(nil, LookinErr_ObjNotFound); + return; + } + // 比如试图更改 frame 时,这个改动很有可能触发用户业务的 relayout,因此这时 dispatch 一下以确保拿到的 attrGroups 数据是最新的 + LookinDisplayItemDetail *detail = [LookinDisplayItemDetail new]; + detail.displayItemOid = modification.targetOid; + detail.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer]; + + NSString *version = modification.clientReadableVersion; + if (version.length > 0 && [version lookin_numbericOSVersion] >= 10004) { + LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer]; + [maker execute]; + detail.customAttrGroupList = [maker getGroups]; + } + + detail.frameValue = [NSValue valueWithCGRect:layer.frame]; + detail.boundsValue = [NSValue valueWithCGRect:layer.bounds]; + detail.hiddenValue = [NSNumber numberWithBool:layer.isHidden]; + detail.alphaValue = @(layer.opacity); + completion(detail, error); + }); +} + + ++ (void)handlePatchWithTasks:(NSArray *)tasks block:(void (^)(LookinDisplayItemDetail *data))block { + if (!block) { + NSAssert(NO, @""); + return; + } + [tasks enumerateObjectsUsingBlock:^(LookinStaticAsyncUpdateTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) { + LookinDisplayItemDetail *itemDetail = [LookinDisplayItemDetail new]; + itemDetail.displayItemOid = task.oid; + id object = [NSObject lks_objectWithOid:task.oid]; + if (!object || ![object isKindOfClass:[CALayer class]]) { + block(itemDetail); + return; + } + + CALayer *layer = object; + if (task.taskType == LookinStaticAsyncUpdateTaskTypeSoloScreenshot) { + UIImage *image = [layer lks_soloScreenshotWithLowQuality:NO]; + itemDetail.soloScreenshot = image; + } else if (task.taskType == LookinStaticAsyncUpdateTaskTypeGroupScreenshot) { + UIImage *image = [layer lks_groupScreenshotWithLowQuality:NO]; + itemDetail.groupScreenshot = image; + } + block(itemDetail); + }]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/LookinServer.h b/Pods/LookinServer/Src/Main/Server/LookinServer.h new file mode 100644 index 00000000..408b431a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/LookinServer.h @@ -0,0 +1,17 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinServer.h +// LookinServer +// +// Created by Li Kai on 2019/7/20. +// https://lookin.work +// + +#ifndef LookinServer_h +#define LookinServer_h + + +#endif /* LookinServer_h */ + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.h b/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.h new file mode 100644 index 00000000..1eecebee --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.h @@ -0,0 +1,26 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKSConfigManager.h +// LookinServer +// +// Created by likai.123 on 2023/1/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface LKSConfigManager : NSObject + ++ (NSArray *)collapsedClassList; + ++ (NSDictionary *)colorAlias; + ++ (BOOL)shouldCaptureScreenshotOfLayer:(CALayer *)layer; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.m b/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.m new file mode 100644 index 00000000..830866ad --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKSConfigManager.m @@ -0,0 +1,195 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKSConfigManager.m +// LookinServer +// +// Created by likai.123 on 2023/1/10. +// + +#import "LKSConfigManager.h" +#import "NSArray+Lookin.h" +#import "CALayer+LookinServer.h" + +@implementation LKSConfigManager + ++ (NSArray *)collapsedClassList { + NSArray *result = [self queryCollapsedClassListWithClass:[NSObject class] selector:@"lookin_collapsedClassList"]; + if (result) { + return result; + } + + // Legacy logic. Deprecated. + Class configClass = NSClassFromString(@"LookinConfig"); + if (!configClass) { + return nil; + } + NSArray *legacyCodeResult = [self queryCollapsedClassListWithClass:configClass selector:@"collapsedClasses"]; + return legacyCodeResult; +} + ++ (NSArray *)queryCollapsedClassListWithClass:(Class)class selector:(NSString *)selectorName { + SEL selector = NSSelectorFromString(selectorName); + if (![class respondsToSelector:selector]) { + return nil; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[class methodSignatureForSelector:selector]]; + [invocation setTarget:class]; + [invocation setSelector:selector]; + [invocation invoke]; + void *arrayValue; + [invocation getReturnValue:&arrayValue]; + id classList = (__bridge id)(arrayValue); + + if ([classList isKindOfClass:[NSArray class]]) { + NSArray *validClassList = [((NSArray *)classList) lookin_filter:^BOOL(id obj) { + return [obj isKindOfClass:[NSString class]]; + }]; + return [validClassList copy]; + } + return nil; +} + ++ (NSDictionary *)colorAlias { + NSDictionary *result = [self queryColorAliasWithClass:[NSObject class] selector:@"lookin_colorAlias"]; + if (result) { + return result; + } + + // Legacy logic. Deprecated. + Class configClass = NSClassFromString(@"LookinConfig"); + if (!configClass) { + return nil; + } + NSDictionary *legacyCodeResult = [self queryColorAliasWithClass:configClass selector:@"colors"]; + return legacyCodeResult; +} + ++ (NSDictionary *)queryColorAliasWithClass:(Class)class selector:(NSString *)selectorName { + SEL selector = NSSelectorFromString(selectorName); + if (![class respondsToSelector:selector]) { + return nil; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[class methodSignatureForSelector:selector]]; + [invocation setTarget:class]; + [invocation setSelector:selector]; + [invocation invoke]; + void *dictValue; + [invocation getReturnValue:&dictValue]; + id colorAlias = (__bridge id)(dictValue); + + if ([colorAlias isKindOfClass:[NSDictionary class]]) { + NSMutableDictionary *validDictionary = [NSMutableDictionary dictionary]; + [(NSDictionary *)colorAlias enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + if ([key isKindOfClass:[NSString class]]) { + if ([obj isKindOfClass:[UIColor class]]) { + [validDictionary setObject:obj forKey:key]; + + } else if ([obj isKindOfClass:[NSDictionary class]]) { + __block BOOL isValidSubDict = YES; + [((NSDictionary *)obj) enumerateKeysAndObjectsUsingBlock:^(id _Nonnull subKey, id _Nonnull subObj, BOOL * _Nonnull stop) { + if (![subKey isKindOfClass:[NSString class]] || ![subObj isKindOfClass:[UIColor class]]) { + isValidSubDict = NO; + *stop = YES; + } + }]; + if (isValidSubDict) { + [validDictionary setObject:obj forKey:key]; + } + } + } + }]; + return [validDictionary copy]; + } + return nil; +} + ++ (BOOL)shouldCaptureScreenshotOfLayer:(CALayer *)layer { + if (!layer) { + return YES; + } + if (![self shouldCaptureImageOfLayer:layer]) { + return NO; + } + UIView *view = layer.lks_hostView; + if (!view) { + return YES; + } + if (![self shouldCaptureImageOfView:view]) { + return NO; + } + return YES; +} + ++ (BOOL)shouldCaptureImageOfLayer:(CALayer *)layer { + if (!layer) { + return YES; + } + SEL selector = NSSelectorFromString(@"lookin_shouldCaptureImageOfLayer:"); + if ([NSObject respondsToSelector:selector]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSObject methodSignatureForSelector:selector]]; + [invocation setTarget:[NSObject class]]; + [invocation setSelector:selector]; + [invocation setArgument:&layer atIndex:2]; + [invocation invoke]; + BOOL resultValue = YES; + [invocation getReturnValue:&resultValue]; + if (!resultValue) { + return NO; + } + } + + SEL selector2 = NSSelectorFromString(@"lookin_shouldCaptureImage"); + if ([layer respondsToSelector:selector2]) { + NSInvocation *invocation2 = [NSInvocation invocationWithMethodSignature:[layer methodSignatureForSelector:selector2]]; + [invocation2 setTarget:layer]; + [invocation2 setSelector:selector2]; + [invocation2 invoke]; + BOOL resultValue2 = YES; + [invocation2 getReturnValue:&resultValue2]; + if (!resultValue2) { + return NO; + } + } + + return YES; +} + ++ (BOOL)shouldCaptureImageOfView:(UIView *)view { + if (!view) { + return YES; + } + + SEL selector = NSSelectorFromString(@"lookin_shouldCaptureImageOfView:"); + if ([NSObject respondsToSelector:selector]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSObject methodSignatureForSelector:selector]]; + [invocation setTarget:[NSObject class]]; + [invocation setSelector:selector]; + [invocation setArgument:&view atIndex:2]; + [invocation invoke]; + BOOL resultValue = YES; + [invocation getReturnValue:&resultValue]; + if (!resultValue) { + return NO; + } + } + + SEL selector2 = NSSelectorFromString(@"lookin_shouldCaptureImage"); + if ([view respondsToSelector:selector2]) { + NSInvocation *invocation2 = [NSInvocation invocationWithMethodSignature:[view methodSignatureForSelector:selector2]]; + [invocation2 setTarget:view]; + [invocation2 setSelector:selector2]; + [invocation2 invoke]; + BOOL resultValue2 = YES; + [invocation2 getReturnValue:&resultValue2]; + if (!resultValue2) { + return NO; + } + } + + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.h new file mode 100644 index 00000000..1902da20 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_AttrGroupsMaker.h +// LookinServer +// +// Created by Li Kai on 2019/6/6. +// https://lookin.work +// + +#import "LookinDefines.h" + +@class LookinAttributesGroup; + +@interface LKS_AttrGroupsMaker : NSObject + ++ (NSArray *)attrGroupsForLayer:(CALayer *)layer; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.m new file mode 100644 index 00000000..c140f21d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_AttrGroupsMaker.m @@ -0,0 +1,302 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_AttrGroupsMaker.m +// LookinServer +// +// Created by Li Kai on 2019/6/6. +// https://lookin.work +// + +#import "LKS_AttrGroupsMaker.h" +#import "LookinAttributesGroup.h" +#import "LookinAttributesSection.h" +#import "LookinAttribute.h" +#import "LookinDashboardBlueprint.h" +#import "LookinIvarTrace.h" +#import "UIColor+LookinServer.h" +#import "LookinServerDefines.h" + +@implementation LKS_AttrGroupsMaker + ++ (NSArray *)attrGroupsForLayer:(CALayer *)layer { + if (!layer) { + NSAssert(NO, @""); + return nil; + } + NSArray *groups = [[LookinDashboardBlueprint groupIDs] lookin_map:^id(NSUInteger idx, LookinAttrGroupIdentifier groupID) { + LookinAttributesGroup *group = [LookinAttributesGroup new]; + group.identifier = groupID; + + NSArray *secIDs = [LookinDashboardBlueprint sectionIDsForGroupID:groupID]; + group.attrSections = [secIDs lookin_map:^id(NSUInteger idx, LookinAttrSectionIdentifier secID) { + LookinAttributesSection *sec = [LookinAttributesSection new]; + sec.identifier = secID; + + NSArray *attrIDs = [LookinDashboardBlueprint attrIDsForSectionID:secID]; + sec.attributes = [attrIDs lookin_map:^id(NSUInteger idx, LookinAttrIdentifier attrID) { + NSInteger minAvailableVersion = [LookinDashboardBlueprint minAvailableOSVersionWithAttrID:attrID]; + if (minAvailableVersion > 0 && (NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < minAvailableVersion)) { + // iOS 版本过低不支持该属性 + return nil; + } + + id targetObj = nil; + if ([LookinDashboardBlueprint isUIViewPropertyWithAttrID:attrID]) { + targetObj = layer.lks_hostView; + } else { + targetObj = layer; + } + + if (targetObj) { + Class targetClass = NSClassFromString([LookinDashboardBlueprint classNameWithAttrID:attrID]); + if (![targetObj isKindOfClass:targetClass]) { + return nil; + } + + LookinAttribute *attr = [self _attributeWithIdentifer:attrID targetObject:targetObj]; + return attr; + } else { + return nil; + } + }]; + + if (sec.attributes.count) { + return sec; + } else { + return nil; + } + }]; + + if ([groupID isEqualToString:LookinAttrGroup_AutoLayout]) { + // 这里特殊处理一下,如果 AutoLayout 里面不包含 Constraints 的话(只有 Hugging 和 Resistance),就丢弃掉这整个 AutoLayout 不显示 + BOOL hasConstraits = [group.attrSections lookin_any:^BOOL(LookinAttributesSection *obj) { + return [obj.identifier isEqualToString:LookinAttrSec_AutoLayout_Constraints]; + }]; + if (!hasConstraits) { + return nil; + } + } + + if (group.attrSections.count) { + return group; + } else { + return nil; + } + }]; + + return groups; +} + ++ (LookinAttribute *)_attributeWithIdentifer:(LookinAttrIdentifier)identifier targetObject:(id)target { + if (!target) { + NSAssert(NO, @""); + return nil; + } + + LookinAttribute *attribute = [LookinAttribute new]; + attribute.identifier = identifier; + + SEL getter = [LookinDashboardBlueprint getterWithAttrID:identifier]; + if (!getter) { + NSAssert(NO, @""); + return nil; + } + if (![target respondsToSelector:getter]) { + // 比如某些 QMUI 的属性,不引入 QMUI 就会走到这个分支里 + return nil; + } + NSMethodSignature *signature = [target methodSignatureForSelector:getter]; + if (signature.numberOfArguments > 2) { + NSAssert(NO, @"getter 不可以有参数"); + return nil; + } + if (strcmp([signature methodReturnType], @encode(void)) == 0) { + NSAssert(NO, @"getter 返回值不能为 void"); + return nil; + } + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + invocation.target = target; + invocation.selector = getter; + [invocation invoke]; + + const char *returnType = [signature methodReturnType]; + + if (strcmp(returnType, @encode(char)) == 0) { + char targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeChar; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(int)) == 0) { + int targetValue; + [invocation getReturnValue:&targetValue]; + attribute.value = @(targetValue); + if ([LookinDashboardBlueprint enumListNameWithAttrID:identifier]) { + attribute.attrType = LookinAttrTypeEnumInt; + } else { + attribute.attrType = LookinAttrTypeInt; + } + + } else if (strcmp(returnType, @encode(short)) == 0) { + short targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeShort; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(long)) == 0) { + long targetValue; + [invocation getReturnValue:&targetValue]; + attribute.value = @(targetValue); + if ([LookinDashboardBlueprint enumListNameWithAttrID:identifier]) { + attribute.attrType = LookinAttrTypeEnumLong; + } else { + attribute.attrType = LookinAttrTypeLong; + } + + } else if (strcmp(returnType, @encode(long long)) == 0) { + long long targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeLongLong; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(unsigned char)) == 0) { + unsigned char targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUnsignedChar; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(unsigned int)) == 0) { + unsigned int targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUnsignedInt; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(unsigned short)) == 0) { + unsigned short targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUnsignedShort; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(unsigned long)) == 0) { + unsigned long targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUnsignedLong; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(unsigned long long)) == 0) { + unsigned long long targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUnsignedLongLong; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(float)) == 0) { + float targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeFloat; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(double)) == 0) { + double targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeDouble; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(BOOL)) == 0) { + BOOL targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeBOOL; + attribute.value = @(targetValue); + + } else if (strcmp(returnType, @encode(SEL)) == 0) { + SEL targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeSel; + attribute.value = NSStringFromSelector(targetValue); + + } else if (strcmp(returnType, @encode(Class)) == 0) { + Class targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeClass; + attribute.value = NSStringFromClass(targetValue); + + } else if (strcmp(returnType, @encode(CGPoint)) == 0) { + CGPoint targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeCGPoint; + attribute.value = [NSValue valueWithCGPoint:targetValue]; + + } else if (strcmp(returnType, @encode(CGVector)) == 0) { + CGVector targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeCGVector; + attribute.value = [NSValue valueWithCGVector:targetValue]; + + } else if (strcmp(returnType, @encode(CGSize)) == 0) { + CGSize targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeCGSize; + attribute.value = [NSValue valueWithCGSize:targetValue]; + + } else if (strcmp(returnType, @encode(CGRect)) == 0) { + CGRect targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeCGRect; + attribute.value = [NSValue valueWithCGRect:targetValue]; + + } else if (strcmp(returnType, @encode(CGAffineTransform)) == 0) { + CGAffineTransform targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeCGAffineTransform; + attribute.value = [NSValue valueWithCGAffineTransform:targetValue]; + + } else if (strcmp(returnType, @encode(UIEdgeInsets)) == 0) { + UIEdgeInsets targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUIEdgeInsets; + attribute.value = [NSValue valueWithUIEdgeInsets:targetValue]; + + } else if (strcmp(returnType, @encode(UIOffset)) == 0) { + UIOffset targetValue; + [invocation getReturnValue:&targetValue]; + attribute.attrType = LookinAttrTypeUIOffset; + attribute.value = [NSValue valueWithUIOffset:targetValue]; + + } else { + NSString *argType_string = [[NSString alloc] lookin_safeInitWithUTF8String:returnType]; + if ([argType_string hasPrefix:@"@"]) { + __unsafe_unretained id returnObjValue; + [invocation getReturnValue:&returnObjValue]; + + if (!returnObjValue && [LookinDashboardBlueprint hideIfNilWithAttrID:identifier]) { + // 对于某些属性,若 value 为 nil 则不显示 + return nil; + } + + attribute.attrType = [LookinDashboardBlueprint objectAttrTypeWithAttrID:identifier]; + if (attribute.attrType == LookinAttrTypeUIColor) { + if (returnObjValue == nil) { + attribute.value = nil; + } else if ([returnObjValue isKindOfClass:[UIColor class]] && [returnObjValue respondsToSelector:@selector(lks_rgbaComponents)]) { + attribute.value = [returnObjValue lks_rgbaComponents]; + } else { + // https://github.com/QMUI/LookinServer/issues/124 + return nil; + } + } else { + attribute.value = returnObjValue; + } + + } else { + NSAssert(NO, @"不支持解析该类型的返回值"); + return nil; + } + } + + return attribute; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.h new file mode 100644 index 00000000..781711a9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.h @@ -0,0 +1,27 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrGroupsMaker.h +// LookinServer +// +// Created by LikaiMacStudioWork on 2023/10/31. +// + +#import "LookinDefines.h" + +@class LookinAttributesGroup; + +@interface LKS_CustomAttrGroupsMaker : NSObject + +- (instancetype)initWithLayer:(CALayer *)layer; + +- (void)execute; + +- (NSArray *)getGroups; +- (NSString *)getCustomDisplayTitle; +- (NSString *)getDanceUISource; + ++ (NSArray *)makeGroupsFromRawProperties:(NSArray *)rawProperties saveCustomSetter:(BOOL)saveCustomSetter; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.m new file mode 100644 index 00000000..428b683d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrGroupsMaker.m @@ -0,0 +1,486 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrGroupsMaker.m +// LookinServer +// +// Created by LikaiMacStudioWork on 2023/10/31. +// + +#import "LKS_CustomAttrGroupsMaker.h" +#import "LKS_AttrGroupsMaker.h" +#import "LookinAttributesGroup.h" +#import "LookinAttributesSection.h" +#import "LookinAttribute.h" +#import "LookinDashboardBlueprint.h" +#import "LookinIvarTrace.h" +#import "UIColor+LookinServer.h" +#import "LookinServerDefines.h" +#import "LKS_CustomAttrSetterManager.h" + +@interface LKS_CustomAttrGroupsMaker () + +/// key 是 section title +@property(nonatomic, strong) NSMutableDictionary *> *sectionAndAttrs; + +@property(nonatomic, copy) NSString *resolvedCustomDisplayTitle; +@property(nonatomic, copy) NSString *resolvedDanceUISource; +@property(nonatomic, strong) NSMutableArray *resolvedGroups; + +@property(nonatomic, weak) CALayer *layer; + +@end + +@implementation LKS_CustomAttrGroupsMaker + +- (instancetype)initWithLayer:(CALayer *)layer { + if (self = [super init]) { + self.sectionAndAttrs = [NSMutableDictionary dictionary]; + self.layer = layer; + } + return self; +} + +- (void)execute { + if (!self.layer) { + NSAssert(NO, @""); + return; + } + NSMutableArray *selectors = [NSMutableArray array]; + [selectors addObject:@"lookin_customDebugInfos"]; + for (int i = 0; i < 5; i++) { + [selectors addObject:[NSString stringWithFormat:@"lookin_customDebugInfos_%@", @(i)]]; + } + + for (NSString *name in selectors) { + [self makeAttrsForViewOrLayer:self.layer selectorName:name]; + + UIView *view = self.layer.lks_hostView; + if (view) { + [self makeAttrsForViewOrLayer:view selectorName:name]; + } + } + + if ([self.sectionAndAttrs count] == 0) { + return; + } + NSMutableArray *groups = [NSMutableArray array]; + [self.sectionAndAttrs enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull groupTitle, NSMutableArray * _Nonnull attrs, BOOL * _Nonnull stop) { + LookinAttributesGroup *group = [LookinAttributesGroup new]; + group.userCustomTitle = groupTitle; + group.identifier = LookinAttrGroup_UserCustom; + + NSMutableArray *sections = [NSMutableArray array]; + [attrs enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) { + LookinAttributesSection *sec = [LookinAttributesSection new]; + sec.identifier = LookinAttrSec_UserCustom; + sec.attributes = @[attr]; + [sections addObject:sec]; + }]; + + group.attrSections = sections; + [groups addObject:group]; + }]; + [groups sortedArrayUsingComparator:^NSComparisonResult(LookinAttributesGroup *obj1, LookinAttributesGroup *obj2) { + return [obj1.userCustomTitle compare:obj2.userCustomTitle]; + }]; + + self.resolvedGroups = groups; +} + +- (void)makeAttrsForViewOrLayer:(id)viewOrLayer selectorName:(NSString *)selectorName { + if (!viewOrLayer || !selectorName.length) { + return; + } + if (![viewOrLayer isKindOfClass:[UIView class]] && ![viewOrLayer isKindOfClass:[CALayer class]]) { + return; + } + SEL selector = NSSelectorFromString(selectorName); + if (![viewOrLayer respondsToSelector:selector]) { + return; + } + NSMethodSignature *signature = [viewOrLayer methodSignatureForSelector:selector]; + if (signature.numberOfArguments > 2) { + NSAssert(NO, @"LookinServer - There should be no explicit parameters."); + return; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:viewOrLayer]; + [invocation setSelector:selector]; + [invocation invoke]; + + // 小心这里的内存管理 + NSDictionary * __unsafe_unretained tempRawData; + [invocation getReturnValue:&tempRawData]; + if (!tempRawData || ![tempRawData isKindOfClass:[NSDictionary class]]) { + return; + } + + NSDictionary *rawData = tempRawData; + NSArray *rawProperties = rawData[@"properties"]; + + NSString *customTitle = rawData[@"title"]; + if (customTitle && [customTitle isKindOfClass:[NSString class]] && customTitle.length > 0) { + self.resolvedCustomDisplayTitle = customTitle; + } + + NSString *danceSource = rawData[@"lookin_source"]; + if (danceSource && [danceSource isKindOfClass:[NSString class]] && danceSource.length > 0) { + self.resolvedDanceUISource = danceSource; + } + + [self makeAttrsFromRawProperties:rawProperties]; +} + +- (void)makeAttrsFromRawProperties:(NSArray *)rawProperties { + if (!rawProperties || ![rawProperties isKindOfClass:[NSArray class]]) { + return; + } + + for (NSDictionary *dict in rawProperties) { + NSString *groupTitle; + LookinAttribute *attr = [LKS_CustomAttrGroupsMaker attrFromRawDict:dict saveCustomSetter:YES groupTitle:&groupTitle]; + if (!attr) { + continue; + } + if (!self.sectionAndAttrs[groupTitle]) { + self.sectionAndAttrs[groupTitle] = [NSMutableArray array]; + } + [self.sectionAndAttrs[groupTitle] addObject:attr]; + } +} + ++ (LookinAttribute *)attrFromRawDict:(NSDictionary *)dict saveCustomSetter:(BOOL)saveCustomSetter groupTitle:(inout NSString **)inoutGroupTitle { + LookinAttribute *attr = [LookinAttribute new]; + attr.identifier = LookinAttr_UserCustom; + + NSString *title = dict[@"title"]; + NSString *type = dict[@"valueType"]; + NSString *section = dict[@"section"]; + id value = dict[@"value"]; + + if (!title || ![title isKindOfClass:[NSString class]]) { + NSLog(@"LookinServer - Wrong title"); + return nil; + } + if (!type || ![type isKindOfClass:[NSString class]]) { + NSLog(@"LookinServer - Wrong valueType"); + return nil; + } + if (!section || ![section isKindOfClass:[NSString class]] || section.length == 0) { + *inoutGroupTitle = @"Custom"; + } else { + *inoutGroupTitle = section; + } + + attr.displayTitle = title; + + NSString *fixedType = type.lowercaseString; + if ([fixedType isEqualToString:@"string"]) { + if (value != nil && ![value isKindOfClass:[NSString class]]) { + // nil 是合法的 + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeNSString; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_StringSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveStringSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"number"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSNumber class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeDouble; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_NumberSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveNumberSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"bool"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSNumber class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeBOOL; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_BoolSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveBoolSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"color"]) { + if (value != nil && ![value isKindOfClass:[UIColor class]]) { + // nil 是合法的 + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeUIColor; + attr.value = [(UIColor *)value lks_rgbaComponents]; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_ColorSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveColorSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"rect"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSValue class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeCGRect; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_RectSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveRectSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"size"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSValue class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeCGSize; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_SizeSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveSizeSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"point"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSValue class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeCGPoint; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_PointSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] savePointSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"insets"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSValue class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeUIEdgeInsets; + attr.value = value; + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_InsetsSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveInsetsSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"shadow"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSDictionary class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + NSDictionary *shadowInfo = value; + if (![shadowInfo[@"offset"] isKindOfClass:[NSValue class]]) { + NSLog(@"LookinServer - Wrong value. No offset."); + return nil; + } + if (![shadowInfo[@"opacity"] isKindOfClass:[NSNumber class]]) { + NSLog(@"LookinServer - Wrong value. No opacity."); + return nil; + } + if (![shadowInfo[@"radius"] isKindOfClass:[NSNumber class]]) { + NSLog(@"LookinServer - Wrong value. No radius."); + return nil; + } + NSMutableDictionary *checkedShadowInfo = [@{ + @"offset": shadowInfo[@"offset"], + @"opacity": shadowInfo[@"opacity"], + @"radius": shadowInfo[@"radius"] + } mutableCopy]; + if ([shadowInfo[@"color"] isKindOfClass:[UIColor class]]) { + checkedShadowInfo[@"color"] = [(UIColor *)shadowInfo[@"color"] lks_rgbaComponents]; + } + + attr.attrType = LookinAttrTypeShadow; + attr.value = checkedShadowInfo; + + return attr; + } + + if ([fixedType isEqualToString:@"enum"]) { + if (value == nil) { + NSLog(@"LookinServer - No value."); + return nil; + } + if (![value isKindOfClass:[NSString class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeEnumString; + attr.value = value; + + NSArray *allEnumCases = dict[@"allEnumCases"]; + if ([allEnumCases isKindOfClass:[NSArray class]]) { + attr.extraValue = allEnumCases; + } + + if (saveCustomSetter && dict[@"retainedSetter"]) { + NSString *uniqueID = [[NSUUID new] UUIDString]; + LKS_EnumSetter setter = dict[@"retainedSetter"]; + [[LKS_CustomAttrSetterManager sharedInstance] saveEnumSetter:setter uniqueID:uniqueID]; + attr.customSetterID = uniqueID; + } + + return attr; + } + + if ([fixedType isEqualToString:@"json"]) { + if (![value isKindOfClass:[NSString class]]) { + NSLog(@"LookinServer - Wrong value type."); + return nil; + } + attr.attrType = LookinAttrTypeJson; + attr.value = value; + + return attr; + } + + NSLog(@"LookinServer - Unsupported value type."); + return nil; +} + +- (NSArray *)getGroups { + return self.resolvedGroups; +} + +- (NSString *)getCustomDisplayTitle { + return self.resolvedCustomDisplayTitle; +} + +- (NSString *)getDanceUISource { + return self.resolvedDanceUISource; +} + ++ (NSArray *)makeGroupsFromRawProperties:(NSArray *)rawProperties saveCustomSetter:(BOOL)saveCustomSetter { + if (!rawProperties || ![rawProperties isKindOfClass:[NSArray class]]) { + return nil; + } + // key 是 group title + NSMutableDictionary *> *groupTitleAndAttrs = [NSMutableDictionary dictionary]; + + for (NSDictionary *dict in rawProperties) { + NSString *groupTitle; + LookinAttribute *attr = [LKS_CustomAttrGroupsMaker attrFromRawDict:dict saveCustomSetter:saveCustomSetter groupTitle:&groupTitle]; + if (!attr) { + continue; + } + if (!groupTitleAndAttrs[groupTitle]) { + groupTitleAndAttrs[groupTitle] = [NSMutableArray array]; + } + [groupTitleAndAttrs[groupTitle] addObject:attr]; + } + + if ([groupTitleAndAttrs count] == 0) { + return nil; + } + NSMutableArray *groups = [NSMutableArray array]; + [groupTitleAndAttrs enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull groupTitle, NSMutableArray * _Nonnull attrs, BOOL * _Nonnull stop) { + LookinAttributesGroup *group = [LookinAttributesGroup new]; + group.userCustomTitle = groupTitle; + group.identifier = LookinAttrGroup_UserCustom; + + NSMutableArray *sections = [NSMutableArray array]; + [attrs enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) { + LookinAttributesSection *sec = [LookinAttributesSection new]; + sec.identifier = LookinAttrSec_UserCustom; + sec.attributes = @[attr]; + [sections addObject:sec]; + }]; + + group.attrSections = sections; + [groups addObject:group]; + }]; + [groups sortedArrayUsingComparator:^NSComparisonResult(LookinAttributesGroup *obj1, LookinAttributesGroup *obj2) { + return [obj1.userCustomTitle compare:obj2.userCustomTitle]; + }]; + return [groups copy]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.h new file mode 100644 index 00000000..7fccc77f --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.h @@ -0,0 +1,56 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrSetterManager.h +// LookinServer +// +// Created by likai.123 on 2023/11/4. +// + +#import + +typedef void(^LKS_StringSetter)(NSString *); +typedef void(^LKS_NumberSetter)(NSNumber *); +typedef void(^LKS_BoolSetter)(BOOL); +typedef void(^LKS_ColorSetter)(UIColor *); +typedef void(^LKS_EnumSetter)(NSString *); +typedef void(^LKS_RectSetter)(CGRect); +typedef void(^LKS_SizeSetter)(CGSize); +typedef void(^LKS_PointSetter)(CGPoint); +typedef void(^LKS_InsetsSetter)(UIEdgeInsets); + +@interface LKS_CustomAttrSetterManager : NSObject + ++ (instancetype)sharedInstance; + +- (void)removeAll; + +- (void)saveStringSetter:(LKS_StringSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_StringSetter)getStringSetterWithID:(NSString *)uniqueID; + +- (void)saveNumberSetter:(LKS_NumberSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_NumberSetter)getNumberSetterWithID:(NSString *)uniqueID; + +- (void)saveBoolSetter:(LKS_BoolSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_BoolSetter)getBoolSetterWithID:(NSString *)uniqueID; + +- (void)saveColorSetter:(LKS_ColorSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_ColorSetter)getColorSetterWithID:(NSString *)uniqueID; + +- (void)saveEnumSetter:(LKS_EnumSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_EnumSetter)getEnumSetterWithID:(NSString *)uniqueID; + +- (void)saveRectSetter:(LKS_RectSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_RectSetter)getRectSetterWithID:(NSString *)uniqueID; + +- (void)saveSizeSetter:(LKS_SizeSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_SizeSetter)getSizeSetterWithID:(NSString *)uniqueID; + +- (void)savePointSetter:(LKS_PointSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_PointSetter)getPointSetterWithID:(NSString *)uniqueID; + +- (void)saveInsetsSetter:(LKS_InsetsSetter)setter uniqueID:(NSString *)uniqueID; +- (LKS_InsetsSetter)getInsetsSetterWithID:(NSString *)uniqueID; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.m new file mode 100644 index 00000000..20b73c9b --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomAttrSetterManager.m @@ -0,0 +1,117 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_CustomAttrSetterManager.m +// LookinServer +// +// Created by likai.123 on 2023/11/4. +// + +#import "LKS_CustomAttrSetterManager.h" + +@interface LKS_CustomAttrSetterManager () + +@property(nonatomic, strong) NSMutableDictionary *settersMap; + +@end + +@implementation LKS_CustomAttrSetterManager + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static LKS_CustomAttrSetterManager *instance = nil; + dispatch_once(&onceToken,^{ + instance = [[super allocWithZone:NULL] init]; + }); + return instance; +} + ++ (id)allocWithZone:(struct _NSZone *)zone { + return [self sharedInstance]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.settersMap = [NSMutableDictionary new]; + } + return self; +} + +- (void)removeAll { + [self.settersMap removeAllObjects]; +} + +- (void)saveStringSetter:(nonnull LKS_StringSetter)setter uniqueID:(nonnull NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (nullable LKS_StringSetter)getStringSetterWithID:(nonnull NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveNumberSetter:(LKS_NumberSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (nullable LKS_NumberSetter)getNumberSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveBoolSetter:(LKS_BoolSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_BoolSetter)getBoolSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveColorSetter:(LKS_ColorSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_ColorSetter)getColorSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveEnumSetter:(LKS_EnumSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_EnumSetter)getEnumSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveRectSetter:(LKS_RectSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_RectSetter)getRectSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveSizeSetter:(LKS_SizeSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_SizeSetter)getSizeSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)savePointSetter:(LKS_PointSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_PointSetter)getPointSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +- (void)saveInsetsSetter:(LKS_InsetsSetter)setter uniqueID:(NSString *)uniqueID { + self.settersMap[uniqueID] = setter; +} + +- (LKS_InsetsSetter)getInsetsSetterWithID:(NSString *)uniqueID { + return self.settersMap[uniqueID]; +} + +@end +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.h new file mode 100644 index 00000000..7cf658ed --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.h @@ -0,0 +1,22 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_CustomDisplayItemsMaker.h +// LookinServer +// +// Created by likai.123 on 2023/11/1. +// + +#import + +@class LookinDisplayItem; + +@interface LKS_CustomDisplayItemsMaker : NSObject + +- (instancetype)initWithLayer:(CALayer *)layer saveAttrSetter:(BOOL)saveAttrSetter; + +- (NSArray *)make; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.m new file mode 100644 index 00000000..bdffcfcf --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_CustomDisplayItemsMaker.m @@ -0,0 +1,144 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_CustomDisplayItemsMaker.m +// LookinServer +// +// Created by likai.123 on 2023/11/1. +// + +#import "LKS_CustomDisplayItemsMaker.h" +#import "CALayer+LookinServer.h" +#import "LookinDisplayItem.h" +#import "NSArray+Lookin.h" +#import "LKS_CustomAttrGroupsMaker.h" + +@interface LKS_CustomDisplayItemsMaker () + +@property(nonatomic, weak) CALayer *layer; +@property(nonatomic, assign) BOOL saveAttrSetter; +@property(nonatomic, strong) NSMutableArray *allSubitems; + +@end + +@implementation LKS_CustomDisplayItemsMaker + +- (instancetype)initWithLayer:(CALayer *)layer saveAttrSetter:(BOOL)saveAttrSetter { + if (self = [super init]) { + self.layer = layer; + self.saveAttrSetter = saveAttrSetter; + self.allSubitems = [NSMutableArray array]; + } + return self; +} + +- (NSArray *)make { + if (!self.layer) { + NSAssert(NO, @""); + return nil; + } + NSMutableArray *selectors = [NSMutableArray array]; + [selectors addObject:@"lookin_customDebugInfos"]; + for (int i = 0; i < 5; i++) { + [selectors addObject:[NSString stringWithFormat:@"lookin_customDebugInfos_%@", @(i)]]; + } + + for (NSString *name in selectors) { + [self makeSubitemsForViewOrLayer:self.layer selectorName:name]; + + UIView *view = self.layer.lks_hostView; + if (view) { + [self makeSubitemsForViewOrLayer:view selectorName:name]; + } + } + + if (self.allSubitems.count) { + return self.allSubitems; + } else { + return nil; + } +} + +- (void)makeSubitemsForViewOrLayer:(id)viewOrLayer selectorName:(NSString *)selectorName { + if (!viewOrLayer || !selectorName.length) { + return; + } + if (![viewOrLayer isKindOfClass:[UIView class]] && ![viewOrLayer isKindOfClass:[CALayer class]]) { + return; + } + SEL selector = NSSelectorFromString(selectorName); + if (![viewOrLayer respondsToSelector:selector]) { + return; + } + NSMethodSignature *signature = [viewOrLayer methodSignatureForSelector:selector]; + if (signature.numberOfArguments > 2) { + NSAssert(NO, @"LookinServer - There should be no explicit parameters."); + return; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:viewOrLayer]; + [invocation setSelector:selector]; + [invocation invoke]; + + // 小心这里的内存管理 + NSDictionary * __unsafe_unretained tempRawData; + [invocation getReturnValue:&tempRawData]; + NSDictionary *rawData = tempRawData; + + [self makeSubitemsFromRawData:rawData]; +} + +- (void)makeSubitemsFromRawData:(NSDictionary *)data { + if (!data || ![data isKindOfClass:[NSDictionary class]]) { + return; + } + NSArray *rawSubviews = data[@"subviews"]; + NSArray *newSubitems = [self displayItemsFromRawArray:rawSubviews]; + if (newSubitems) { + [self.allSubitems addObjectsFromArray:newSubitems]; + } +} + +- (NSArray *)displayItemsFromRawArray:(NSArray *)rawArray { + if (!rawArray || ![rawArray isKindOfClass:[NSArray class]]) { + return nil; + } + NSArray *items = [rawArray lookin_map:^id(NSUInteger idx, NSDictionary *rawDict) { + if (![rawDict isKindOfClass:[NSDictionary class]]) { + return nil; + } + return [self displayItemFromRawDict:rawDict]; + }]; + return items; +} + +- (LookinDisplayItem *)displayItemFromRawDict:(NSDictionary *)dict { + NSString *title = dict[@"title"]; + NSString *subtitle = dict[@"subtitle"]; + NSValue *frameValue = dict[@"frameInWindow"]; + NSArray *properties = dict[@"properties"]; + NSArray *subviews = dict[@"subviews"]; + NSString *danceSource = dict[@"lookin_source"]; + + if (![title isKindOfClass:[NSString class]]) { + return nil; + } + LookinDisplayItem *newItem = [LookinDisplayItem new]; + if (subviews && [subviews isKindOfClass:[NSArray class]]) { + newItem.subitems = [self displayItemsFromRawArray:subviews]; + } + newItem.isHidden = NO; + newItem.alpha = 1.0; + newItem.customInfo = [LookinCustomDisplayItemInfo new]; + newItem.customInfo.title = title; + newItem.customInfo.subtitle = subtitle; + newItem.customInfo.frameInWindow = frameValue; + newItem.customInfo.danceuiSource = danceSource; + newItem.customAttrGroupList = [LKS_CustomAttrGroupsMaker makeGroupsFromRawProperties:properties saveCustomSetter:self.saveAttrSetter]; + + return newItem; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.h new file mode 100644 index 00000000..cc12c499 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_EventHandlerMaker.h +// LookinServer +// +// Created by Li Kai on 2019/8/7. +// https://lookin.work +// + +#import "LookinDefines.h" + +@class LookinEventHandler; + +@interface LKS_EventHandlerMaker : NSObject + ++ (NSArray *)makeForView:(UIView *)view; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.m new file mode 100644 index 00000000..200543eb --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_EventHandlerMaker.m @@ -0,0 +1,215 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_EventHandlerMaker.m +// LookinServer +// +// Created by Li Kai on 2019/8/7. +// https://lookin.work +// + +#import "LKS_EventHandlerMaker.h" +#import "LookinTuple.h" +#import "LookinEventHandler.h" +#import "LookinObject.h" +#import "LookinWeakContainer.h" +#import "LookinIvarTrace.h" +#import "LookinServerDefines.h" +#import "LKS_GestureTargetActionsSearcher.h" +#import "LKS_MultiplatformAdapter.h" + +@implementation LKS_EventHandlerMaker + ++ (NSArray *)makeForView:(UIView *)view { + if (!view) { + return nil; + } + + NSMutableArray *allHandlers = nil; + + if ([view isKindOfClass:[UIControl class]]) { + NSArray *targetActionHandlers = [self _targetActionHandlersForControl:(UIControl *)view]; + if (targetActionHandlers.count) { + if (!allHandlers) { + allHandlers = [NSMutableArray array]; + } + [allHandlers addObjectsFromArray:targetActionHandlers]; + } + } + + NSArray *gestureHandlers = [self _gestureHandlersForView:view]; + if (gestureHandlers.count) { + if (!allHandlers) { + allHandlers = [NSMutableArray array]; + } + [allHandlers addObjectsFromArray:gestureHandlers]; + } + + return allHandlers.copy; +} + ++ (NSArray *)_gestureHandlersForView:(UIView *)view { + if (view.gestureRecognizers.count == 0) { + return nil; + } + NSArray *handlers = [view.gestureRecognizers lookin_map:^id(NSUInteger idx, __kindof UIGestureRecognizer *recognizer) { + LookinEventHandler *handler = [LookinEventHandler new]; + handler.handlerType = LookinEventHandlerTypeGesture; + handler.eventName = NSStringFromClass([recognizer class]); + + NSArray *targetActionInfos = [LKS_GestureTargetActionsSearcher getTargetActionsFromRecognizer:recognizer]; + handler.targetActions = [targetActionInfos lookin_map:^id(NSUInteger idx, LookinTwoTuple *rawTuple) { + NSObject *target = ((LookinWeakContainer *)rawTuple.first).object; + if (!target) { + // 该 target 已被释放 + return nil; + } + LookinStringTwoTuple *newTuple = [LookinStringTwoTuple new]; + newTuple.first = [LKS_Helper descriptionOfObject:target]; + newTuple.second = (NSString *)rawTuple.second; + return newTuple; + }]; + handler.inheritedRecognizerName = [self _inheritedRecognizerNameForRecognizer:recognizer]; + handler.gestureRecognizerIsEnabled = recognizer.enabled; + if (recognizer.delegate) { + handler.gestureRecognizerDelegator = [LKS_Helper descriptionOfObject:recognizer.delegate]; + } + handler.recognizerIvarTraces = [recognizer.lks_ivarTraces lookin_map:^id(NSUInteger idx, LookinIvarTrace *trace) { + return [NSString stringWithFormat:@"(%@ *) -> %@", trace.hostClassName, trace.ivarName]; + }]; + + handler.recognizerOid = [recognizer lks_registerOid]; + return handler; + }]; + return handlers; +} + ++ (NSString *)_inheritedRecognizerNameForRecognizer:(UIGestureRecognizer *)recognizer { + if (!recognizer) { + NSAssert(NO, @""); + return nil; + } + + static NSArray *baseRecognizers; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // 注意这里 UIScreenEdgePanGestureRecognizer 在 UIPanGestureRecognizer 前面,因为 UIScreenEdgePanGestureRecognizer 继承于 UIPanGestureRecognizer +#if TARGET_OS_TV + baseRecognizers = @[[UILongPressGestureRecognizer class], + [UIPanGestureRecognizer class], + [UISwipeGestureRecognizer class], + [UITapGestureRecognizer class]]; +#elif TARGET_OS_VISION + baseRecognizers = @[[UILongPressGestureRecognizer class], + [UIPanGestureRecognizer class], + [UISwipeGestureRecognizer class], + [UIRotationGestureRecognizer class], + [UIPinchGestureRecognizer class], + [UITapGestureRecognizer class]]; +#else + baseRecognizers = @[[UILongPressGestureRecognizer class], + [UIScreenEdgePanGestureRecognizer class], + [UIPanGestureRecognizer class], + [UISwipeGestureRecognizer class], + [UIRotationGestureRecognizer class], + [UIPinchGestureRecognizer class], + [UITapGestureRecognizer class]]; +#endif + + }); + + __block NSString *result = @"UIGestureRecognizer"; + [baseRecognizers enumerateObjectsUsingBlock:^(Class _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if ([recognizer isMemberOfClass:obj]) { + // 自身就是基本款,则直接置为 nil + result = nil; + *stop = YES; + return; + } + if ([recognizer isKindOfClass:obj]) { + result = NSStringFromClass(obj); + *stop = YES; + return; + } + }]; + return result; +} + ++ (NSArray *)_targetActionHandlersForControl:(UIControl *)control { + static dispatch_once_t onceToken; + static NSArray *allEvents = nil; + dispatch_once(&onceToken,^{ + allEvents = @[@(UIControlEventTouchDown), @(UIControlEventTouchDownRepeat), @(UIControlEventTouchDragInside), @(UIControlEventTouchDragOutside), @(UIControlEventTouchDragEnter), @(UIControlEventTouchDragExit), @(UIControlEventTouchUpInside), @(UIControlEventTouchUpOutside), @(UIControlEventTouchCancel), @(UIControlEventValueChanged), @(UIControlEventEditingDidBegin), @(UIControlEventEditingChanged), @(UIControlEventEditingDidEnd), @(UIControlEventEditingDidEndOnExit)]; + if (@available(iOS 9.0, *)) { + allEvents = [allEvents arrayByAddingObject:@(UIControlEventPrimaryActionTriggered)]; + } + }); + + NSSet *allTargets = control.allTargets; + + if (!allTargets.count) { + return nil; + } + + NSMutableArray *handlers = [NSMutableArray array]; + + [allEvents enumerateObjectsUsingBlock:^(NSNumber * _Nonnull eventNum, NSUInteger idx, BOOL * _Nonnull stop) { + UIControlEvents event = [eventNum unsignedIntegerValue]; + + NSMutableArray *targetActions = [NSMutableArray array]; + + [allTargets enumerateObjectsUsingBlock:^(id _Nonnull target, BOOL * _Nonnull stop) { + NSArray *actions = [control actionsForTarget:target forControlEvent:event]; + [actions enumerateObjectsUsingBlock:^(NSString * _Nonnull action, NSUInteger idx, BOOL * _Nonnull stop) { + LookinStringTwoTuple *tuple = [LookinStringTwoTuple new]; + tuple.first = [LKS_Helper descriptionOfObject:target]; + tuple.second = action; + [targetActions addObject:tuple]; + }]; + }]; + + if (targetActions.count) { + LookinEventHandler *handler = [LookinEventHandler new]; + handler.handlerType = LookinEventHandlerTypeTargetAction; + handler.eventName = [self _nameFromControlEvent:event]; + handler.targetActions = targetActions.copy; + [handlers addObject:handler]; + } + }]; + + return handlers; +} + ++ (NSString *)_nameFromControlEvent:(UIControlEvents)event { + static dispatch_once_t onceToken; + static NSDictionary *eventsAndNames = nil; + dispatch_once(&onceToken,^{ + NSMutableDictionary *eventsAndNames_m = @{ + @(UIControlEventTouchDown): @"UIControlEventTouchDown", + @(UIControlEventTouchDownRepeat): @"UIControlEventTouchDownRepeat", + @(UIControlEventTouchDragInside): @"UIControlEventTouchDragInside", + @(UIControlEventTouchDragOutside): @"UIControlEventTouchDragOutside", + @(UIControlEventTouchDragEnter): @"UIControlEventTouchDragEnter", + @(UIControlEventTouchDragExit): @"UIControlEventTouchDragExit", + @(UIControlEventTouchUpInside): @"UIControlEventTouchUpInside", + @(UIControlEventTouchUpOutside): @"UIControlEventTouchUpOutside", + @(UIControlEventTouchCancel): @"UIControlEventTouchCancel", + @(UIControlEventValueChanged): @"UIControlEventValueChanged", + @(UIControlEventEditingDidBegin): @"UIControlEventEditingDidBegin", + @(UIControlEventEditingChanged): @"UIControlEventEditingChanged", + @(UIControlEventEditingDidEnd): @"UIControlEventEditingDidEnd", + @(UIControlEventEditingDidEndOnExit): @"UIControlEventEditingDidEndOnExit", + }.mutableCopy; + if (@available(iOS 9.0, *)) { + eventsAndNames_m[@(UIControlEventPrimaryActionTriggered)] = @"UIControlEventPrimaryActionTriggered"; + } + eventsAndNames = eventsAndNames_m.copy; + }); + + NSString *name = eventsAndNames[@(event)]; + return name; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.h new file mode 100644 index 00000000..90fe53b9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_ExportManager.h +// LookinServer +// +// Created by Li Kai on 2019/5/13. +// https://lookin.work +// + +#import + +@interface LKS_ExportManager : NSObject + ++ (instancetype)sharedInstance; + +- (void)exportAndShare; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.m new file mode 100644 index 00000000..be040b9c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_ExportManager.m @@ -0,0 +1,193 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_ExportManager.m +// LookinServer +// +// Created by Li Kai on 2019/5/13. +// https://lookin.work +// + +#import "LKS_ExportManager.h" +#import "UIViewController+LookinServer.h" +#import "LookinHierarchyInfo.h" +#import "LookinHierarchyFile.h" +#import "LookinAppInfo.h" +#import "LookinServerDefines.h" +#import "LKS_MultiplatformAdapter.h" + +@interface LKS_ExportManagerMaskView : UIView + +@property(nonatomic, strong) UIView *tipsView; +@property(nonatomic, strong) UILabel *firstLabel; +@property(nonatomic, strong) UILabel *secondLabel; +@property(nonatomic, strong) UILabel *thirdLabel; + +@end + +@implementation LKS_ExportManagerMaskView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.35]; + + self.tipsView = [UIView new]; + self.tipsView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.88]; + self.tipsView.layer.cornerRadius = 6; + self.tipsView.layer.masksToBounds = YES; + [self addSubview:self.tipsView]; + + self.firstLabel = [UILabel new]; + self.firstLabel.text = LKS_Localized(@"Creating File…"); + self.firstLabel.textColor = [UIColor whiteColor]; + self.firstLabel.font = [UIFont boldSystemFontOfSize:14]; + self.firstLabel.textAlignment = NSTextAlignmentCenter; + self.firstLabel.numberOfLines = 0; + [self.tipsView addSubview:self.firstLabel]; + + self.secondLabel = [UILabel new]; + self.secondLabel.text = LKS_Localized(@"May take 8 or more seconds according to the UI complexity."); + self.secondLabel.textColor = [UIColor colorWithRed:173/255.0 green:180/255.0 blue:190/255.0 alpha:1]; + self.secondLabel.font = [UIFont systemFontOfSize:12]; + self.secondLabel.textAlignment = NSTextAlignmentLeft; + self.secondLabel.numberOfLines = 0; + [self.tipsView addSubview:self.secondLabel]; + + self.thirdLabel = [UILabel new]; + self.thirdLabel.text = LKS_Localized(@"The file can be opend by Lookin.app in macOS."); + self.thirdLabel.textColor = [UIColor colorWithRed:173/255.0 green:180/255.0 blue:190/255.0 alpha:1]; + self.thirdLabel.font = [UIFont systemFontOfSize:12]; + self.thirdLabel.textAlignment = NSTextAlignmentCenter; + self.thirdLabel.numberOfLines = 0; + [self.tipsView addSubview:self.thirdLabel]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + UIEdgeInsets insets = UIEdgeInsetsMake(8, 10, 8, 10); + CGFloat maxLabelWidth = self.bounds.size.width * .8 - insets.left - insets.right; + + CGSize firstSize = [self.firstLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)]; + CGSize secondSize = [self.secondLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)]; + CGSize thirdSize = [self.thirdLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)]; + + CGFloat tipsWidth = MAX(MAX(firstSize.width, secondSize.width), thirdSize.width) + insets.left + insets.right; + + self.firstLabel.frame = CGRectMake(tipsWidth / 2.0 - firstSize.width / 2.0, insets.top, firstSize.width, firstSize.height); + self.secondLabel.frame = CGRectMake(tipsWidth / 2.0 - secondSize.width / 2.0, CGRectGetMaxY(self.firstLabel.frame) + 10, secondSize.width, secondSize.height); + self.thirdLabel.frame = CGRectMake(tipsWidth / 2.0 - thirdSize.width / 2.0, CGRectGetMaxY(self.secondLabel.frame) + 5, thirdSize.width, thirdSize.height); + + self.tipsView.frame = ({ + CGFloat height = CGRectGetMaxY(self.thirdLabel.frame) + insets.bottom; + CGRectMake(self.bounds.size.width / 2.0 - tipsWidth / 2.0, self.bounds.size.height / 2.0 - height / 2.0, tipsWidth, height); + }); +} + +@end + +@interface LKS_ExportManager () + +#if TARGET_OS_TV +#else +@property(nonatomic, strong) UIDocumentInteractionController *documentController; +#endif + +@property(nonatomic, strong) LKS_ExportManagerMaskView *maskView; + +@end + +@implementation LKS_ExportManager + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static LKS_ExportManager *instance = nil; + dispatch_once(&onceToken,^{ + instance = [[super allocWithZone:NULL] init]; + }); + return instance; +} + ++ (id)allocWithZone:(struct _NSZone *)zone{ + return [self sharedInstance]; +} + +#if TARGET_OS_TV +- (void)exportAndShare { + NSAssert(NO, @"not supported"); +} +#else +- (void)exportAndShare { + + UIViewController *visibleVc = [UIViewController lks_visibleViewController]; + if (!visibleVc) { + NSLog(@"LookinServer - Failed to export because we didn't find any visible view controller."); + return; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_WillExport" object:nil]; + + if (!self.maskView) { + self.maskView = [LKS_ExportManagerMaskView new]; + } + [visibleVc.view.window addSubview:self.maskView]; + self.maskView.frame = visibleVc.view.window.bounds; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + LookinHierarchyInfo *info = [LookinHierarchyInfo exportedInfo]; + LookinHierarchyFile *file = [LookinHierarchyFile new]; + file.serverVersion = info.serverVersion; + file.hierarchyInfo = info; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:file]; + if (!data) { + return; + } + + NSString *fileName = ({ + NSString *timeString = ({ + NSDate *date = [NSDate date]; + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"MMddHHmm"]; + [formatter stringFromDate:date]; + }); + NSString *iOSVersion = ({ + NSString *str = info.appInfo.osDescription; + NSUInteger dotIdx = [str rangeOfString:@"."].location; + if (dotIdx != NSNotFound) { + str = [str substringToIndex:dotIdx]; + } + str; + }); + [NSString stringWithFormat:@"%@_ios%@_%@.lookin", info.appInfo.appName, iOSVersion, timeString]; + }); + NSString *path = [NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), fileName]; + [data writeToFile:path atomically:YES]; + + [self.maskView removeFromSuperview]; + + if (!self.documentController) { + self.documentController = [UIDocumentInteractionController new]; + } + self.documentController.URL = [NSURL fileURLWithPath:path]; + if ([LKS_MultiplatformAdapter isiPad]) { + [self.documentController presentOpenInMenuFromRect:CGRectMake(0, 0, 1, 1) inView:visibleVc.view animated:YES]; + } else { + [self.documentController presentOpenInMenuFromRect:visibleVc.view.bounds inView:visibleVc.view animated:YES]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_DidFinishExport" object:nil]; + +// [self.documentController presentOptionsMenuFromRect:visibleVc.view.bounds inView:visibleVc.view animated:YES]; + +// CFTimeInterval endTime = CACurrentMediaTime(); +// CFTimeInterval consumingTime = endTime - startTime; +// NSLog(@"LookinServer - 导出 UI 结构耗时:%@", @(consumingTime)); + }); +} +#endif + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.h new file mode 100644 index 00000000..def0ca90 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.h @@ -0,0 +1,26 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_GestureTargetActionsSearcher.h +// LookinServer +// +// Created by likai.123 on 2023/9/11. +// + +#import + +@class LookinTwoTuple; + +NS_ASSUME_NONNULL_BEGIN + +@interface LKS_GestureTargetActionsSearcher : NSObject + +/// 返回一个 UIGestureRecognizer 实例身上绑定的 target & action 信息 +/// tuple.first => LookinWeakContainer(包裹着 target),tuple.second => action(方法名字符串) ++ (NSArray *)getTargetActionsFromRecognizer:(UIGestureRecognizer *)recognizer; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.m new file mode 100644 index 00000000..0487bffe --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_GestureTargetActionsSearcher.m @@ -0,0 +1,52 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_GestureTargetActionsSearcher.m +// LookinServer +// +// Created by likai.123 on 2023/9/11. +// + +#import "LKS_GestureTargetActionsSearcher.h" +#import +#import "NSArray+Lookin.h" +#import "LookinTuple.h" +#import "LookinWeakContainer.h" + +@implementation LKS_GestureTargetActionsSearcher + ++ (NSArray *)getTargetActionsFromRecognizer:(UIGestureRecognizer *)recognizer { + if (!recognizer) { + return @[]; + } + // KVC 要放到 try catch 里面防止 Crash + @try { + NSArray* targetsList = [recognizer valueForKey:@"_targets"]; + if (!targetsList || targetsList.count == 0) { + return @[]; + } + // 数组元素对象是 UIGestureRecognizerTarget* + // 这个元素有两个属性,一个是名为 _target 的属性指向某个实例,另一个是名为 _action 的属性保存一个 SEL + NSArray* ret = [targetsList lookin_map:^id(NSUInteger idx, id targetBox) { + id targetObj = [targetBox valueForKey:@"_target"]; + if (!targetObj) { + return nil; + } + SEL action = ((SEL (*)(id, Ivar))object_getIvar)(targetBox, class_getInstanceVariable([targetBox class], "_action")); + + LookinTwoTuple* tuple = [LookinTwoTuple new]; + tuple.first = [LookinWeakContainer containerWithObject:targetObj]; + tuple.second = (action == NULL ? @"NULL" : NSStringFromSelector(action)); + return tuple; + }]; + return ret; + } + @catch (NSException * e) { + NSLog(@"LookinServer - %@", e); + return @[]; + } +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.h new file mode 100644 index 00000000..dcb16d70 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.h @@ -0,0 +1,29 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_Helper.h +// LookinServer +// +// Created by Li Kai on 2019/7/20. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import + +#define LKS_Localized(stringKey) NSLocalizedStringFromTableInBundle(stringKey, nil, [NSBundle bundleForClass:self.class], nil) + +@interface LKS_Helper : NSObject + +/// 如果 object 为 nil 则返回字符串 “nil”,否则返回字符串格式类似于 (UIView *) ++ (NSString *)descriptionOfObject:(id)object; + +/// 返回当前的bundle ++ (NSBundle *)bundle; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.m new file mode 100644 index 00000000..8a0368f4 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_Helper.m @@ -0,0 +1,38 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_Helper.m +// LookinServer +// +// Created by Li Kai on 2019/7/20. +// https://lookin.work +// + +#import "LKS_Helper.h" +#import "NSObject+LookinServer.h" + +@implementation LKS_Helper + ++ (NSString *)descriptionOfObject:(id)object { + if (!object) { + return @"nil"; + } + NSString *className = NSStringFromClass([object class]); + return [NSString stringWithFormat:@"(%@ *)", className]; +} + ++ (NSBundle *)bundle { + static id bundle = nil; + if (bundle != nil) { +#ifdef SPM_RESOURCE_BUNDLE_IDENTIFITER + bundle = [NSBundle bundleWithIdentifier:SPM_RESOURCE_BUNDLE_IDENTIFITER]; +#else + bundle = [NSBundle bundleForClass:self.class]; +#endif + } + return bundle; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.h new file mode 100644 index 00000000..6e9bbe09 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.h @@ -0,0 +1,31 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_HierarchyDisplayItemsMaker.h +// LookinServer +// +// Created by Li Kai on 2019/2/19. +// https://lookin.work +// + + + +#import "LookinDefines.h" + +@class LookinDisplayItem; + +@interface LKS_HierarchyDisplayItemsMaker : NSObject + +/// @param hasScreenshots 是否包含 soloScreenshots 和 groupScreenshot 属性 +/// @param hasAttrList 是否包含 attributesGroupList 属性 +/// @param lowQuality screenshots 是否为低质量(当 hasScreenshots 为 NO 时,该属性无意义) +/// @param readCustomInfo 是否读取 lookin_customDebugInfos,比如低版本的 Lookin 发请求时,就无需读取(因为 Lookin 解析不了、还可能出 Bug) +/// @param saveCustomSetter 是否要读取并保存用户给 attribute 配置的 custom setter ++ (NSArray *)itemsWithScreenshots:(BOOL)hasScreenshots attrList:(BOOL)hasAttrList lowImageQuality:(BOOL)lowQuality readCustomInfo:(BOOL)readCustomInfo saveCustomSetter:(BOOL)saveCustomSetter; + +/// 把 layer 的 sublayers 转换为 displayItem 数组并返回 ++ (NSArray *)subitemsOfLayer:(CALayer *)layer; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.m new file mode 100644 index 00000000..4207a43c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_HierarchyDisplayItemsMaker.m @@ -0,0 +1,162 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_HierarchyDisplayItemsMaker.m +// LookinServer +// +// Created by Li Kai on 2019/2/19. +// https://lookin.work +// + +#import "LKS_HierarchyDisplayItemsMaker.h" +#import "LookinDisplayItem.h" +#import "LKS_TraceManager.h" +#import "LKS_AttrGroupsMaker.h" +#import "LKS_EventHandlerMaker.h" +#import "LookinServerDefines.h" +#import "UIColor+LookinServer.h" +#import "LKSConfigManager.h" +#import "LKS_CustomAttrGroupsMaker.h" +#import "LKS_CustomDisplayItemsMaker.h" +#import "LKS_CustomAttrSetterManager.h" +#import "LKS_MultiplatformAdapter.h" + +@implementation LKS_HierarchyDisplayItemsMaker + ++ (NSArray *)itemsWithScreenshots:(BOOL)hasScreenshots attrList:(BOOL)hasAttrList lowImageQuality:(BOOL)lowQuality readCustomInfo:(BOOL)readCustomInfo saveCustomSetter:(BOOL)saveCustomSetter { + + [[LKS_TraceManager sharedInstance] reload]; + + NSArray *windows = [LKS_MultiplatformAdapter allWindows]; + NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:windows.count]; + [windows enumerateObjectsUsingBlock:^(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) { + LookinDisplayItem *item = [self _displayItemWithLayer:window.layer screenshots:hasScreenshots attrList:hasAttrList lowImageQuality:lowQuality readCustomInfo:readCustomInfo saveCustomSetter:saveCustomSetter]; + item.representedAsKeyWindow = window.isKeyWindow; + if (item) { + [resultArray addObject:item]; + } + }]; + + return [resultArray copy]; +} + ++ (LookinDisplayItem *)_displayItemWithLayer:(CALayer *)layer screenshots:(BOOL)hasScreenshots attrList:(BOOL)hasAttrList lowImageQuality:(BOOL)lowQuality readCustomInfo:(BOOL)readCustomInfo saveCustomSetter:(BOOL)saveCustomSetter { + if (!layer) { + return nil; + } + + LookinDisplayItem *item = [LookinDisplayItem new]; + CGRect layerFrame = layer.frame; + UIView *hostView = layer.lks_hostView; + if (hostView && hostView.superview) { + layerFrame = [hostView.superview convertRect:layerFrame toView:nil]; + } + if ([self validateFrame:layerFrame]) { + item.frame = layer.frame; + } else { + NSLog(@"LookinServer - The layer frame(%@) seems really weird. Lookin will ignore it to avoid potential render error in Lookin.", NSStringFromCGRect(layer.frame)); + item.frame = CGRectZero; + } + item.bounds = layer.bounds; + if (hasScreenshots) { + item.soloScreenshot = [layer lks_soloScreenshotWithLowQuality:lowQuality]; + item.groupScreenshot = [layer lks_groupScreenshotWithLowQuality:lowQuality]; + item.screenshotEncodeType = LookinDisplayItemImageEncodeTypeNSData; + } + + if (hasAttrList) { + item.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer]; + LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer]; + [maker execute]; + item.customAttrGroupList = [maker getGroups]; + item.customDisplayTitle = [maker getCustomDisplayTitle]; + item.danceuiSource = [maker getDanceUISource]; + } + + item.isHidden = layer.isHidden; + item.alpha = layer.opacity; + item.layerObject = [LookinObject instanceWithObject:layer]; + item.shouldCaptureImage = [LKSConfigManager shouldCaptureScreenshotOfLayer:layer]; + + if (layer.lks_hostView) { + UIView *view = layer.lks_hostView; + item.viewObject = [LookinObject instanceWithObject:view]; + item.eventHandlers = [LKS_EventHandlerMaker makeForView:view]; + item.backgroundColor = view.backgroundColor; + + UIViewController* vc = [view lks_findHostViewController]; + if (vc) { + item.hostViewControllerObject = [LookinObject instanceWithObject:vc]; + } + } else { + item.backgroundColor = [UIColor lks_colorWithCGColor:layer.backgroundColor]; + } + + if (layer.sublayers.count) { + NSArray *sublayers = [layer.sublayers copy]; + NSMutableArray *allSubitems = [NSMutableArray arrayWithCapacity:sublayers.count]; + [sublayers enumerateObjectsUsingBlock:^(__kindof CALayer * _Nonnull sublayer, NSUInteger idx, BOOL * _Nonnull stop) { + LookinDisplayItem *sublayer_item = [self _displayItemWithLayer:sublayer screenshots:hasScreenshots attrList:hasAttrList lowImageQuality:lowQuality readCustomInfo:readCustomInfo saveCustomSetter:saveCustomSetter]; + if (sublayer_item) { + [allSubitems addObject:sublayer_item]; + } + }]; + item.subitems = [allSubitems copy]; + } + if (readCustomInfo) { + NSArray *customSubitems = [[[LKS_CustomDisplayItemsMaker alloc] initWithLayer:layer saveAttrSetter:saveCustomSetter] make]; + if (customSubitems.count > 0) { + if (item.subitems) { + item.subitems = [item.subitems arrayByAddingObjectsFromArray:customSubitems]; + } else { + item.subitems = customSubitems; + } + } + } + + return item; +} + ++ (NSArray *)subitemsOfLayer:(CALayer *)layer { + if (!layer || layer.sublayers.count == 0) { + return @[]; + } + [[LKS_TraceManager sharedInstance] reload]; + + NSMutableArray *resultSubitems = [NSMutableArray array]; + + NSArray *sublayers = [layer.sublayers copy]; + [sublayers enumerateObjectsUsingBlock:^(__kindof CALayer * _Nonnull sublayer, NSUInteger idx, BOOL * _Nonnull stop) { + LookinDisplayItem *sublayer_item = [self _displayItemWithLayer:sublayer screenshots:NO attrList:NO lowImageQuality:NO readCustomInfo:YES saveCustomSetter:YES]; + if (sublayer_item) { + [resultSubitems addObject:sublayer_item]; + } + }]; + + NSArray *customSubitems = [[[LKS_CustomDisplayItemsMaker alloc] initWithLayer:layer saveAttrSetter:YES] make]; + if (customSubitems.count > 0) { + [resultSubitems addObjectsFromArray:customSubitems]; + } + + return resultSubitems; +} + ++ (BOOL)validateFrame:(CGRect)frame { + return !CGRectIsNull(frame) && !CGRectIsInfinite(frame) && ![self cgRectIsNaN:frame] && ![self cgRectIsInf:frame] && ![self cgRectIsUnreasonable:frame]; +} + ++ (BOOL)cgRectIsNaN:(CGRect)rect { + return isnan(rect.origin.x) || isnan(rect.origin.y) || isnan(rect.size.width) || isnan(rect.size.height); +} + ++ (BOOL)cgRectIsInf:(CGRect)rect { + return isinf(rect.origin.x) || isinf(rect.origin.y) || isinf(rect.size.width) || isinf(rect.size.height); +} + ++ (BOOL)cgRectIsUnreasonable:(CGRect)rect { + return ABS(rect.origin.x) > 100000 || ABS(rect.origin.y) > 100000 || rect.size.width < 0 || rect.size.height < 0 || rect.size.width > 100000 || rect.size.height > 100000; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.h new file mode 100644 index 00000000..dc13f647 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.h @@ -0,0 +1,30 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_MultiplatformAdapter.h +// +// +// Created by nixjiang on 2024/3/12. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface LKS_MultiplatformAdapter : NSObject + ++ (UIWindow *)keyWindow; + ++ (NSArray *)allWindows; + ++ (CGRect)mainScreenBounds; + ++ (CGFloat)mainScreenScale; + ++ (BOOL)isiPad; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.m new file mode 100644 index 00000000..8c04b98d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_MultiplatformAdapter.m @@ -0,0 +1,92 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LKS_MultiplatformAdapter.m +// +// +// Created by nixjiang on 2024/3/12. +// + +#import "LKS_MultiplatformAdapter.h" +#import + +@implementation LKS_MultiplatformAdapter + ++ (BOOL)isiPad { + static BOOL s_isiPad = NO; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *nsModel = [UIDevice currentDevice].model; + s_isiPad = [nsModel hasPrefix:@"iPad"]; + }); + + return s_isiPad; +} + ++ (CGRect)mainScreenBounds { +#if TARGET_OS_VISION + return [LKS_MultiplatformAdapter getFirstActiveWindowScene].coordinateSpace.bounds; +#else + return [UIScreen mainScreen].bounds; +#endif +} + ++ (CGFloat)mainScreenScale { +#if TARGET_OS_VISION + return 2.f; +#else + return [UIScreen mainScreen].scale; +#endif +} + +#if TARGET_OS_VISION ++ (UIWindowScene *)getFirstActiveWindowScene { + for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { + if (![scene isKindOfClass:UIWindowScene.class]) { + continue; + } + UIWindowScene *windowScene = (UIWindowScene *)scene; + if (windowScene.activationState == UISceneActivationStateForegroundActive) { + return windowScene; + } + } + return nil; +} +#endif + ++ (UIWindow *)keyWindow { +#if TARGET_OS_VISION + return [self getFirstActiveWindowScene].keyWindow; +#else + return [UIApplication sharedApplication].keyWindow; +#endif +} + ++ (NSArray *)allWindows { +#if TARGET_OS_VISION + NSMutableArray *windows = [NSMutableArray new]; + for (UIScene *scene in + UIApplication.sharedApplication.connectedScenes) { + if (![scene isKindOfClass:UIWindowScene.class]) { + continue; + } + UIWindowScene *windowScene = (UIWindowScene *)scene; + [windows addObjectsFromArray:windowScene.windows]; + + // 以UIModalPresentationFormSheet形式展示的页面由系统私有window承载,不出现在scene.windows,不过可以从scene.keyWindow中获取 + if (![windows containsObject:windowScene.keyWindow]) { + if (![NSStringFromClass(windowScene.keyWindow.class) containsString:@"HUD"]) { + [windows addObject:windowScene.keyWindow]; + } + } + } + + return [windows copy]; +#else + return [[UIApplication sharedApplication].windows copy]; +#endif +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.h new file mode 100644 index 00000000..64a12521 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.h @@ -0,0 +1,23 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_ObjectRegistry.h +// LookinServer +// +// Created by Li Kai on 2019/4/21. +// https://lookin.work +// + +#import + +@interface LKS_ObjectRegistry : NSObject + ++ (instancetype)sharedInstance; + +- (unsigned long)addObject:(NSObject *)object; + +- (NSObject *)objectWithOid:(unsigned long)oid; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.m new file mode 100644 index 00000000..e651cc33 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_ObjectRegistry.m @@ -0,0 +1,62 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_ObjectRegistry.m +// LookinServer +// +// Created by Li Kai on 2019/4/21. +// https://lookin.work +// + +#import "LKS_ObjectRegistry.h" +#import + +@interface LKS_ObjectRegistry () + +@property(nonatomic, strong) NSPointerArray *data; + +@end + +@implementation LKS_ObjectRegistry + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static LKS_ObjectRegistry *instance = nil; + dispatch_once(&onceToken,^{ + instance = [[super allocWithZone:NULL] init]; + }); + return instance; +} + ++ (id)allocWithZone:(struct _NSZone *)zone{ + return [self sharedInstance]; +} + +- (instancetype)init { + if (self = [super init]) { + self.data = [NSPointerArray weakObjectsPointerArray]; + // index 为 0 用 Null 填充 + self.data.count = 1; + } + return self; +} + +- (unsigned long)addObject:(NSObject *)object { + if (!object) { + return 0; + } + [self.data addPointer:(void *)object]; + return self.data.count - 1; +} + +- (NSObject *)objectWithOid:(unsigned long)oid { + if (self.data.count <= oid) { + return nil; + } + id object = [self.data pointerAtIndex:oid]; + return object; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.h b/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.h new file mode 100644 index 00000000..aac9ef7f --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.h @@ -0,0 +1,27 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_TraceManager.h +// LookinServer +// +// Created by Li Kai on 2019/5/5. +// https://lookin.work +// + + + +#import + +@class LookinIvarTrace; + +@interface LKS_TraceManager : NSObject + ++ (instancetype)sharedInstance; + +- (void)reload; + +- (void)addSearchTarger:(id)target; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.m b/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.m new file mode 100644 index 00000000..b90fdf32 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LKS_TraceManager.m @@ -0,0 +1,310 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LKS_TraceManager.m +// LookinServer +// +// Created by Li Kai on 2019/5/5. +// https://lookin.work +// + +#import "LKS_TraceManager.h" +#import +#import "LookinIvarTrace.h" +#import "LookinServerDefines.h" +#import "LookinWeakContainer.h" +#import "LKS_MultiplatformAdapter.h" + +#ifdef LOOKIN_SERVER_SWIFT_ENABLED + +#if __has_include() + #import + #define LOOKIN_SERVER_SWIFT_ENABLED_SUCCESSFULLY +#elif __has_include("LookinServer-Swift.h") + #import "LookinServer-Swift.h" + #define LOOKIN_SERVER_SWIFT_ENABLED_SUCCESSFULLY +#endif + +#endif + +#ifdef SPM_LOOKIN_SERVER_ENABLED +@import LookinServerSwift; +#define LOOKIN_SERVER_SWIFT_ENABLED_SUCCESSFULLY +#endif + +@interface LKS_TraceManager () + +@property(nonatomic, strong) NSMutableArray *searchTargets; + +@end + +@implementation LKS_TraceManager + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static LKS_TraceManager *instance = nil; + dispatch_once(&onceToken,^{ + instance = [[super allocWithZone:NULL] init]; + }); + return instance; +} + ++ (id)allocWithZone:(struct _NSZone *)zone { + return [self sharedInstance]; +} + +- (void)addSearchTarger:(id)target { + if (!target) { + return; + } + if (!self.searchTargets) { + self.searchTargets = [NSMutableArray array]; + } + LookinWeakContainer *container = [LookinWeakContainer containerWithObject:target]; + [self.searchTargets addObject:container]; +} + +- (void)reload { + // 把旧的先都清理掉 + [NSObject lks_clearAllObjectsTraces]; + + [self.searchTargets enumerateObjectsUsingBlock:^(LookinWeakContainer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (!obj.object) { + return; + } + [self _markIVarsInAllClassLevelsOfObject:obj.object]; + }]; + + [[LKS_MultiplatformAdapter allWindows] enumerateObjectsUsingBlock:^(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) { + [self _addTraceForLayersRootedByLayer:window.layer]; + }]; +} + +- (void)_addTraceForLayersRootedByLayer:(CALayer *)layer { + UIView *view = layer.lks_hostView; + + if ([view.superview lks_isChildrenViewOfTabBar]) { + view.lks_isChildrenViewOfTabBar = YES; + } else if ([view isKindOfClass:[UITabBar class]]) { + view.lks_isChildrenViewOfTabBar = YES; + } + + if (view) { + [self _markIVarsInAllClassLevelsOfObject:view]; + UIViewController* vc = [view lks_findHostViewController]; + if (vc) { + [self _markIVarsInAllClassLevelsOfObject:vc]; + } + + [self _buildSpecialTraceForView:view]; + } else { + [self _markIVarsInAllClassLevelsOfObject:layer]; + } + + [[layer.sublayers copy] enumerateObjectsUsingBlock:^(__kindof CALayer * _Nonnull sublayer, NSUInteger idx, BOOL * _Nonnull stop) { + [self _addTraceForLayersRootedByLayer:sublayer]; + }]; +} + +- (void)_buildSpecialTraceForView:(UIView *)view { + UIViewController* vc = [view lks_findHostViewController]; + if (vc) { + view.lks_specialTrace = [NSString stringWithFormat:@"%@.view", NSStringFromClass(vc.class)]; + + } else if ([view isKindOfClass:[UIWindow class]]) { + CGFloat currentWindowLevel = ((UIWindow *)view).windowLevel; + + if (((UIWindow *)view).isKeyWindow) { + view.lks_specialTrace = [NSString stringWithFormat:@"KeyWindow ( Level: %@ )", @(currentWindowLevel)]; + } else { + view.lks_specialTrace = [NSString stringWithFormat:@"WindowLevel: %@", @(currentWindowLevel)]; + } + } else if ([view isKindOfClass:[UITableViewCell class]]) { + ((UITableViewCell *)view).backgroundView.lks_specialTrace = @"cell.backgroundView"; + ((UITableViewCell *)view).accessoryView.lks_specialTrace = @"cell.accessoryView"; + + } else if ([view isKindOfClass:[UITableView class]]) { + UITableView *tableView = (UITableView *)view; + + NSMutableArray *relatedSectionIdx = [NSMutableArray array]; + [[tableView visibleCells] enumerateObjectsUsingBlock:^(__kindof UITableViewCell * _Nonnull cell, NSUInteger idx, BOOL * _Nonnull stop) { + NSIndexPath *indexPath = [tableView indexPathForCell:cell]; + cell.lks_specialTrace = [NSString stringWithFormat:@"{ sec:%@, row:%@ }", @(indexPath.section), @(indexPath.row)]; + + if (![relatedSectionIdx containsObject:@(indexPath.section)]) { + [relatedSectionIdx addObject:@(indexPath.section)]; + } + }]; + + [relatedSectionIdx enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSUInteger secIdx = [obj unsignedIntegerValue]; + UIView *secHeaderView = [tableView headerViewForSection:secIdx]; + secHeaderView.lks_specialTrace = [NSString stringWithFormat:@"sectionHeader { sec: %@ }", @(secIdx)]; + + UIView *secFooterView = [tableView footerViewForSection:secIdx]; + secFooterView.lks_specialTrace = [NSString stringWithFormat:@"sectionFooter { sec: %@ }", @(secIdx)]; + }]; + + } else if ([view isKindOfClass:[UICollectionView class]]) { + UICollectionView *collectionView = (UICollectionView *)view; + collectionView.backgroundView.lks_specialTrace = @"collectionView.backgroundView"; + + if (@available(iOS 9.0, *)) { + [[collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { + UIView *headerView = [collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:indexPath]; + headerView.lks_specialTrace = [NSString stringWithFormat:@"sectionHeader { sec:%@ }", @(indexPath.section)]; + }]; + [[collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionFooter] enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { + UIView *footerView = [collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:indexPath]; + footerView.lks_specialTrace = [NSString stringWithFormat:@"sectionFooter { sec:%@ }", @(indexPath.section)]; + }]; + } + + [[collectionView visibleCells] enumerateObjectsUsingBlock:^(__kindof UICollectionViewCell * _Nonnull cell, NSUInteger idx, BOOL * _Nonnull stop) { + NSIndexPath *indexPath = [collectionView indexPathForCell:cell]; + cell.lks_specialTrace = [NSString stringWithFormat:@"{ item:%@, sec:%@ }", @(indexPath.item), @(indexPath.section)]; + }]; + + } else if ([view isKindOfClass:[UITableViewHeaderFooterView class]]) { + UITableViewHeaderFooterView *headerFooterView = (UITableViewHeaderFooterView *)view; + headerFooterView.textLabel.lks_specialTrace = @"sectionHeaderFooter.textLabel"; + headerFooterView.detailTextLabel.lks_specialTrace = @"sectionHeaderFooter.detailTextLabel"; + } +} + +- (void)_markIVarsInAllClassLevelsOfObject:(NSObject *)object { + [self _markIVarsOfObject:object class:object.class]; +#ifdef LOOKIN_SERVER_SWIFT_ENABLED_SUCCESSFULLY + [LKS_SwiftTraceManager swiftMarkIVarsOfObject:object]; +#endif +} + +- (void)_markIVarsOfObject:(NSObject *)hostObject class:(Class)targetClass { + if (!targetClass) { + return; + } + + NSArray *prefixesToTerminateRecursion = @[@"NSObject", @"UIResponder", @"UIButton", @"UIButtonLabel"]; + BOOL hasPrefix = [prefixesToTerminateRecursion lookin_any:^BOOL(NSString *prefix) { + return [NSStringFromClass(targetClass) hasPrefix:prefix]; + }]; + if (hasPrefix) { + return; + } + + unsigned int outCount = 0; + Ivar *ivars = class_copyIvarList(targetClass, &outCount); + for (unsigned int i = 0; i < outCount; i ++) { + Ivar ivar = ivars[i]; + NSString *ivarType = [[NSString alloc] lookin_safeInitWithUTF8String:ivar_getTypeEncoding(ivar)]; + if (![ivarType hasPrefix:@"@"] || ivarType.length <= 3) { + continue; + } + NSString *ivarClassName = [ivarType substringWithRange:NSMakeRange(2, ivarType.length - 3)]; + Class ivarClass = NSClassFromString(ivarClassName); + if (![ivarClass isSubclassOfClass:[UIView class]] + && ![ivarClass isSubclassOfClass:[CALayer class]] + && ![ivarClass isSubclassOfClass:[UIViewController class]] + && ![ivarClass isSubclassOfClass:[UIGestureRecognizer class]]) { + continue; + } + const char * ivarNameChar = ivar_getName(ivar); + if (!ivarNameChar) { + continue; + } + // 这个 ivarObject 可能的类型:UIView, CALayer, UIViewController, UIGestureRecognizer + NSObject *ivarObject = object_getIvar(hostObject, ivar); + if (!ivarObject || ![ivarObject isKindOfClass:[NSObject class]]) { + continue; + } + + LookinIvarTrace *ivarTrace = [LookinIvarTrace new]; + ivarTrace.hostObject = hostObject; + ivarTrace.hostClassName = [self makeDisplayClassNameWithSuper:targetClass childClass:hostObject.class]; + ivarTrace.ivarName = [[NSString alloc] lookin_safeInitWithUTF8String:ivarNameChar]; + + if (hostObject == ivarObject) { + ivarTrace.relation = LookinIvarTraceRelationValue_Self; + } else if ([hostObject isKindOfClass:[UIView class]]) { + CALayer *ivarLayer = nil; + if ([ivarObject isKindOfClass:[CALayer class]]) { + ivarLayer = (CALayer *)ivarObject; + } else if ([ivarObject isKindOfClass:[UIView class]]) { + ivarLayer = ((UIView *)ivarObject).layer; + } + if (ivarLayer && (ivarLayer.superlayer == ((UIView *)hostObject).layer)) { + ivarTrace.relation = @"superview"; + } + } + + if ([LKS_InvalidIvarTraces() containsObject:ivarTrace]) { + continue; + } + + if (![ivarObject respondsToSelector:@selector(lks_ivarTraces)] || ![ivarObject respondsToSelector:@selector(setLks_ivarTraces:)]) { + continue; + } + if (!ivarObject.lks_ivarTraces) { + ivarObject.lks_ivarTraces = [NSArray array]; + } + if (![ivarObject.lks_ivarTraces containsObject:ivarTrace]) { + ivarObject.lks_ivarTraces = [ivarObject.lks_ivarTraces arrayByAddingObject:ivarTrace]; + } + } + free(ivars); + + Class superClass = [targetClass superclass]; + [self _markIVarsOfObject:hostObject class:superClass]; +} + +// 比如 superClass 可能是 UIView,而 childClass 可能是 UIButton +- (NSString *)makeDisplayClassNameWithSuper:(Class)superClass childClass:(Class)childClass { + NSString *superName = NSStringFromClass(superClass); + if (!childClass) { + return superName; + } + NSString *childName = NSStringFromClass(childClass); + if ([childName isEqualToString:superName]) { + return superName; + } + return [NSString stringWithFormat:@"%@ : %@", childName, superName]; +} + +static NSSet *LKS_InvalidIvarTraces(void) { + static NSSet *list; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableSet *set = [NSMutableSet set]; + + [set addObject:({ + LookinIvarTrace *trace = [LookinIvarTrace new]; + trace.hostClassName = @"UIView"; + trace.ivarName = @"_window"; + trace; + })]; + [set addObject:({ + LookinIvarTrace *trace = [LookinIvarTrace new]; + trace.hostClassName = @"UIViewController"; + trace.ivarName = @"_view"; + trace; + })]; + [set addObject:({ + LookinIvarTrace *trace = [LookinIvarTrace new]; + trace.hostClassName = @"UIView"; + trace.ivarName = @"_viewDelegate"; + trace; + })]; + [set addObject:({ + LookinIvarTrace *trace = [LookinIvarTrace new]; + trace.hostClassName = @"UIViewController"; + trace.ivarName = @"_parentViewController"; + trace; + })]; + list = set.copy; + }); + return list; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Server/Others/LookinServerDefines.h b/Pods/LookinServer/Src/Main/Server/Others/LookinServerDefines.h new file mode 100644 index 00000000..53f7a7c6 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Server/Others/LookinServerDefines.h @@ -0,0 +1,23 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinServer_PrefixHeader.pch +// LookinServer +// +// Created by Li Kai on 2018/12/21. +// https://lookin.work +// + +#import "TargetConditionals.h" +#import "LookinDefines.h" +#import "LKS_Helper.h" +#import "NSObject+LookinServer.h" +#import "NSArray+Lookin.h" +#import "NSSet+Lookin.h" +#import "CALayer+Lookin.h" +#import "UIView+LookinServer.h" +#import "CALayer+LookinServer.h" +#import "NSObject+Lookin.h" +#import "NSString+Lookin.h" + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.h new file mode 100644 index 00000000..815459a7 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.h @@ -0,0 +1,23 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// CALayer+Lookin.h +// Lookin +// +// Created by Li Kai on 2018/8/4. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import + +@interface CALayer (Lookin) + +- (void)lookin_removeImplicitAnimations; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.m new file mode 100644 index 00000000..e756fc49 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/CALayer+Lookin.m @@ -0,0 +1,70 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// CALayer+Lookin.m +// Lookin +// +// Created by Li Kai on 2018/8/4. +// https://lookin.work +// + + + +#import "CALayer+Lookin.h" + +@implementation CALayer (Lookin) + +- (void)lookin_removeImplicitAnimations { + NSMutableDictionary> *actions = @{NSStringFromSelector(@selector(bounds)): [NSNull null], + NSStringFromSelector(@selector(position)): [NSNull null], + NSStringFromSelector(@selector(zPosition)): [NSNull null], + NSStringFromSelector(@selector(anchorPoint)): [NSNull null], + NSStringFromSelector(@selector(anchorPointZ)): [NSNull null], + NSStringFromSelector(@selector(transform)): [NSNull null], + NSStringFromSelector(@selector(sublayerTransform)): [NSNull null], + NSStringFromSelector(@selector(masksToBounds)): [NSNull null], + NSStringFromSelector(@selector(contents)): [NSNull null], + NSStringFromSelector(@selector(contentsRect)): [NSNull null], + NSStringFromSelector(@selector(contentsScale)): [NSNull null], + NSStringFromSelector(@selector(contentsCenter)): [NSNull null], + NSStringFromSelector(@selector(minificationFilterBias)): [NSNull null], + NSStringFromSelector(@selector(backgroundColor)): [NSNull null], + NSStringFromSelector(@selector(cornerRadius)): [NSNull null], + NSStringFromSelector(@selector(borderWidth)): [NSNull null], + NSStringFromSelector(@selector(borderColor)): [NSNull null], + NSStringFromSelector(@selector(opacity)): [NSNull null], + NSStringFromSelector(@selector(compositingFilter)): [NSNull null], + NSStringFromSelector(@selector(filters)): [NSNull null], + NSStringFromSelector(@selector(backgroundFilters)): [NSNull null], + NSStringFromSelector(@selector(shouldRasterize)): [NSNull null], + NSStringFromSelector(@selector(rasterizationScale)): [NSNull null], + NSStringFromSelector(@selector(shadowColor)): [NSNull null], + NSStringFromSelector(@selector(shadowOpacity)): [NSNull null], + NSStringFromSelector(@selector(shadowOffset)): [NSNull null], + NSStringFromSelector(@selector(shadowRadius)): [NSNull null], + NSStringFromSelector(@selector(shadowPath)): [NSNull null]}.mutableCopy; + + if ([self isKindOfClass:[CAShapeLayer class]]) { + [actions addEntriesFromDictionary:@{NSStringFromSelector(@selector(path)): [NSNull null], + NSStringFromSelector(@selector(fillColor)): [NSNull null], + NSStringFromSelector(@selector(strokeColor)): [NSNull null], + NSStringFromSelector(@selector(strokeStart)): [NSNull null], + NSStringFromSelector(@selector(strokeEnd)): [NSNull null], + NSStringFromSelector(@selector(lineWidth)): [NSNull null], + NSStringFromSelector(@selector(miterLimit)): [NSNull null], + NSStringFromSelector(@selector(lineDashPhase)): [NSNull null]}]; + } + + if ([self isKindOfClass:[CAGradientLayer class]]) { + [actions addEntriesFromDictionary:@{NSStringFromSelector(@selector(colors)): [NSNull null], + NSStringFromSelector(@selector(locations)): [NSNull null], + NSStringFromSelector(@selector(startPoint)): [NSNull null], + NSStringFromSelector(@selector(endPoint)): [NSNull null]}]; + } + + self.actions = actions; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.h new file mode 100644 index 00000000..9a49ab90 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.h @@ -0,0 +1,27 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Color+Lookin.h +// LookinShared +// +// Created by 李凯 on 2022/4/2. +// + +#import + +#if TARGET_OS_IPHONE + +#elif TARGET_OS_MAC + +@interface NSColor (Lookin) + ++ (instancetype)lookin_colorFromRGBAComponents:(NSArray *)components; + +- (NSArray *)lookin_rgbaComponents; + +@end + +#endif + + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.m new file mode 100644 index 00000000..4f5ede15 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/Color+Lookin.m @@ -0,0 +1,42 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Color+Lookin.m +// LookinShared +// +// Created by 李凯 on 2022/4/2. +// + +#import "Image+Lookin.h" + +#if TARGET_OS_IPHONE + +#elif TARGET_OS_MAC + +@implementation NSColor (Lookin) + ++ (instancetype)lookin_colorFromRGBAComponents:(NSArray *)components { + if (!components) { + return nil; + } + if (components.count != 4) { + NSAssert(NO, @""); + return nil; + } + NSColor *color = [NSColor colorWithRed:components[0].doubleValue green:components[1].doubleValue blue:components[2].doubleValue alpha:components[3].doubleValue]; + return color; +} + +- (NSArray *)lookin_rgbaComponents { + NSColor *rgbColor = [self colorUsingColorSpace:NSColorSpace.sRGBColorSpace]; + CGFloat r, g, b, a; + [rgbColor getRed:&r green:&g blue:&b alpha:&a]; + NSArray *rgba = @[@(r), @(g), @(b), @(a)]; + return rgba; +} + +@end + +#endif + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.h new file mode 100644 index 00000000..7fe33c88 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.h @@ -0,0 +1,25 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Image+Lookin.h +// LookinShared +// +// Created by 李凯 on 2022/4/2. +// + +#import + +#if TARGET_OS_IPHONE + +#elif TARGET_OS_MAC + +@interface NSImage (LookinClient) + +- (NSData *)lookin_data; + +@end + +#endif + + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.m new file mode 100644 index 00000000..d285d548 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/Image+Lookin.m @@ -0,0 +1,26 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Image+Lookin.m +// LookinShared +// +// Created by 李凯 on 2022/4/2. +// + +#import "Image+Lookin.h" + +#if TARGET_OS_IPHONE + +#elif TARGET_OS_MAC + +@implementation NSImage (LookinClient) + +- (NSData *)lookin_data { + return [self TIFFRepresentation]; +} + +@end + +#endif + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.h new file mode 100644 index 00000000..a66e02a9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.h @@ -0,0 +1,72 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSArray+Lookin.h +// Lookin +// +// Created by Li Kai on 2018/9/3. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import +#import + +@interface NSArray<__covariant ValueType> (Lookin) + +/** + 初始化一个新的 NSArray 并返回,新数组的长度为 count,如果当前数组长度比 count 小则会补充新元素(被补充的元素由 addBlock 返回),如果当前数组长度比 count 大则会舍弃多余的元素,被舍弃的元素会作为参数传入 removeBlock。最终,新数组的所有元素均会作为参数被传入 doBlock。 + */ +- (NSArray *)lookin_resizeWithCount:(NSUInteger)count add:(ValueType (^)(NSUInteger idx))addBlock remove:(void (^)(NSUInteger idx, ValueType obj))removeBlock doNext:(void (^)(NSUInteger idx, ValueType obj))doBlock __attribute__((warn_unused_result)); + ++ (NSArray *)lookin_arrayWithCount:(NSUInteger)count block:(id (^)(NSUInteger idx))block; + +/** + 检查 index 位置是否有元素存在 + */ +- (BOOL)lookin_hasIndex:(NSInteger)index; + +- (NSArray *)lookin_map:(id (^)(NSUInteger idx, ValueType value))block; + +- (NSArray *)lookin_filter:(BOOL (^)( ValueType obj))block; + +- (ValueType)lookin_firstFiltered:(BOOL (^)(ValueType obj))block; + +/// 返回最后一个 block 返回 YES 的元素 +- (ValueType)lookin_lastFiltered:(BOOL (^)(ValueType obj))block; + +- (id)lookin_reduce:(id (^)(id accumulator, NSUInteger idx, ValueType obj))block; + +- (CGFloat)lookin_reduceCGFloat:(CGFloat (^)(CGFloat accumulator, NSUInteger idx, ValueType obj))block initialAccumlator:(CGFloat)initialAccumlator; +- (NSInteger)lookin_reduceInteger:(NSInteger (^)(NSInteger accumulator, NSUInteger idx, ValueType obj))block initialAccumlator:(NSInteger)initialAccumlator; + +- (BOOL)lookin_all:(BOOL (^)(ValueType obj))block; + +- (BOOL)lookin_any:(BOOL (^)(ValueType obj))block; + +- (NSArray *)lookin_arrayByRemovingObject:(ValueType)obj; + +- (NSArray *)lookin_nonredundantArray; + +- (ValueType)lookin_safeObjectAtIndex:(NSInteger)idx; + +/// 字符串长度从短到长,即 length 小的字符串的 idx 更小 +- (NSArray *)lookin_sortedArrayByStringLength; + +@end + +@interface NSMutableArray (Lookin) + +/** + 如果当前数组长度比 count 小则会补充新元素(被补充的元素由 addBlock 返回),如果当前数组长度比 count 大则多余的元素会被作为参数传入 notDequeued。然后从 idx 为 0 算起,前 count 个元素会被作为参数传入 doBlock + */ +- (void)lookin_dequeueWithCount:(NSUInteger)count add:(ValueType (^)(NSUInteger idx))addBlock notDequeued:(void (^)(NSUInteger idx, ValueType obj))notDequeuedBlock doNext:(void (^)(NSUInteger idx, ValueType obj))doBlock; + +- (void)lookin_removeObjectsPassingTest:(BOOL (^)(NSUInteger idx, ValueType obj))block; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.m new file mode 100644 index 00000000..6df614b7 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSArray+Lookin.m @@ -0,0 +1,300 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSArray+Lookin.m +// Lookin +// +// Created by Li Kai on 2018/9/3. +// https://lookin.work +// + + + +#import "NSArray+Lookin.h" + +@implementation NSArray (Lookin) + +- (NSArray *)lookin_resizeWithCount:(NSUInteger)count add:(id (^)(NSUInteger idx))addBlock remove:(void (^)(NSUInteger idx, id obj))removeBlock doNext:(void (^)(NSUInteger idx, id obj))doBlock { + NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:count]; + + for (NSUInteger i = 0; i < count; i++) { + if (self.count > i) { + id obj = [self objectAtIndex:i]; + [resultArray addObject:obj]; + if (doBlock) { + doBlock(i, obj); + } + } else { + if (addBlock) { + id newObj = addBlock(i); + if (newObj) { + [resultArray addObject:newObj]; + if (doBlock) { + doBlock(i, newObj); + } + } else { + NSAssert(NO, @""); + } + } else { + NSAssert(NO, @""); + } + } + } + + if (removeBlock) { + if (self.count > count) { + for (NSUInteger i = count; i < self.count; i++) { + id obj = [self objectAtIndex:i]; + removeBlock(i, obj); + } + } + } + + return [resultArray copy]; +} + ++ (NSArray *)lookin_arrayWithCount:(NSUInteger)count block:(id (^)(NSUInteger idx))block { + NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; + for (NSUInteger i = 0; i < count; i++) { + id obj = block(i); + if (obj) { + [array addObject:obj]; + } + } + return [array copy]; +} + +- (BOOL)lookin_hasIndex:(NSInteger)index { + if (index == NSNotFound || index < 0) { + return NO; + } + return self.count > index; +} + +- (NSArray *)lookin_map:(id (^)(NSUInteger , id))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:self.count]; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + id newObj = block(idx, obj); + if (newObj) { + [array addObject:newObj]; + } + }]; + return [array copy]; +} + +- (NSArray *)lookin_filter:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + NSMutableArray *mArray = [NSMutableArray array]; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (block(obj)) { + [mArray addObject:obj]; + } + }]; + return [mArray copy]; +} + +- (id)lookin_firstFiltered:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + __block id targetObj = nil; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (block(obj)) { + targetObj = obj; + *stop = YES; + } + }]; + return targetObj; +} + +- (id)lookin_lastFiltered:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + __block id targetObj = nil; + [self enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (block(obj)) { + targetObj = obj; + *stop = YES; + } + }]; + return targetObj; +} + +- (id)lookin_reduce:(id (^)(id accumulator, NSUInteger idx, id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + __block id accumulator = nil; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + accumulator = block(accumulator, idx, obj); + }]; + return accumulator; +} + +- (CGFloat)lookin_reduceCGFloat:(CGFloat (^)(CGFloat accumulator, NSUInteger idx, id obj))block initialAccumlator:(CGFloat)initialAccumlator { + if (!block) { + NSAssert(NO, @""); + return initialAccumlator; + } + + __block CGFloat accumulator = initialAccumlator; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + accumulator = block(accumulator, idx, obj); + }]; + return accumulator; +} + +- (NSInteger)lookin_reduceInteger:(NSInteger (^)(NSInteger, NSUInteger, id))block initialAccumlator:(NSInteger)initialAccumlator { + if (!block) { + NSAssert(NO, @""); + return initialAccumlator; + } + + __block NSInteger accumulator = initialAccumlator; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + accumulator = block(accumulator, idx, obj); + }]; + return accumulator; +} + +- (BOOL)lookin_all:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return NO; + } + __block BOOL allPass = YES; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + BOOL boolValue = block(obj); + if (!boolValue) { + allPass = NO; + *stop = YES; + } + }]; + return allPass; +} + +- (BOOL)lookin_any:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return NO; + } + __block BOOL anyPass = NO; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + BOOL boolValue = block(obj); + if (boolValue) { + anyPass = YES; + *stop = YES; + } + }]; + return anyPass; +} + +- (NSArray *)lookin_arrayByRemovingObject:(id)obj { + if (!obj || ![self containsObject:obj]) { + return self; + } + NSMutableArray *mutableArray = self.mutableCopy; + [mutableArray removeObject:obj]; + return mutableArray.copy; +} + +- (NSArray *)lookin_nonredundantArray { + NSSet *set = [NSSet setWithArray:self]; + NSArray *newArray = [set allObjects]; + return newArray; +} + +- (id)lookin_safeObjectAtIndex:(NSInteger)idx { + if (idx == NSNotFound || idx < 0) { + return nil; + } + if (self.count <= idx) { + return nil; + } + return [self objectAtIndex:idx]; +} + +- (NSArray *)lookin_sortedArrayByStringLength { + NSArray *sortedArray = [self sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { + if (obj1.length > obj2.length) { + return NSOrderedDescending; + } else if (obj1.length == obj2.length) { + return NSOrderedSame; + } else { + return NSOrderedAscending; + } + }]; + return sortedArray; +} + +@end + +@implementation NSMutableArray (Lookin) + +- (void)lookin_dequeueWithCount:(NSUInteger)count add:(id (^)(NSUInteger idx))addBlock notDequeued:(void (^)(NSUInteger idx, id obj))notDequeuedBlock doNext:(void (^)(NSUInteger idx, id obj))doBlock { + for (NSUInteger i = 0; i < count; i++) { + if ([self lookin_hasIndex:i]) { + id obj = [self objectAtIndex:i]; + if (doBlock) { + doBlock(i, obj); + } + } else { + if (addBlock) { + id newObj = addBlock(i); + if (newObj) { + [self addObject:newObj]; + if (doBlock) { + doBlock(i, newObj); + } + } else { + NSAssert(NO, @""); + } + } else { + NSAssert(NO, @""); + } + } + } + + if (notDequeuedBlock) { + if (self.count > count) { + for (NSUInteger i = count; i < self.count; i++) { + id obj = [self objectAtIndex:i]; + notDequeuedBlock(i, obj); + } + } + } +} + +- (void)lookin_removeObjectsPassingTest:(BOOL (^)(NSUInteger idx, id obj))block { + if (!block) { + return; + } + NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet]; + [self enumerateObjectsUsingBlock:^(id _Nonnull currentObj, NSUInteger idx, BOOL * _Nonnull stop) { + BOOL boolValue = block(idx, currentObj); + if (boolValue) { + [indexSet addIndex:idx]; + } + }]; + [self removeObjectsAtIndexes:indexSet]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.h new file mode 100644 index 00000000..c8839cf1 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.h @@ -0,0 +1,108 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSObject+Lookin.h +// Lookin +// +// Created by Li Kai on 2018/12/22. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import +#import "LookinCodingValueType.h" + +@interface NSObject (Lookin) + +#pragma mark - Data Bind + +/** + 给对象绑定上另一个对象以供后续取出使用,如果 object 传入 nil 则会清除该 key 之前绑定的对象 + + @attention 被绑定的对象会被 strong 强引用 + @note 内部是使用 objc_setAssociatedObject / objc_getAssociatedObject 来实现 + + @code + - (UITableViewCell *)cellForIndexPath:(NSIndexPath *)indexPath { + // 1)在这里给 button 绑定上 indexPath 对象 + [cell lookin_bindObject:indexPath forKey:@"indexPath"]; + } + + - (void)didTapButton:(UIButton *)button { + // 2)在这里取出被点击的 button 的 indexPath 对象 + NSIndexPath *indexPathTapped = [button lookin_getBindObjectForKey:@"indexPath"]; + } + @endcode + */ +- (void)lookin_bindObject:(id)object forKey:(NSString *)key; + +/** + 给对象绑定上另一个对象以供后续取出使用,但相比于 lookin_bindObject:forKey:,该方法不会 strong 强引用传入的 object + */ +- (void)lookin_bindObjectWeakly:(id)object forKey:(NSString *)key; + +/** + 取出之前使用 bind 方法绑定的对象 + */ +- (id)lookin_getBindObjectForKey:(NSString *)key; + +/** + 给对象绑定上一个 double 值以供后续取出使用 + */ +- (void)lookin_bindDouble:(double)doubleValue forKey:(NSString *)key; + +/** + 取出之前用 lookin_bindDouble:forKey: 绑定的值 + */ +- (double)lookin_getBindDoubleForKey:(NSString *)key; + +/** + 给对象绑定上一个 BOOL 值以供后续取出使用 + */ +- (void)lookin_bindBOOL:(BOOL)boolValue forKey:(NSString *)key; + +/** + 取出之前用 lookin_bindBOOL:forKey: 绑定的值 + */ +- (BOOL)lookin_getBindBOOLForKey:(NSString *)key; + +/** + 给对象绑定上一个 long 值以供后续取出使用 + */ +- (void)lookin_bindLong:(long)longValue forKey:(NSString *)key; + +/** + 取出之前用 lookin_bindLong:forKey: 绑定的值 + */ +- (long)lookin_getBindLongForKey:(NSString *)key; + +/** + 给对象绑定上一个 CGPoint 值以供后续取出使用 + */ +- (void)lookin_bindPoint:(CGPoint)pointValue forKey:(NSString *)key; + +/** + 取出之前用 lookin_bindPoint:forKey: 绑定的值 + */ +- (CGPoint)lookin_getBindPointForKey:(NSString *)key; + +/** + 移除之前使用 bind 方法绑定的对象 + */ +- (void)lookin_clearBindForKey:(NSString *)key; + +@end + +@interface NSObject (Lookin_Coding) + +/// 会把 NSImage/UIImage 转换为 NSData,把 NSColor/UIColor 转换回 NSNumber 数组(rgba) +- (id)lookin_encodedObjectWithType:(LookinCodingValueType)type; +/// 会把 NSData 转换回 NSImage/UIImage,把 NSNumber 数组(rgba) 转换为 NSColor/UIColor +- (id)lookin_decodedObjectWithType:(LookinCodingValueType)type; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.m new file mode 100644 index 00000000..d206613d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSObject+Lookin.m @@ -0,0 +1,238 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSObject+Lookin.m +// Lookin +// +// Created by Li Kai on 2018/12/22. +// https://lookin.work +// + +#import "NSObject+Lookin.h" +#import +#import "TargetConditionals.h" +#import "LookinWeakContainer.h" + +@implementation NSObject (Lookin) + +#pragma mark - Data Bind + +static char kAssociatedObjectKey_LookinAllBindObjects; +- (NSMutableDictionary *)lookin_allBindObjects { + NSMutableDictionary *dict = objc_getAssociatedObject(self, &kAssociatedObjectKey_LookinAllBindObjects); + if (!dict) { + dict = [NSMutableDictionary dictionary]; + objc_setAssociatedObject(self, &kAssociatedObjectKey_LookinAllBindObjects, dict, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return dict; +} + +- (void)lookin_bindObject:(id)object forKey:(NSString *)key { + if (!key.length) { + NSAssert(NO, @""); + return; + } + @synchronized (self) { + if (object) { + [[self lookin_allBindObjects] setObject:object forKey:key]; + } else { + [[self lookin_allBindObjects] removeObjectForKey:key]; + } + } +} + +- (id)lookin_getBindObjectForKey:(NSString *)key { + if (!key.length) { + NSAssert(NO, @""); + return nil; + } + @synchronized (self) { + id storedObj = [[self lookin_allBindObjects] objectForKey:key]; + if ([storedObj isKindOfClass:[LookinWeakContainer class]]) { + storedObj = [(LookinWeakContainer *)storedObj object]; + } + return storedObj; + } +} + +- (void)lookin_bindObjectWeakly:(id)object forKey:(NSString *)key { + if (!key.length) { + NSAssert(NO, @""); + return; + } + if (object) { + LookinWeakContainer *container = [[LookinWeakContainer alloc] init]; + container.object = object; + [self lookin_bindObject:container forKey:key]; + } else { + [self lookin_bindObject:nil forKey:key]; + } +} + +- (void)lookin_bindDouble:(double)doubleValue forKey:(NSString *)key { + [self lookin_bindObject:@(doubleValue) forKey:key]; +} + +- (double)lookin_getBindDoubleForKey:(NSString *)key { + id object = [self lookin_getBindObjectForKey:key]; + if ([object isKindOfClass:[NSNumber class]]) { + double doubleValue = [(NSNumber *)object doubleValue]; + return doubleValue; + + } else { + return 0.0; + } +} + +- (void)lookin_bindBOOL:(BOOL)boolValue forKey:(NSString *)key { + [self lookin_bindObject:@(boolValue) forKey:key]; +} + +- (BOOL)lookin_getBindBOOLForKey:(NSString *)key { + id object = [self lookin_getBindObjectForKey:key]; + if ([object isKindOfClass:[NSNumber class]]) { + BOOL boolValue = [(NSNumber *)object boolValue]; + return boolValue; + + } else { + return NO; + } +} + +- (void)lookin_bindLong:(long)longValue forKey:(NSString *)key { + [self lookin_bindObject:@(longValue) forKey:key]; +} + +- (long)lookin_getBindLongForKey:(NSString *)key { + id object = [self lookin_getBindObjectForKey:key]; + if ([object isKindOfClass:[NSNumber class]]) { + long longValue = [(NSNumber *)object longValue]; + return longValue; + + } else { + return 0; + } +} + +- (void)lookin_bindPoint:(CGPoint)pointValue forKey:(NSString *)key { +#if TARGET_OS_IPHONE + [self lookin_bindObject:[NSValue valueWithCGPoint:pointValue] forKey:key]; +#elif TARGET_OS_MAC + NSPoint nsPoint = NSMakePoint(pointValue.x, pointValue.y); + [self lookin_bindObject:[NSValue valueWithPoint:nsPoint] forKey:key]; +#endif +} + +- (CGPoint)lookin_getBindPointForKey:(NSString *)key { + id object = [self lookin_getBindObjectForKey:key]; + if ([object isKindOfClass:[NSValue class]]) { +#if TARGET_OS_IPHONE + CGPoint pointValue = [(NSValue *)object CGPointValue]; +#elif TARGET_OS_MAC + NSPoint nsPointValue = [(NSValue *)object pointValue]; + CGPoint pointValue = CGPointMake(nsPointValue.x, nsPointValue.y); +#endif + return pointValue; + } else { + return CGPointZero; + } +} + +- (void)lookin_clearBindForKey:(NSString *)key { + [self lookin_bindObject:nil forKey:key]; +} + +@end + +@implementation NSObject (Lookin_Coding) + +- (id)lookin_encodedObjectWithType:(LookinCodingValueType)type { + if (type == LookinCodingValueTypeColor) { + if ([self isKindOfClass:[LookinColor class]]) { + CGFloat r, g, b, a; +#if TARGET_OS_IPHONE + CGFloat white; + if ([(UIColor *)self getRed:&r green:&g blue:&b alpha:&a]) { + // valid + } else if ([(UIColor *)self getWhite:&white alpha:&a]) { + r = white; + g = white; + b = white; + } else { + NSAssert(NO, @""); + r = 0; + g = 0; + b = 0; + a = 0; + } +#elif TARGET_OS_MAC + NSColor *color = [((NSColor *)self) colorUsingColorSpace:NSColorSpace.sRGBColorSpace]; + [color getRed:&r green:&g blue:&b alpha:&a]; +#endif + NSArray *rgba = @[@(r), @(g), @(b), @(a)]; + return rgba; + + } else { + NSAssert(NO, @""); + return nil; + } + + } else if (type == LookinCodingValueTypeImage) { +#if TARGET_OS_IPHONE + if ([self isKindOfClass:[UIImage class]]) { + UIImage *image = (UIImage *)self; + return UIImagePNGRepresentation(image); + + } else { + NSAssert(NO, @""); + return nil; + } +#elif TARGET_OS_MAC + if ([self isKindOfClass:[NSImage class]]) { + NSImage *image = (NSImage *)self; + return [image TIFFRepresentation]; + + } else { + NSAssert(NO, @""); + return nil; + } +#endif + + } else { + return self; + } +} + +- (id)lookin_decodedObjectWithType:(LookinCodingValueType)type { + if (type == LookinCodingValueTypeColor) { + if ([self isKindOfClass:[NSArray class]]) { + NSArray *rgba = (NSArray *)self; + CGFloat r = [rgba[0] doubleValue]; + CGFloat g = [rgba[1] doubleValue]; + CGFloat b = [rgba[2] doubleValue]; + CGFloat a = [rgba[3] doubleValue]; + LookinColor *color = [LookinColor colorWithRed:r green:g blue:b alpha:a]; + return color; + + } else { + NSAssert(NO, @""); + return nil; + } + + } else if (type == LookinCodingValueTypeImage) { + if ([self isKindOfClass:[NSData class]]) { + LookinImage *image = [[LookinImage alloc] initWithData:(NSData *)self]; + return image; + } else { + NSAssert(NO, @""); + return nil; + } + + } else { + return self; + } +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.h new file mode 100644 index 00000000..f09a7041 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.h @@ -0,0 +1,39 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSSet+Lookin.h +// Lookin +// +// Created by Li Kai on 2019/1/13. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import "TargetConditionals.h" +#if TARGET_OS_IPHONE +#import +#elif TARGET_OS_MAC +#import +#endif + +@interface NSSet<__covariant ValueType> (Lookin) + +- (NSSet *)lookin_map:(id (^)(ValueType obj))block; + +- (ValueType)lookin_firstFiltered:(BOOL (^)(ValueType obj))block; + +- (NSSet *)lookin_filter:(BOOL (^)(ValueType obj))block; + + +/** + 是否有任何一个元素满足某条件 + @note 元素将被依次传入 block 里,如果任何一个 block 返回 YES,则该方法返回 YES。如果所有 block 均返回 NO,则该方法返回 NO。 + */ +- (BOOL)lookin_any:(BOOL (^)(ValueType obj))block; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.m new file mode 100644 index 00000000..1ec9edf2 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSSet+Lookin.m @@ -0,0 +1,81 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSSet+Lookin.m +// Lookin +// +// Created by Li Kai on 2019/1/13. +// https://lookin.work +// + + + +#import "NSSet+Lookin.h" + +@implementation NSSet (Lookin) + +- (NSSet *)lookin_map:(id (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + NSMutableSet *newSet = [NSMutableSet setWithCapacity:self.count]; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { + id newObj = block(obj); + if (newObj) { + [newSet addObject:newObj]; + } + }]; + return [newSet copy]; +} + +- (id)lookin_firstFiltered:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + __block id targetObj = nil; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { + if (block(obj)) { + targetObj = obj; + *stop = YES; + } + }]; + return targetObj; +} + +- (NSSet *)lookin_filter:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return nil; + } + + NSMutableSet *mSet = [NSMutableSet set]; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { + if (block(obj)) { + [mSet addObject:obj]; + } + }]; + return [mSet copy]; +} + +- (BOOL)lookin_any:(BOOL (^)(id obj))block { + if (!block) { + NSAssert(NO, @""); + return NO; + } + __block BOOL boolValue = NO; + [self enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { + if (block(obj)) { + boolValue = YES; + *stop = YES; + } + }]; + return boolValue; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.h b/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.h new file mode 100644 index 00000000..15f11717 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.h @@ -0,0 +1,42 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSString+Lookin.h +// Lookin +// +// Created by Li Kai on 2019/5/11. +// https://lookin.work +// + +#import "LookinDefines.h" + + + +#import + +@interface NSString (Lookin) + +/** + 把 CGFloat 转成字符串,最多保留 3 位小数,转换后末尾的 0 会被删除 + 如:1.2341 => @"1.234", 2.1002 => @"2.1", 3.000 => @"3" + */ ++ (NSString *)lookin_stringFromDouble:(double)doubleValue decimal:(NSUInteger)decimal; + ++ (NSString *)lookin_stringFromRect:(CGRect)rect; + ++ (NSString *)lookin_stringFromInset:(LookinInsets)insets; + ++ (NSString *)lookin_stringFromSize:(CGSize)size; + ++ (NSString *)lookin_stringFromPoint:(CGPoint)point; + ++ (NSString *)lookin_rgbaStringFromColor:(LookinColor *)color; + +- (NSString *)lookin_safeInitWithUTF8String:(const char *)string; + +/// 把 1.2.3 这种 String 版本号转换成数字,可用于大小比较,如 110205 代表 11.2.5 版本 +- (NSInteger)lookin_numbericOSVersion; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.m b/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.m new file mode 100644 index 00000000..9b76fb59 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Category/NSString+Lookin.m @@ -0,0 +1,117 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// NSString+Lookin.m +// Lookin +// +// Created by Li Kai on 2019/5/11. +// https://lookin.work +// + + + +#import "NSString+Lookin.h" + +@implementation NSString (Lookin) + ++ (NSString *)lookin_stringFromDouble:(double)doubleValue decimal:(NSUInteger)decimal { + NSString *formatString = [NSString stringWithFormat:@"%%.%@f", @(decimal)]; + NSString *string = [NSString stringWithFormat:formatString, doubleValue]; + for (int i = 0; i < decimal; i++) { + if ([[string substringFromIndex:string.length - 1] isEqualToString:@"0"]) { + string = [string substringToIndex:string.length - 1]; + } + } + if ([[string substringFromIndex:string.length - 1] isEqualToString:@"."]) { + string = [string substringToIndex:string.length - 1]; + } + return string; +} + ++ (NSString *)lookin_stringFromInset:(LookinInsets)insets { + return [NSString stringWithFormat:@"{%@, %@, %@, %@}", + [NSString lookin_stringFromDouble:insets.top decimal:2], + [NSString lookin_stringFromDouble:insets.left decimal:2], + [NSString lookin_stringFromDouble:insets.bottom decimal:2], + [NSString lookin_stringFromDouble:insets.right decimal:2]]; +} + ++ (NSString *)lookin_stringFromSize:(CGSize)size { + return [NSString stringWithFormat:@"{%@, %@}", + [NSString lookin_stringFromDouble:size.width decimal:2], + [NSString lookin_stringFromDouble:size.height decimal:2]]; +} + + ++ (NSString *)lookin_stringFromPoint:(CGPoint)point { + return [NSString stringWithFormat:@"{%@, %@}", + [NSString lookin_stringFromDouble:point.x decimal:2], + [NSString lookin_stringFromDouble:point.y decimal:2]]; +} + ++ (NSString *)lookin_stringFromRect:(CGRect)rect { + return [NSString stringWithFormat:@"{%@, %@, %@, %@}", + [NSString lookin_stringFromDouble:rect.origin.x decimal:2], + [NSString lookin_stringFromDouble:rect.origin.y decimal:2], + [NSString lookin_stringFromDouble:rect.size.width decimal:2], + [NSString lookin_stringFromDouble:rect.size.height decimal:2]]; +} + ++ (NSString *)lookin_rgbaStringFromColor:(LookinColor *)color { + if (!color) { + return @"nil"; + } + +#if TARGET_OS_IPHONE + UIColor *rgbColor = color; +#elif TARGET_OS_MAC + NSColor *rgbColor = [color colorUsingColorSpace:NSColorSpace.sRGBColorSpace]; +#endif + + CGFloat r, g, b, a; + [rgbColor getRed:&r green:&g blue:&b alpha:&a]; + + NSString *colorDesc; + if (a >= 1) { + colorDesc = [NSString stringWithFormat:@"(%.0f, %.0f, %.0f)", r * 255, g * 255, b * 255]; + } else { + colorDesc = [NSString stringWithFormat:@"(%.0f, %.0f, %.0f, %@)", r * 255, g * 255, b * 255, [NSString lookin_stringFromDouble:a decimal:2]]; + + } + + return colorDesc; +} + +- (NSString *)lookin_safeInitWithUTF8String:(const char *)string { + if (NULL != string) { + return [self initWithUTF8String:string]; + } + return nil; +} + +- (NSInteger)lookin_numbericOSVersion { + if (self.length == 0) { + NSAssert(NO, @""); + return 0; + } + NSArray *versionArr = [self componentsSeparatedByString:@"."]; + if (versionArr.count != 3) { + NSAssert(NO, @""); + return 0; + } + + NSInteger numbericOSVersion = 0; + NSInteger pos = 0; + + while ([versionArr count] > pos && pos < 3) { + numbericOSVersion += ([[versionArr objectAtIndex:pos] integerValue] * pow(10, (4 - pos * 2))); + pos++; + } + + return numbericOSVersion; +} + + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.h b/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.h new file mode 100644 index 00000000..1082d12d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.h @@ -0,0 +1,72 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAppInfo.h +// qmuidemo +// +// Created by Li Kai on 2018/11/3. +// Copyright © 2018 QMUI Team. All rights reserved. +// + + + +#import "LookinDefines.h" + +typedef NS_ENUM(NSInteger, LookinAppInfoDevice) { + LookinAppInfoDeviceSimulator, // 模拟器 + LookinAppInfoDeviceIPad, // iPad 真机 + LookinAppInfoDeviceOthers // 应该视为 iPhone 真机 +}; + +@interface LookinAppInfo : NSObject + +/// 每次启动 app 时都会随机生成一个 appInfoIdentifier 直到 app 被 kill 掉 +@property(nonatomic, assign) NSUInteger appInfoIdentifier; +/// mac 端应该先读取该属性,如果为 YES 则表示应该使用之前保存的旧 appInfo 对象即可 +@property(nonatomic, assign) BOOL shouldUseCache; +/// LookinServer 的版本 +@property(nonatomic, assign) int serverVersion; +/// 类似 "1.1.9",只在 1.2.3 以及之后的 LookinServer 版本里有值 +@property(nonatomic, assign) NSString *serverReadableVersion; +/// 如果 iOS 侧使用了 SPM 或引入了 Swift Subspec,则该属性为 1 +/// 如果 iOS 侧没使用,则该属性为 -1 +/// 如果不知道,则该属性为 0 +@property(nonatomic, assign) int swiftEnabledInLookinServer; +/// app 的当前截图 +@property(nonatomic, strong) LookinImage *screenshot; +/// 可能为 nil,比如新建的 iOS 空项目 +@property(nonatomic, strong) LookinImage *appIcon; +/// @"微信读书" +@property(nonatomic, copy) NSString *appName; +/// hughkli.lookin +@property(nonatomic, copy) NSString *appBundleIdentifier; +/// @"iPhone X" +@property(nonatomic, copy) NSString *deviceDescription; +/// @"12.1" +@property(nonatomic, copy) NSString *osDescription; +/// 返回 os 的主版本号,比如 iOS 12.1 的设备将返回 12,iOS 13.2.1 的设备将返回 13 +@property(nonatomic, assign) NSUInteger osMainVersion; +/// 设备类型 +@property(nonatomic, assign) LookinAppInfoDevice deviceType; +/// 屏幕的宽度 +@property(nonatomic, assign) double screenWidth; +/// 屏幕的高度 +@property(nonatomic, assign) double screenHeight; +/// 是几倍的屏幕 +@property(nonatomic, assign) double screenScale; + +- (BOOL)isEqualToAppInfo:(LookinAppInfo *)info; + +#if TARGET_OS_IPHONE + ++ (LookinAppInfo *)currentInfoWithScreenshot:(BOOL)hasScreenshot icon:(BOOL)hasIcon localIdentifiers:(NSArray *)localIdentifiers; + +#else + +@property(nonatomic, assign) NSTimeInterval cachedTimestamp; + +#endif + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.m b/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.m new file mode 100644 index 00000000..b1c0c501 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAppInfo.m @@ -0,0 +1,242 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAppInfo.m +// qmuidemo +// +// Created by Li Kai on 2018/11/3. +// Copyright © 2018 QMUI Team. All rights reserved. +// + + + +#import "LookinAppInfo.h" +#import "LKS_MultiplatformAdapter.h" + +static NSString * const CodingKey_AppIcon = @"1"; +static NSString * const CodingKey_Screenshot = @"2"; +static NSString * const CodingKey_DeviceDescription = @"3"; +static NSString * const CodingKey_OsDescription = @"4"; +static NSString * const CodingKey_AppName = @"5"; +static NSString * const CodingKey_ScreenWidth = @"6"; +static NSString * const CodingKey_ScreenHeight = @"7"; +static NSString * const CodingKey_DeviceType = @"8"; + +@implementation LookinAppInfo + +- (id)copyWithZone:(NSZone *)zone { + LookinAppInfo *newAppInfo = [[LookinAppInfo allocWithZone:zone] init]; + newAppInfo.appIcon = self.appIcon; + newAppInfo.appName = self.appName; + newAppInfo.deviceDescription = self.deviceDescription; + newAppInfo.osDescription = self.osDescription; + newAppInfo.osMainVersion = self.osMainVersion; + newAppInfo.deviceType = self.deviceType; + newAppInfo.screenWidth = self.screenWidth; + newAppInfo.screenHeight = self.screenHeight; + newAppInfo.screenScale = self.screenScale; + newAppInfo.appInfoIdentifier = self.appInfoIdentifier; + return newAppInfo; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + + self.serverVersion = [aDecoder decodeIntForKey:@"serverVersion"]; + self.serverReadableVersion = [aDecoder decodeObjectForKey:@"serverReadableVersion"]; + self.swiftEnabledInLookinServer = [aDecoder decodeIntForKey:@"swiftEnabledInLookinServer"]; + NSData *screenshotData = [aDecoder decodeObjectForKey:CodingKey_Screenshot]; + self.screenshot = [[LookinImage alloc] initWithData:screenshotData]; + + NSData *appIconData = [aDecoder decodeObjectForKey:CodingKey_AppIcon]; + self.appIcon = [[LookinImage alloc] initWithData:appIconData]; + + self.appName = [aDecoder decodeObjectForKey:CodingKey_AppName]; + self.appBundleIdentifier = [aDecoder decodeObjectForKey:@"appBundleIdentifier"]; + self.deviceDescription = [aDecoder decodeObjectForKey:CodingKey_DeviceDescription]; + self.osDescription = [aDecoder decodeObjectForKey:CodingKey_OsDescription]; + self.osMainVersion = [aDecoder decodeIntegerForKey:@"osMainVersion"]; + self.deviceType = [aDecoder decodeIntegerForKey:CodingKey_DeviceType]; + self.screenWidth = [aDecoder decodeDoubleForKey:CodingKey_ScreenWidth]; + self.screenHeight = [aDecoder decodeDoubleForKey:CodingKey_ScreenHeight]; + self.screenScale = [aDecoder decodeDoubleForKey:@"screenScale"]; + self.appInfoIdentifier = [aDecoder decodeIntegerForKey:@"appInfoIdentifier"]; + self.shouldUseCache = [aDecoder decodeBoolForKey:@"shouldUseCache"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInt:self.serverVersion forKey:@"serverVersion"]; + [aCoder encodeObject:self.serverReadableVersion forKey:@"serverReadableVersion"]; + [aCoder encodeInt:self.swiftEnabledInLookinServer forKey:@"swiftEnabledInLookinServer"]; + +#if TARGET_OS_IPHONE + NSData *screenshotData = UIImagePNGRepresentation(self.screenshot); + [aCoder encodeObject:screenshotData forKey:CodingKey_Screenshot]; + + NSData *appIconData = UIImagePNGRepresentation(self.appIcon); + [aCoder encodeObject:appIconData forKey:CodingKey_AppIcon]; +#elif TARGET_OS_MAC + NSData *screenshotData = [self.screenshot TIFFRepresentation]; + [aCoder encodeObject:screenshotData forKey:CodingKey_Screenshot]; + + NSData *appIconData = [self.appIcon TIFFRepresentation]; + [aCoder encodeObject:appIconData forKey:CodingKey_AppIcon]; +#endif + + [aCoder encodeObject:self.appName forKey:CodingKey_AppName]; + [aCoder encodeObject:self.appBundleIdentifier forKey:@"appBundleIdentifier"]; + [aCoder encodeObject:self.deviceDescription forKey:CodingKey_DeviceDescription]; + [aCoder encodeObject:self.osDescription forKey:CodingKey_OsDescription]; + [aCoder encodeInteger:self.osMainVersion forKey:@"osMainVersion"]; + [aCoder encodeInteger:self.deviceType forKey:CodingKey_DeviceType]; + [aCoder encodeDouble:self.screenWidth forKey:CodingKey_ScreenWidth]; + [aCoder encodeDouble:self.screenHeight forKey:CodingKey_ScreenHeight]; + [aCoder encodeDouble:self.screenScale forKey:@"screenScale"]; + [aCoder encodeInteger:self.appInfoIdentifier forKey:@"appInfoIdentifier"]; + [aCoder encodeBool:self.shouldUseCache forKey:@"shouldUseCache"]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinAppInfo class]]) { + return NO; + } + if ([self isEqualToAppInfo:object]) { + return YES; + } + return NO; +} + +- (NSUInteger)hash { + return self.appName.hash ^ self.deviceDescription.hash ^ self.osDescription.hash ^ self.deviceType; +} + +- (BOOL)isEqualToAppInfo:(LookinAppInfo *)info { + if (!info) { + return NO; + } + if ([self.appName isEqualToString:info.appName] && [self.deviceDescription isEqualToString:info.deviceDescription] && [self.osDescription isEqualToString:info.osDescription] && self.deviceType == info.deviceType) { + return YES; + } + return NO; +} + +#if TARGET_OS_IPHONE + ++ (LookinAppInfo *)currentInfoWithScreenshot:(BOOL)hasScreenshot icon:(BOOL)hasIcon localIdentifiers:(NSArray *)localIdentifiers { + NSInteger selfIdentifier = [self getAppInfoIdentifier]; + if ([localIdentifiers containsObject:@(selfIdentifier)]) { + LookinAppInfo *info = [LookinAppInfo new]; + info.appInfoIdentifier = selfIdentifier; + info.shouldUseCache = YES; + return info; + } + + LookinAppInfo *info = [[LookinAppInfo alloc] init]; + info.serverReadableVersion = LOOKIN_SERVER_READABLE_VERSION; +#ifdef LOOKIN_SERVER_SWIFT_ENABLED + info.swiftEnabledInLookinServer = 1; +#else + info.swiftEnabledInLookinServer = -1; +#endif + info.appInfoIdentifier = selfIdentifier; + info.appName = [self appName]; + info.deviceDescription = [UIDevice currentDevice].name; + info.appBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + if ([self isSimulator]) { + info.deviceType = LookinAppInfoDeviceSimulator; + } else if ([LKS_MultiplatformAdapter isiPad]) { + info.deviceType = LookinAppInfoDeviceIPad; + } else { + info.deviceType = LookinAppInfoDeviceOthers; + } + + info.osDescription = [UIDevice currentDevice].systemVersion; + + NSString *mainVersionStr = [[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."].firstObject; + info.osMainVersion = [mainVersionStr integerValue]; + + CGSize screenSize = [LKS_MultiplatformAdapter mainScreenBounds].size; + info.screenWidth = screenSize.width; + info.screenHeight = screenSize.height; + info.screenScale = [LKS_MultiplatformAdapter mainScreenScale]; + + if (hasScreenshot) { + info.screenshot = [self screenshotImage]; + } + if (hasIcon) { + info.appIcon = [self appIcon]; + } + + return info; +} + ++ (NSString *)appName { + NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; + NSString *displayName = [info objectForKey:@"CFBundleDisplayName"]; + NSString *name = [info objectForKey:@"CFBundleName"]; + return displayName.length ? displayName : name; +} + ++ (UIImage *)appIcon { +#if TARGET_OS_TV + return nil; +#else + NSString *imageName = [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"] lastObject]; + if (!imageName.length) { + // 正常情况下拿到的 name 可能比如 “AppIcon60x60”。但某些情况可能为 nil,此时直接 return 否则 [UIImage imageNamed:nil] 可能导致 console 报 "CUICatalog: Invalid asset name supplied: '(null)'" 的错误信息 + return nil; + } + return [UIImage imageNamed:imageName]; +#endif +} + ++ (UIImage *)screenshotImage { + UIWindow *window = [LKS_MultiplatformAdapter keyWindow]; + if (!window) { + return nil; + } + CGSize size = window.bounds.size; + if (size.width <= 0 || size.height <= 0) { + // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={0, 0}, scale=3.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer to avoid this assert.' + + // https://github.com/hughkli/Lookin/issues/21 + return nil; + } + UIGraphicsBeginImageContextWithOptions(size, YES, 0.4); + [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES]; + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + ++ (BOOL)isSimulator { + if (TARGET_OS_SIMULATOR) { + return YES; + } + return NO; +} + +#endif + ++ (NSInteger)getAppInfoIdentifier { + static dispatch_once_t onceToken; + static NSInteger identifier = 0; + dispatch_once(&onceToken,^{ + identifier = [[NSDate date] timeIntervalSince1970]; + }); + return identifier; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.h b/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.h new file mode 100644 index 00000000..577d5324 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.h @@ -0,0 +1,257 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttrIdentifiers.h +// Lookin +// +// Created by Li Kai on 2019/9/18. +// https://lookin.work +// + + + +#import + +#pragma mark - Group + +typedef NSString * LookinAttrGroupIdentifier; + +extern LookinAttrGroupIdentifier const LookinAttrGroup_None; +extern LookinAttrGroupIdentifier const LookinAttrGroup_Class; +extern LookinAttrGroupIdentifier const LookinAttrGroup_Relation; +extern LookinAttrGroupIdentifier const LookinAttrGroup_Layout; +extern LookinAttrGroupIdentifier const LookinAttrGroup_AutoLayout; +extern LookinAttrGroupIdentifier const LookinAttrGroup_ViewLayer; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIImageView; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UILabel; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIControl; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIButton; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIScrollView; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UITableView; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UITextView; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UITextField; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIVisualEffectView; +extern LookinAttrGroupIdentifier const LookinAttrGroup_UIStackView; + +extern LookinAttrGroupIdentifier const LookinAttrGroup_UserCustom; + +#pragma mark - Section + +typedef NSString * LookinAttrSectionIdentifier; + +extern LookinAttrSectionIdentifier const LookinAttrSec_None; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UserCustom; + +extern LookinAttrSectionIdentifier const LookinAttrSec_Class_Class; + +extern LookinAttrSectionIdentifier const LookinAttrSec_Relation_Relation; + +extern LookinAttrSectionIdentifier const LookinAttrSec_Layout_Frame; +extern LookinAttrSectionIdentifier const LookinAttrSec_Layout_Bounds; +extern LookinAttrSectionIdentifier const LookinAttrSec_Layout_SafeArea; +extern LookinAttrSectionIdentifier const LookinAttrSec_Layout_Position; +extern LookinAttrSectionIdentifier const LookinAttrSec_Layout_AnchorPoint; + +extern LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Hugging; +extern LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Resistance; +extern LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Constraints; +extern LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_IntrinsicSize; + +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Visibility; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_InterationAndMasks; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Corner; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_BgColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Border; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Shadow; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_ContentMode; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_TintColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Tag; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIImageView_Name; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIImageView_Open; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Text; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Font; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_NumberOfLines; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_TextColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_BreakMode; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Alignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UILabel_CanAdjustFont; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIControl_EnabledSelected; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIControl_VerAlignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIControl_HorAlignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIControl_QMUIOutsideEdge; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIButton_ContentInsets; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIButton_TitleInsets; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIButton_ImageInsets; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentInset; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_AdjustedInset; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_IndicatorInset; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Offset; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentSize; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Behavior; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ShowsIndicator; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Bounce; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ScrollPaging; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentTouches; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Zoom; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_QMUIInitialInset; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_Style; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SectionsNumber; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_RowsNumber; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorStyle; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorInset; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Basic; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Text; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Font; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_TextColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Alignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextView_ContainerInset; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Text; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Placeholder; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Font; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_TextColor; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Alignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Clears; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_CanAdjustFont; +extern LookinAttrSectionIdentifier const LookinAttrSec_UITextField_ClearButtonMode; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIVisualEffectView_Style; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIVisualEffectView_QMUIForegroundColor; + +extern LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Axis; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Distribution; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Alignment; +extern LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Spacing; + +#pragma mark - Attr + +typedef NSString * LookinAttrIdentifier; + +extern LookinAttrIdentifier const LookinAttr_None; + +/// 用户自定义的 +extern LookinAttrIdentifier const LookinAttr_UserCustom; + +extern LookinAttrIdentifier const LookinAttr_Class_Class_Class; + +extern LookinAttrIdentifier const LookinAttr_Relation_Relation_Relation; + +extern LookinAttrIdentifier const LookinAttr_Layout_Frame_Frame; +extern LookinAttrIdentifier const LookinAttr_Layout_Bounds_Bounds; +extern LookinAttrIdentifier const LookinAttr_Layout_SafeArea_SafeArea; +extern LookinAttrIdentifier const LookinAttr_Layout_Position_Position; +extern LookinAttrIdentifier const LookinAttr_Layout_AnchorPoint_AnchorPoint; + +extern LookinAttrIdentifier const LookinAttr_AutoLayout_Hugging_Hor; +extern LookinAttrIdentifier const LookinAttr_AutoLayout_Hugging_Ver; +extern LookinAttrIdentifier const LookinAttr_AutoLayout_Resistance_Hor; +extern LookinAttrIdentifier const LookinAttr_AutoLayout_Resistance_Ver; +extern LookinAttrIdentifier const LookinAttr_AutoLayout_Constraints_Constraints; +extern LookinAttrIdentifier const LookinAttr_AutoLayout_IntrinsicSize_Size; + +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Visibility_Hidden; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Visibility_Opacity; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_InterationAndMasks_Interaction; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_InterationAndMasks_MasksToBounds; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Corner_Radius; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_BgColor_BgColor; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Border_Color; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Border_Width; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Color; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Opacity; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Radius; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_OffsetW; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_OffsetH; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_ContentMode_Mode; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_TintColor_Color; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_TintColor_Mode; +extern LookinAttrIdentifier const LookinAttr_ViewLayer_Tag_Tag; + +extern LookinAttrIdentifier const LookinAttr_UIImageView_Name_Name; +extern LookinAttrIdentifier const LookinAttr_UIImageView_Open_Open; + +extern LookinAttrIdentifier const LookinAttr_UILabel_Text_Text; +extern LookinAttrIdentifier const LookinAttr_UILabel_Font_Name; +extern LookinAttrIdentifier const LookinAttr_UILabel_Font_Size; +extern LookinAttrIdentifier const LookinAttr_UILabel_NumberOfLines_NumberOfLines; +extern LookinAttrIdentifier const LookinAttr_UILabel_TextColor_Color; +extern LookinAttrIdentifier const LookinAttr_UILabel_Alignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UILabel_BreakMode_Mode; +extern LookinAttrIdentifier const LookinAttr_UILabel_CanAdjustFont_CanAdjustFont; + +extern LookinAttrIdentifier const LookinAttr_UIControl_EnabledSelected_Enabled; +extern LookinAttrIdentifier const LookinAttr_UIControl_EnabledSelected_Selected; +extern LookinAttrIdentifier const LookinAttr_UIControl_VerAlignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UIControl_HorAlignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UIControl_QMUIOutsideEdge_Edge; + +extern LookinAttrIdentifier const LookinAttr_UIButton_ContentInsets_Insets; +extern LookinAttrIdentifier const LookinAttr_UIButton_TitleInsets_Insets; +extern LookinAttrIdentifier const LookinAttr_UIButton_ImageInsets_Insets; + +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Offset_Offset; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ContentSize_Size; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ContentInset_Inset; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_AdjustedInset_Inset; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Behavior_Behavior; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_IndicatorInset_Inset; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ScrollPaging_ScrollEnabled; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ScrollPaging_PagingEnabled; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Bounce_Ver; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Bounce_Hor; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ShowsIndicator_Hor; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ShowsIndicator_Ver; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ContentTouches_Delay; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_ContentTouches_CanCancel; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_MinScale; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_MaxScale; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_Scale; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_Bounce; +extern LookinAttrIdentifier const LookinAttr_UIScrollView_QMUIInitialInset_Inset; + +extern LookinAttrIdentifier const LookinAttr_UITableView_Style_Style; +extern LookinAttrIdentifier const LookinAttr_UITableView_SectionsNumber_Number; +extern LookinAttrIdentifier const LookinAttr_UITableView_RowsNumber_Number; +extern LookinAttrIdentifier const LookinAttr_UITableView_SeparatorInset_Inset; +extern LookinAttrIdentifier const LookinAttr_UITableView_SeparatorColor_Color; +extern LookinAttrIdentifier const LookinAttr_UITableView_SeparatorStyle_Style; + +extern LookinAttrIdentifier const LookinAttr_UITextView_Font_Name; +extern LookinAttrIdentifier const LookinAttr_UITextView_Font_Size; +extern LookinAttrIdentifier const LookinAttr_UITextView_Basic_Editable; +extern LookinAttrIdentifier const LookinAttr_UITextView_Basic_Selectable; +extern LookinAttrIdentifier const LookinAttr_UITextView_Text_Text; +extern LookinAttrIdentifier const LookinAttr_UITextView_TextColor_Color; +extern LookinAttrIdentifier const LookinAttr_UITextView_Alignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UITextView_ContainerInset_Inset; + +extern LookinAttrIdentifier const LookinAttr_UITextField_Text_Text; +extern LookinAttrIdentifier const LookinAttr_UITextField_Placeholder_Placeholder; +extern LookinAttrIdentifier const LookinAttr_UITextField_Font_Name; +extern LookinAttrIdentifier const LookinAttr_UITextField_Font_Size; +extern LookinAttrIdentifier const LookinAttr_UITextField_TextColor_Color; +extern LookinAttrIdentifier const LookinAttr_UITextField_Alignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UITextField_Clears_ClearsOnBeginEditing; +extern LookinAttrIdentifier const LookinAttr_UITextField_Clears_ClearsOnInsertion; +extern LookinAttrIdentifier const LookinAttr_UITextField_CanAdjustFont_CanAdjustFont; +extern LookinAttrIdentifier const LookinAttr_UITextField_CanAdjustFont_MinSize; +extern LookinAttrIdentifier const LookinAttr_UITextField_ClearButtonMode_Mode; + +extern LookinAttrIdentifier const LookinAttr_UIVisualEffectView_Style_Style; +extern LookinAttrIdentifier const LookinAttr_UIVisualEffectView_QMUIForegroundColor_Color; + +extern LookinAttrIdentifier const LookinAttr_UIStackView_Axis_Axis; +extern LookinAttrIdentifier const LookinAttr_UIStackView_Distribution_Distribution; +extern LookinAttrIdentifier const LookinAttr_UIStackView_Alignment_Alignment; +extern LookinAttrIdentifier const LookinAttr_UIStackView_Spacing_Spacing; + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.m b/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.m new file mode 100644 index 00000000..29a1f98e --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttrIdentifiers.m @@ -0,0 +1,253 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttrIdentifiers.m +// Lookin +// +// Created by Li Kai on 2019/9/18. +// https://lookin.work +// + + + +#import "LookinAttrIdentifiers.h" + +// value 不能重复(AppDelegate 里的 runTests 有相关 test) +// 如果要去掉某一项可以考虑注释掉而非直接删除,以防止新项和旧项的 value 相同而引发 preference 错乱(这些 value 会被存储到 userDefaults 里) + +#pragma mark - Group + +LookinAttrGroupIdentifier const LookinAttrGroup_None = @"n"; +LookinAttrGroupIdentifier const LookinAttrGroup_Class = @"c"; +LookinAttrGroupIdentifier const LookinAttrGroup_Relation = @"r"; +LookinAttrGroupIdentifier const LookinAttrGroup_Layout = @"l"; +LookinAttrGroupIdentifier const LookinAttrGroup_AutoLayout = @"a"; +LookinAttrGroupIdentifier const LookinAttrGroup_ViewLayer = @"vl"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIImageView = @"i"; +LookinAttrGroupIdentifier const LookinAttrGroup_UILabel = @"la"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIControl = @"co"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIButton = @"b"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIScrollView = @"s"; +LookinAttrGroupIdentifier const LookinAttrGroup_UITableView = @"ta"; +LookinAttrGroupIdentifier const LookinAttrGroup_UITextView = @"te"; +LookinAttrGroupIdentifier const LookinAttrGroup_UITextField = @"tf"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIVisualEffectView = @"ve"; +LookinAttrGroupIdentifier const LookinAttrGroup_UIStackView = @"UIStackView"; + +LookinAttrGroupIdentifier const LookinAttrGroup_UserCustom = @"guc"; // user custom + +#pragma mark - Section + +LookinAttrSectionIdentifier const LookinAttrSec_None = @"n"; + +LookinAttrSectionIdentifier const LookinAttrSec_UserCustom = @"sec_ctm"; + +LookinAttrSectionIdentifier const LookinAttrSec_Class_Class = @"cl_c"; + +LookinAttrSectionIdentifier const LookinAttrSec_Relation_Relation = @"r_r"; + +LookinAttrSectionIdentifier const LookinAttrSec_Layout_Frame = @"l_f"; +LookinAttrSectionIdentifier const LookinAttrSec_Layout_Bounds = @"l_b"; +LookinAttrSectionIdentifier const LookinAttrSec_Layout_SafeArea = @"l_s"; +LookinAttrSectionIdentifier const LookinAttrSec_Layout_Position = @"l_p"; +LookinAttrSectionIdentifier const LookinAttrSec_Layout_AnchorPoint = @"l_a"; + +LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Hugging = @"a_h"; +LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Resistance = @"a_r"; +LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_Constraints = @"a_c"; +LookinAttrSectionIdentifier const LookinAttrSec_AutoLayout_IntrinsicSize = @"a_i"; + +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Visibility = @"v_v"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_InterationAndMasks = @"v_i"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Corner = @"v_c"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_BgColor = @"v_b"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Border = @"v_bo"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Shadow = @"v_s"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_ContentMode = @"v_co"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_TintColor = @"v_t"; +LookinAttrSectionIdentifier const LookinAttrSec_ViewLayer_Tag = @"v_ta"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIImageView_Name = @"i_n"; +LookinAttrSectionIdentifier const LookinAttrSec_UIImageView_Open = @"i_o"; + +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Text = @"lb_t"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Font = @"lb_f"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_NumberOfLines = @"lb_n"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_TextColor = @"lb_tc"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_BreakMode = @"lb_b"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_Alignment = @"lb_a"; +LookinAttrSectionIdentifier const LookinAttrSec_UILabel_CanAdjustFont = @"lb_c"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIControl_EnabledSelected = @"c_e"; +LookinAttrSectionIdentifier const LookinAttrSec_UIControl_VerAlignment = @"c_v"; +LookinAttrSectionIdentifier const LookinAttrSec_UIControl_HorAlignment = @"c_h"; +LookinAttrSectionIdentifier const LookinAttrSec_UIControl_QMUIOutsideEdge = @"c_o"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIButton_ContentInsets = @"b_c"; +LookinAttrSectionIdentifier const LookinAttrSec_UIButton_TitleInsets = @"b_t"; +LookinAttrSectionIdentifier const LookinAttrSec_UIButton_ImageInsets = @"b_i"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentInset = @"s_c"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_AdjustedInset = @"s_a"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_IndicatorInset = @"s_i"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Offset = @"s_o"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentSize = @"s_cs"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Behavior = @"s_b"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ShowsIndicator = @"s_si"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Bounce = @"s_bo"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ScrollPaging = @"s_s"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_ContentTouches = @"s_ct"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_Zoom = @"s_z"; +LookinAttrSectionIdentifier const LookinAttrSec_UIScrollView_QMUIInitialInset = @"s_ii"; + +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_Style = @"t_s"; +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SectionsNumber = @"t_sn"; +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_RowsNumber = @"t_r"; +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorStyle = @"t_ss"; +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorColor = @"t_sc"; +LookinAttrSectionIdentifier const LookinAttrSec_UITableView_SeparatorInset = @"t_si"; + +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Basic = @"tv_b"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Text = @"tv_t"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Font = @"tv_f"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_TextColor = @"tv_tc"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_Alignment = @"tv_a"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextView_ContainerInset = @"tv_c"; + +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Text = @"tf_t"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Placeholder = @"tf_p"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Font = @"tf_f"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_TextColor = @"tf_tc"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Alignment = @"tf_a"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_Clears = @"tf_c"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_CanAdjustFont = @"tf_ca"; +LookinAttrSectionIdentifier const LookinAttrSec_UITextField_ClearButtonMode = @"tf_cb"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIVisualEffectView_Style = @"ve_s"; +LookinAttrSectionIdentifier const LookinAttrSec_UIVisualEffectView_QMUIForegroundColor = @"ve_f"; + +LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Axis = @"usv_axis"; +LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Distribution = @"usv_dis"; +LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Alignment = @"usv_align"; +LookinAttrSectionIdentifier const LookinAttrSec_UIStackView_Spacing = @"usv_spa"; + +#pragma mark - Attr + +LookinAttrIdentifier const LookinAttr_None = @"n"; +LookinAttrIdentifier const LookinAttr_UserCustom = @"ctm"; + +LookinAttrIdentifier const LookinAttr_Class_Class_Class = @"c_c_c"; + + +LookinAttrIdentifier const LookinAttr_Relation_Relation_Relation = @"r_r_r"; + +LookinAttrIdentifier const LookinAttr_Layout_Frame_Frame = @"l_f_f"; +LookinAttrIdentifier const LookinAttr_Layout_Bounds_Bounds = @"l_b_b"; +LookinAttrIdentifier const LookinAttr_Layout_SafeArea_SafeArea = @"l_s_s"; +LookinAttrIdentifier const LookinAttr_Layout_Position_Position = @"l_p_p"; +LookinAttrIdentifier const LookinAttr_Layout_AnchorPoint_AnchorPoint = @"l_a_a"; + +LookinAttrIdentifier const LookinAttr_AutoLayout_Hugging_Hor = @"al_h_h"; +LookinAttrIdentifier const LookinAttr_AutoLayout_Hugging_Ver = @"al_h_v"; +LookinAttrIdentifier const LookinAttr_AutoLayout_Resistance_Hor = @"al_r_h"; +LookinAttrIdentifier const LookinAttr_AutoLayout_Resistance_Ver = @"al_r_v"; +LookinAttrIdentifier const LookinAttr_AutoLayout_Constraints_Constraints = @"al_c_c"; +LookinAttrIdentifier const LookinAttr_AutoLayout_IntrinsicSize_Size = @"cl_i_s"; + +LookinAttrIdentifier const LookinAttr_ViewLayer_Visibility_Hidden = @"vl_v_h"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Visibility_Opacity = @"vl_v_o"; +LookinAttrIdentifier const LookinAttr_ViewLayer_InterationAndMasks_Interaction = @"vl_i_i"; +LookinAttrIdentifier const LookinAttr_ViewLayer_InterationAndMasks_MasksToBounds = @"vl_i_m"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Corner_Radius = @"vl_c_r"; +LookinAttrIdentifier const LookinAttr_ViewLayer_BgColor_BgColor = @"vl_b_b"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Border_Color = @"vl_b_c"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Border_Width = @"vl_b_w"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Color = @"vl_s_c"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Opacity = @"vl_s_o"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_Radius = @"vl_s_r"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_OffsetW = @"vl_s_ow"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Shadow_OffsetH = @"vl_s_oh"; +LookinAttrIdentifier const LookinAttr_ViewLayer_ContentMode_Mode = @"vl_c_m"; +LookinAttrIdentifier const LookinAttr_ViewLayer_TintColor_Color = @"vl_t_c"; +LookinAttrIdentifier const LookinAttr_ViewLayer_TintColor_Mode = @"vl_t_m"; +LookinAttrIdentifier const LookinAttr_ViewLayer_Tag_Tag = @"vl_t_t"; + +LookinAttrIdentifier const LookinAttr_UIImageView_Name_Name = @"iv_n_n"; +LookinAttrIdentifier const LookinAttr_UIImageView_Open_Open = @"iv_o_o"; + +LookinAttrIdentifier const LookinAttr_UILabel_Text_Text = @"lb_t_t"; +LookinAttrIdentifier const LookinAttr_UILabel_Font_Name = @"lb_f_n"; +LookinAttrIdentifier const LookinAttr_UILabel_Font_Size = @"lb_f_s"; +LookinAttrIdentifier const LookinAttr_UILabel_NumberOfLines_NumberOfLines = @"lb_n_n"; +LookinAttrIdentifier const LookinAttr_UILabel_TextColor_Color = @"lb_t_c"; +LookinAttrIdentifier const LookinAttr_UILabel_Alignment_Alignment = @"lb_a_a"; +LookinAttrIdentifier const LookinAttr_UILabel_BreakMode_Mode = @"lb_b_m"; +LookinAttrIdentifier const LookinAttr_UILabel_CanAdjustFont_CanAdjustFont = @"lb_c_c"; + +LookinAttrIdentifier const LookinAttr_UIControl_EnabledSelected_Enabled = @"ct_e_e"; +LookinAttrIdentifier const LookinAttr_UIControl_EnabledSelected_Selected = @"ct_e_s"; +LookinAttrIdentifier const LookinAttr_UIControl_VerAlignment_Alignment = @"ct_v_a"; +LookinAttrIdentifier const LookinAttr_UIControl_HorAlignment_Alignment = @"ct_h_a"; +LookinAttrIdentifier const LookinAttr_UIControl_QMUIOutsideEdge_Edge = @"ct_o_e"; + +LookinAttrIdentifier const LookinAttr_UIButton_ContentInsets_Insets = @"bt_c_i"; +LookinAttrIdentifier const LookinAttr_UIButton_TitleInsets_Insets = @"bt_t_i"; +LookinAttrIdentifier const LookinAttr_UIButton_ImageInsets_Insets = @"bt_i_i"; + +LookinAttrIdentifier const LookinAttr_UIScrollView_Offset_Offset = @"sv_o_o"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ContentSize_Size = @"sv_c_s"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ContentInset_Inset = @"sv_c_i"; +LookinAttrIdentifier const LookinAttr_UIScrollView_AdjustedInset_Inset = @"sv_a_i"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Behavior_Behavior = @"sv_b_b"; +LookinAttrIdentifier const LookinAttr_UIScrollView_IndicatorInset_Inset = @"sv_i_i"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ScrollPaging_ScrollEnabled = @"sv_s_s"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ScrollPaging_PagingEnabled = @"sv_s_p"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Bounce_Ver = @"sv_b_v"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Bounce_Hor = @"sv_b_h"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ShowsIndicator_Hor = @"sv_h_h"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ShowsIndicator_Ver = @"sv_s_v"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ContentTouches_Delay = @"sv_c_d"; +LookinAttrIdentifier const LookinAttr_UIScrollView_ContentTouches_CanCancel = @"sv_c_c"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_MinScale = @"sv_z_mi"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_MaxScale = @"sv_z_ma"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_Scale = @"sv_z_s"; +LookinAttrIdentifier const LookinAttr_UIScrollView_Zoom_Bounce = @"sv_z_b"; +LookinAttrIdentifier const LookinAttr_UIScrollView_QMUIInitialInset_Inset = @"sv_qi_i"; + +LookinAttrIdentifier const LookinAttr_UITableView_Style_Style = @"tv_s_s"; +LookinAttrIdentifier const LookinAttr_UITableView_SectionsNumber_Number = @"tv_s_n"; +LookinAttrIdentifier const LookinAttr_UITableView_RowsNumber_Number = @"tv_r_n"; +LookinAttrIdentifier const LookinAttr_UITableView_SeparatorInset_Inset = @"tv_s_i"; +LookinAttrIdentifier const LookinAttr_UITableView_SeparatorColor_Color = @"tv_s_c"; +LookinAttrIdentifier const LookinAttr_UITableView_SeparatorStyle_Style = @"tv_ss_s"; + +LookinAttrIdentifier const LookinAttr_UITextView_Font_Name = @"te_f_n"; +LookinAttrIdentifier const LookinAttr_UITextView_Font_Size = @"te_f_s"; +LookinAttrIdentifier const LookinAttr_UITextView_Basic_Editable = @"te_b_e"; +LookinAttrIdentifier const LookinAttr_UITextView_Basic_Selectable = @"te_b_s"; +LookinAttrIdentifier const LookinAttr_UITextView_Text_Text = @"te_t_t"; +LookinAttrIdentifier const LookinAttr_UITextView_TextColor_Color = @"te_t_c"; +LookinAttrIdentifier const LookinAttr_UITextView_Alignment_Alignment = @"te_a_a"; +LookinAttrIdentifier const LookinAttr_UITextView_ContainerInset_Inset = @"te_c_i"; + +LookinAttrIdentifier const LookinAttr_UITextField_Text_Text = @"tf_t_t"; +LookinAttrIdentifier const LookinAttr_UITextField_Placeholder_Placeholder = @"tf_p_p"; +LookinAttrIdentifier const LookinAttr_UITextField_Font_Name = @"tf_f_n"; +LookinAttrIdentifier const LookinAttr_UITextField_Font_Size = @"tf_f_s"; +LookinAttrIdentifier const LookinAttr_UITextField_TextColor_Color = @"tf_t_c"; +LookinAttrIdentifier const LookinAttr_UITextField_Alignment_Alignment = @"tf_a_a"; +LookinAttrIdentifier const LookinAttr_UITextField_Clears_ClearsOnBeginEditing = @"tf_c_c"; +LookinAttrIdentifier const LookinAttr_UITextField_Clears_ClearsOnInsertion = @"tf_c_co"; +LookinAttrIdentifier const LookinAttr_UITextField_CanAdjustFont_CanAdjustFont = @"tf_c_ca"; +LookinAttrIdentifier const LookinAttr_UITextField_CanAdjustFont_MinSize = @"tf_c_m"; +LookinAttrIdentifier const LookinAttr_UITextField_ClearButtonMode_Mode = @"tf_cb_m"; + +LookinAttrIdentifier const LookinAttr_UIVisualEffectView_Style_Style = @"ve_s_s"; +LookinAttrIdentifier const LookinAttr_UIVisualEffectView_QMUIForegroundColor_Color = @"ve_f_c"; + +LookinAttrIdentifier const LookinAttr_UIStackView_Axis_Axis = @"usv_axis_axis"; +LookinAttrIdentifier const LookinAttr_UIStackView_Distribution_Distribution = @"usv_dis_dis"; +LookinAttrIdentifier const LookinAttr_UIStackView_Alignment_Alignment = @"usv_ali_ali"; +LookinAttrIdentifier const LookinAttr_UIStackView_Spacing_Spacing = @"usv_spa_spa"; + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttrType.h b/Pods/LookinServer/Src/Main/Shared/LookinAttrType.h new file mode 100644 index 00000000..feba9ce9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttrType.h @@ -0,0 +1,50 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttrIdentifiers.h +// Lookin +// +// Created by Li Kai on 2018/12/1. +// https://lookin.work +// + +/// 注意:新属性只能加到末尾,否则新旧版本搭配时可能有兼容问题 +typedef NS_ENUM(NSInteger, LookinAttrType) { + LookinAttrTypeNone, + LookinAttrTypeVoid, + LookinAttrTypeChar, + LookinAttrTypeInt, + LookinAttrTypeShort, + LookinAttrTypeLong, + LookinAttrTypeLongLong, + LookinAttrTypeUnsignedChar, + LookinAttrTypeUnsignedInt, + LookinAttrTypeUnsignedShort, + LookinAttrTypeUnsignedLong, + LookinAttrTypeUnsignedLongLong, + LookinAttrTypeFloat, + LookinAttrTypeDouble, + LookinAttrTypeBOOL, + LookinAttrTypeSel, + LookinAttrTypeClass, + LookinAttrTypeCGPoint, + LookinAttrTypeCGVector, + LookinAttrTypeCGSize, + LookinAttrTypeCGRect, + LookinAttrTypeCGAffineTransform, + LookinAttrTypeUIEdgeInsets, + LookinAttrTypeUIOffset, + LookinAttrTypeNSString, + LookinAttrTypeEnumInt, + LookinAttrTypeEnumLong, + /// value 实际为 RGBA 数组,即 @[NSNumber, NSNumber, NSNumber, NSNumber],NSNumber 范围是 0 ~ 1 + LookinAttrTypeUIColor, + /// 业务需要根据具体的 AttrIdentifier 来解析 + LookinAttrTypeCustomObj, + + LookinAttrTypeEnumString, + LookinAttrTypeShadow, + LookinAttrTypeJson +}; + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttribute.h b/Pods/LookinServer/Src/Main/Shared/LookinAttribute.h new file mode 100644 index 00000000..d86f2987 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttribute.h @@ -0,0 +1,48 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttribute.h +// qmuidemo +// +// Created by Li Kai on 2018/11/17. +// Copyright © 2018 QMUI Team. All rights reserved. +// + +#import "LookinAttrIdentifiers.h" +#import "LookinCodingValueType.h" +#import "LookinAttrType.h" + +@class LookinDisplayItem; + +@interface LookinAttribute : NSObject + +@property(nonatomic, copy) LookinAttrIdentifier identifier; + +/// 只有 Custom Attr 才有该属性 +@property(nonatomic, copy) NSString *displayTitle; + +/// 标识 value 的具体类型(如 double / NSString /...) +@property(nonatomic, assign) LookinAttrType attrType; + +/// 具体的值,需配合 attrType 属性来解析它 +/// 对于 String、Color 等 attyType,该属性可能为 nil +@property(nonatomic, strong) id value; + +/// 额外信息,大部分情况下它是 nil +/// 当 attyType 为 LookinAttrTypeEnumString 时,extraValue 是一个 [String] 且保存了 allEnumCases +@property(nonatomic, strong) id extraValue; + +/// 仅 Custom Attr 可能有该属性 +/// 对于有 retainedSetter 的 Custom Attr,它的 setter 会以 customSetterID 作为 key 被保存到 LKS_CustomAttrSetterManager 里,后续可以通过这个 uniqueID 重新把 setter 从 LKS_CustomAttrSetterManager 里取出来并调用 +@property(nonatomic, copy) NSString *customSetterID; + +#pragma mark - 以下属性不会参与 encode/decode + +/// 标识该 LookinAttribute 对象隶属于哪一个 LookinDisplayItem +@property(nonatomic, weak) LookinDisplayItem *targetDisplayItem; + +- (BOOL)isUserCustom; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttribute.m b/Pods/LookinServer/Src/Main/Shared/LookinAttribute.m new file mode 100644 index 00000000..c0625d70 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttribute.m @@ -0,0 +1,64 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttribute.m +// qmuidemo +// +// Created by Li Kai on 2018/11/17. +// Copyright © 2018 QMUI Team. All rights reserved. +// + + + +#import "LookinAttribute.h" +#import "LookinDisplayItem.h" + +@implementation LookinAttribute + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinAttribute *newAttr = [[LookinAttribute allocWithZone:zone] init]; + newAttr.identifier = self.identifier; + newAttr.displayTitle = self.displayTitle; + newAttr.value = self.value; + newAttr.attrType = self.attrType; + newAttr.extraValue = self.extraValue; + newAttr.customSetterID = self.customSetterID; + return newAttr; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.displayTitle forKey:@"displayTitle"]; + [aCoder encodeObject:self.identifier forKey:@"identifier"]; + [aCoder encodeInteger:self.attrType forKey:@"attrType"]; + [aCoder encodeObject:self.value forKey:@"value"]; + [aCoder encodeObject:self.extraValue forKey:@"extraValue"]; + [aCoder encodeObject:self.customSetterID forKey:@"customSetterID"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.displayTitle = [aDecoder decodeObjectForKey:@"displayTitle"]; + self.identifier = [aDecoder decodeObjectForKey:@"identifier"]; + self.attrType = [aDecoder decodeIntegerForKey:@"attrType"]; + self.value = [aDecoder decodeObjectForKey:@"value"]; + self.extraValue = [aDecoder decodeObjectForKey:@"extraValue"]; + self.customSetterID = [aDecoder decodeObjectForKey:@"customSetterID"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (BOOL)isUserCustom { + return [self.identifier isEqualToString:LookinAttr_UserCustom]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.h b/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.h new file mode 100644 index 00000000..c9357e0b --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.h @@ -0,0 +1,31 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributeModification.h +// Lookin +// +// Created by Li Kai on 2018/11/20. +// https://lookin.work +// + + + +#import +#import "LookinAttrType.h" + +@interface LookinAttributeModification : NSObject + +@property(nonatomic, assign) unsigned long targetOid; + +@property(nonatomic, assign) SEL setterSelector; +@property(nonatomic, assign) SEL getterSelector; + +@property(nonatomic, assign) LookinAttrType attrType; +@property(nonatomic, strong) id value; + +/// 1.0.4 开始加入这个参数 +@property(nonatomic, copy) NSString *clientReadableVersion; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.m b/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.m new file mode 100644 index 00000000..39f16c9a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributeModification.m @@ -0,0 +1,40 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributeModification.m +// Lookin +// +// Created by Li Kai on 2018/11/20. +// https://lookin.work +// + +#import "LookinAttributeModification.h" + +@implementation LookinAttributeModification + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:@(self.targetOid) forKey:@"targetOid"]; + [aCoder encodeObject:NSStringFromSelector(self.setterSelector) forKey:@"setterSelector"]; + [aCoder encodeInteger:self.attrType forKey:@"attrType"]; + [aCoder encodeObject:self.value forKey:@"value"]; + [aCoder encodeObject:self.clientReadableVersion forKey:@"clientReadableVersion"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.targetOid = [[aDecoder decodeObjectForKey:@"targetOid"] unsignedLongValue]; + self.setterSelector = NSSelectorFromString([aDecoder decodeObjectForKey:@"setterSelector"]); + self.attrType = [aDecoder decodeIntegerForKey:@"attrType"]; + self.value = [aDecoder decodeObjectForKey:@"value"]; + self.clientReadableVersion = [aDecoder decodeObjectForKey:@"clientReadableVersion"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.h b/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.h new file mode 100644 index 00000000..e8ee7ed2 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.h @@ -0,0 +1,41 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributesGroup.h +// Lookin +// +// Created by Li Kai on 2018/11/19. +// https://lookin.work +// + + + +#import +#import "LookinAttrIdentifiers.h" + +@class LookinAttributesSection; + +/** + In Lookin, a LookinAttributesGroup instance will be rendered as a property card. + + When isUserCustom is false: two LookinAttributesGroup instances will be regard as equal when they has the same LookinAttrGroupIdentifier. + When isUserCustom is true: two LookinAttributesGroup instances will be regard as equal when they has the same title. + 当 isUserCustom 为 false 时:若两个 attrGroup 有相同的 LookinAttrGroupIdentifier,则 isEqual: 返回 YES + */ +@interface LookinAttributesGroup : NSObject + +/// 只有在 identifier 为 custom 时,才存在该值 +@property(nonatomic, copy) NSString *userCustomTitle; + +@property(nonatomic, copy) LookinAttrGroupIdentifier identifier; + +@property(nonatomic, copy) NSArray *attrSections; + +/// 如果是 custom 则返回 userCustomTitle,如果不是 custom 则返回 identifier +- (NSString *)uniqueKey; + +- (BOOL)isUserCustom; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.m b/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.m new file mode 100644 index 00000000..49a4825e --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributesGroup.m @@ -0,0 +1,92 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributesGroup.m +// Lookin +// +// Created by Li Kai on 2018/11/19. +// https://lookin.work +// + + + +#import "LookinAttributesGroup.h" +#import "LookinAttribute.h" +#import "LookinAttributesSection.h" +#import "LookinDashboardBlueprint.h" +#import "NSArray+Lookin.h" + +@implementation LookinAttributesGroup + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinAttributesGroup *newGroup = [[LookinAttributesGroup allocWithZone:zone] init]; + newGroup.userCustomTitle = self.userCustomTitle; + newGroup.identifier = self.identifier; + newGroup.attrSections = [self.attrSections lookin_map:^id(NSUInteger idx, LookinAttributesSection *value) { + return value.copy; + }]; + return newGroup; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.userCustomTitle forKey:@"userCustomTitle"]; + [aCoder encodeObject:self.identifier forKey:@"identifier"]; + [aCoder encodeObject:self.attrSections forKey:@"attrSections"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.userCustomTitle = [aDecoder decodeObjectForKey:@"userCustomTitle"]; + self.identifier = [aDecoder decodeObjectForKey:@"identifier"]; + self.attrSections = [aDecoder decodeObjectForKey:@"attrSections"]; + } + return self; +} + +- (NSUInteger)hash { + return self.uniqueKey.hash; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinAttributesGroup class]]) { + return NO; + } + LookinAttributesGroup *targetObject = object; + + if (![self.identifier isEqualToString:targetObject.identifier]) { + return false; + } + if ([self.identifier isEqualToString:LookinAttrGroup_UserCustom]) { + BOOL ret = [self.userCustomTitle isEqualToString:targetObject.userCustomTitle]; + return ret; + } else { + return true; + } +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (NSString *)uniqueKey { + if ([self.identifier isEqualToString:LookinAttrGroup_UserCustom]) { + return self.userCustomTitle; + } else { + return self.identifier; + } +} + +- (BOOL)isUserCustom { + return [self.identifier isEqualToString:LookinAttrSec_UserCustom]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.h b/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.h new file mode 100644 index 00000000..32ddec8d --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.h @@ -0,0 +1,35 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributesSection.h +// Lookin +// +// Created by Li Kai on 2019/3/2. +// https://lookin.work +// + + + +#import +#import "LookinAttrIdentifiers.h" + +@class LookinAttribute; + +typedef NS_ENUM (NSInteger, LookinAttributesSectionStyle) { + LookinAttributesSectionStyleDefault, // 每个 attr 独占一行 + LookinAttributesSectionStyle0, // frame 等卡片使用,前 4 个 attr 每行两个,之后每个 attr 在同一排,每个宽度为 1/4 + LookinAttributesSectionStyle1, // 第一个 attr 在第一排靠左,第二个 attr 在第一排靠右,之后的 attr 每个独占一行 + LookinAttributesSectionStyle2 // 第一排独占一行,剩下的在同一行且均分宽度 +}; + +@interface LookinAttributesSection : NSObject + +@property(nonatomic, copy) LookinAttrSectionIdentifier identifier; + +@property(nonatomic, copy) NSArray *attributes; + +- (BOOL)isUserCustom; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.m b/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.m new file mode 100644 index 00000000..7617c094 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAttributesSection.m @@ -0,0 +1,56 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAttributesSection.m +// Lookin +// +// Created by Li Kai on 2019/3/2. +// https://lookin.work +// + + + +#import "LookinAttributesSection.h" +#import "LookinAttribute.h" + +#import "NSArray+Lookin.h" + +@implementation LookinAttributesSection + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinAttributesSection *newSection = [[LookinAttributesSection allocWithZone:zone] init]; + newSection.identifier = self.identifier; + newSection.attributes = [self.attributes lookin_map:^id(NSUInteger idx, LookinAttribute *value) { + return value.copy; + }]; + return newSection; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.identifier forKey:@"identifier"]; + [aCoder encodeObject:self.attributes forKey:@"attributes"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.identifier = [aDecoder decodeObjectForKey:@"identifier"]; + self.attributes = [aDecoder decodeObjectForKey:@"attributes"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (BOOL)isUserCustom { + return [self.identifier isEqualToString:LookinAttrSec_UserCustom]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.h b/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.h new file mode 100644 index 00000000..3edf865e --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.h @@ -0,0 +1,51 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAutoLayoutConstraint.h +// Lookin +// +// Created by Li Kai on 2019/9/28. +// https://lookin.work +// + + + +#import "LookinDefines.h" + +@class LookinObject; + +typedef NS_ENUM(NSInteger, LookinConstraintItemType) { + LookinConstraintItemTypeUnknown, + LookinConstraintItemTypeNil, + LookinConstraintItemTypeView, + LookinConstraintItemTypeSelf, + LookinConstraintItemTypeSuper, + LookinConstraintItemTypeLayoutGuide +}; + +@interface LookinAutoLayoutConstraint : NSObject + +#if TARGET_OS_IPHONE ++ (instancetype)instanceFromNSConstraint:(NSLayoutConstraint *)constraint isEffective:(BOOL)isEffective firstItemType:(LookinConstraintItemType)firstItemType secondItemType:(LookinConstraintItemType)secondItemType; +#endif + +@property(nonatomic, assign) BOOL effective; +@property(nonatomic, assign) BOOL active; +@property(nonatomic, assign) BOOL shouldBeArchived; +@property(nonatomic, strong) LookinObject *firstItem; +@property(nonatomic, assign) LookinConstraintItemType firstItemType; +/// iOS 里的 NSLayoutAttribute,注意 iOS 和 macOS 虽然都有 NSLayoutAttribute 但是 value 非常不同,因此这里使用 NSInteger 避免混淆 +@property(nonatomic, assign) NSInteger firstAttribute; +@property(nonatomic, assign) NSLayoutRelation relation; +@property(nonatomic, strong) LookinObject *secondItem; +@property(nonatomic, assign) LookinConstraintItemType secondItemType; +/// iOS 里的 NSLayoutAttribute,注意 iOS 和 macOS 虽然都有 NSLayoutAttribute 但是 value 非常不同,因此这里使用 NSInteger 避免混淆 +@property(nonatomic, assign) NSInteger secondAttribute; +@property(nonatomic, assign) CGFloat multiplier; +@property(nonatomic, assign) CGFloat constant; +@property(nonatomic, assign) CGFloat priority; +@property(nonatomic, copy) NSString *identifier; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.m b/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.m new file mode 100644 index 00000000..a8e45202 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinAutoLayoutConstraint.m @@ -0,0 +1,107 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinAutoLayoutConstraint.m +// Lookin +// +// Created by Li Kai on 2019/9/28. +// https://lookin.work +// + + + +#import "LookinAutoLayoutConstraint.h" +#import "LookinObject.h" + +@implementation LookinAutoLayoutConstraint + +#if TARGET_OS_IPHONE + ++ (instancetype)instanceFromNSConstraint:(NSLayoutConstraint *)constraint isEffective:(BOOL)isEffective firstItemType:(LookinConstraintItemType)firstItemType secondItemType:(LookinConstraintItemType)secondItemType { + LookinAutoLayoutConstraint *instance = [LookinAutoLayoutConstraint new]; + instance.effective = isEffective; + instance.active = constraint.active; + instance.shouldBeArchived = constraint.shouldBeArchived; + instance.firstItem = [LookinObject instanceWithObject:constraint.firstItem]; + instance.firstItemType = firstItemType; + instance.firstAttribute = constraint.firstAttribute; + instance.relation = constraint.relation; + instance.secondItem = [LookinObject instanceWithObject:constraint.secondItem]; + instance.secondItemType = secondItemType; + instance.secondAttribute = constraint.secondAttribute; + instance.multiplier = constraint.multiplier; + instance.constant = constraint.constant; + instance.priority = constraint.priority; + instance.identifier = constraint.identifier; + + return instance; +} + +- (void)setFirstAttribute:(NSInteger)firstAttribute { + _firstAttribute = firstAttribute; + [self _assertUnknownAttribute:firstAttribute]; +} + +- (void)setSecondAttribute:(NSInteger)secondAttribute { + _secondAttribute = secondAttribute; + [self _assertUnknownAttribute:secondAttribute]; +} + +- (void)_assertUnknownAttribute:(NSInteger)attribute { + // 以下几个 assert 用来帮助发现那些系统私有的定义,正式发布时应该去掉这几个 assert + if (attribute > 20 && attribute < 32) { + NSAssert(NO, nil); + } + if (attribute > 37) { + NSAssert(NO, nil); + } +} + +#endif + +#pragma mark - + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeBool:self.effective forKey:@"effective"]; + [aCoder encodeBool:self.active forKey:@"active"]; + [aCoder encodeBool:self.shouldBeArchived forKey:@"shouldBeArchived"]; + [aCoder encodeObject:self.firstItem forKey:@"firstItem"]; + [aCoder encodeInteger:self.firstItemType forKey:@"firstItemType"]; + [aCoder encodeInteger:self.firstAttribute forKey:@"firstAttribute"]; + [aCoder encodeInteger:self.relation forKey:@"relation"]; + [aCoder encodeObject:self.secondItem forKey:@"secondItem"]; + [aCoder encodeInteger:self.secondItemType forKey:@"secondItemType"]; + [aCoder encodeInteger:self.secondAttribute forKey:@"secondAttribute"]; + [aCoder encodeDouble:self.multiplier forKey:@"multiplier"]; + [aCoder encodeDouble:self.constant forKey:@"constant"]; + [aCoder encodeDouble:self.priority forKey:@"priority"]; + [aCoder encodeObject:self.identifier forKey:@"identifier"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.effective = [aDecoder decodeBoolForKey:@"effective"]; + self.active = [aDecoder decodeBoolForKey:@"active"]; + self.shouldBeArchived = [aDecoder decodeBoolForKey:@"shouldBeArchived"]; + self.firstItem = [aDecoder decodeObjectForKey:@"firstItem"]; + self.firstItemType = [aDecoder decodeIntegerForKey:@"firstItemType"]; + self.firstAttribute = [aDecoder decodeIntegerForKey:@"firstAttribute"]; + self.relation = [aDecoder decodeIntegerForKey:@"relation"]; + self.secondItem = [aDecoder decodeObjectForKey:@"secondItem"]; + self.secondItemType = [aDecoder decodeIntegerForKey:@"secondItemType"]; + self.secondAttribute = [aDecoder decodeIntegerForKey:@"secondAttribute"]; + self.multiplier = [aDecoder decodeDoubleForKey:@"multiplier"]; + self.constant = [aDecoder decodeDoubleForKey:@"constant"]; + self.priority = [aDecoder decodeDoubleForKey:@"priority"]; + self.identifier = [aDecoder decodeObjectForKey:@"identifier"]; + } + return self; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinCodingValueType.h b/Pods/LookinServer/Src/Main/Shared/LookinCodingValueType.h new file mode 100644 index 00000000..8349d68f --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinCodingValueType.h @@ -0,0 +1,30 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinCodingValueType.h +// Lookin +// +// Created by Li Kai on 2019/2/13. +// https://lookin.work +// + +typedef NS_ENUM(NSInteger, LookinCodingValueType) { + LookinCodingValueTypeUnknown, + LookinCodingValueTypeChar, + LookinCodingValueTypeDouble, + LookinCodingValueTypeFloat, + LookinCodingValueTypeLongLong, +// LookinCodingValueTypePoint, +// LookinCodingValueTypeString, +// LookinCodingValueTypeStringArray, +// LookinCodingValueTypeEdgeInsets, +// LookinCodingValueTypeRect, + LookinCodingValueTypeBOOL, +// LookinCodingValueTypeSize, + LookinCodingValueTypeColor, + LookinCodingValueTypeEnum, +// LookinCodingValueTypeRange, + LookinCodingValueTypeImage +}; + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.h b/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.h new file mode 100644 index 00000000..54a4b900 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.h @@ -0,0 +1,24 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinConnectionAttachment.h +// Lookin +// +// Created by Li Kai on 2019/2/15. +// https://lookin.work +// + + + +#import +#import "LookinCodingValueType.h" + +@interface LookinConnectionAttachment : NSObject + +@property(nonatomic, assign) LookinCodingValueType dataType; + +@property(nonatomic, strong) id data; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.m b/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.m new file mode 100644 index 00000000..99eda1ea --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinConnectionAttachment.m @@ -0,0 +1,52 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinConnectionAttachment.m +// Lookin +// +// Created by Li Kai on 2019/2/15. +// https://lookin.work +// + + + +#import "LookinConnectionAttachment.h" +#import "LookinDefines.h" +#import "NSObject+Lookin.h" + +static NSString * const Key_Data = @"0"; +static NSString * const Key_DataType = @"1"; + +@interface LookinConnectionAttachment () + +@end + +@implementation LookinConnectionAttachment + +- (instancetype)init { + if (self = [super init]) { + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + + [aCoder encodeObject:[self.data lookin_encodedObjectWithType:self.dataType] forKey:Key_Data]; + [aCoder encodeInteger:self.dataType forKey:Key_DataType]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.dataType = [aDecoder decodeIntegerForKey:Key_DataType]; + self.data = [[aDecoder decodeObjectForKey:Key_Data] lookin_decodedObjectWithType:self.dataType]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.h b/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.h new file mode 100644 index 00000000..46bb0e97 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.h @@ -0,0 +1,36 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinConnectionResponse.h +// Lookin +// +// Created by Li Kai on 2019/1/15. +// https://lookin.work +// + + + +#import +#import "LookinConnectionAttachment.h" + +@interface LookinConnectionResponseAttachment : LookinConnectionAttachment + ++ (instancetype)attachmentWithError:(NSError *)error; + +@property(nonatomic, assign) int lookinServerVersion; + +@property(nonatomic, strong) NSError *error; + +/// 如果为 YES,则表示 app 正处于后台模式,默认为 NO +@property(nonatomic, assign) BOOL appIsInBackground; + +/** + dataTotalCount 为 0 时表示仅有这一个 response,默认为 0 + dataTotalCount 大于 0 时表示可能有多个 response,当所有 response 的 currentDataCount 的总和大于 dataTotalCount 即表示所有 response 已接收完毕 + */ +@property(nonatomic, assign) NSUInteger dataTotalCount; +@property(nonatomic, assign) NSUInteger currentDataCount; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.m b/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.m new file mode 100644 index 00000000..71f62fed --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinConnectionResponseAttachment.m @@ -0,0 +1,62 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinConnectionResponse.m +// Lookin +// +// Created by Li Kai on 2019/1/15. +// https://lookin.work +// + + + +#import "LookinConnectionResponseAttachment.h" +#import "LookinDefines.h" + +@interface LookinConnectionResponseAttachment () + +@end + +@implementation LookinConnectionResponseAttachment + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + [aCoder encodeInt:self.lookinServerVersion forKey:@"lookinServerVersion"]; + [aCoder encodeObject:self.error forKey:@"error"]; + [aCoder encodeObject:@(self.dataTotalCount) forKey:@"dataTotalCount"]; + [aCoder encodeObject:@(self.currentDataCount) forKey:@"currentDataCount"]; + [aCoder encodeBool:self.appIsInBackground forKey:@"appIsInBackground"]; +} + +- (instancetype)init { + if (self = [super init]) { + self.lookinServerVersion = LOOKIN_SERVER_VERSION; + self.dataTotalCount = 0; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + self.lookinServerVersion = [aDecoder decodeIntForKey:@"lookinServerVersion"]; + self.error = [aDecoder decodeObjectForKey:@"error"]; + self.dataTotalCount = [[aDecoder decodeObjectForKey:@"dataTotalCount"] unsignedIntegerValue]; + self.currentDataCount = [[aDecoder decodeObjectForKey:@"currentDataCount"] unsignedIntegerValue]; + self.appIsInBackground = [aDecoder decodeBoolForKey:@"appIsInBackground"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + ++ (instancetype)attachmentWithError:(NSError *)error { + LookinConnectionResponseAttachment *attachment = [LookinConnectionResponseAttachment new]; + attachment.error = error; + return attachment; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.h b/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.h new file mode 100644 index 00000000..1be7926a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.h @@ -0,0 +1,20 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LookinCustomAttrModification.h +// LookinShared +// +// Created by likaimacbookhome on 2023/11/4. +// + +#import +#import "LookinAttrType.h" + +@interface LookinCustomAttrModification : NSObject + +@property(nonatomic, assign) LookinAttrType attrType; +@property(nonatomic, copy) NSString *customSetterID; +@property(nonatomic, strong) id value; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.m b/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.m new file mode 100644 index 00000000..6d490165 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinCustomAttrModification.m @@ -0,0 +1,34 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LookinCustomAttrModification.m +// LookinShared +// +// Created by likaimacbookhome on 2023/11/4. +// + +#import "LookinCustomAttrModification.h" + +@implementation LookinCustomAttrModification + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInteger:self.attrType forKey:@"attrType"]; + [aCoder encodeObject:self.value forKey:@"value"]; + [aCoder encodeObject:self.customSetterID forKey:@"customSetterID"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.attrType = [aDecoder decodeIntegerForKey:@"attrType"]; + self.value = [aDecoder decodeObjectForKey:@"value"]; + self.customSetterID = [aDecoder decodeObjectForKey:@"customSetterID"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.h b/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.h new file mode 100644 index 00000000..a74d6ed3 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.h @@ -0,0 +1,21 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER +// +// LookinCustomDisplayItemInfo.h +// LookinServer +// +// Created by likai.123 on 2023/11/1. +// + +#import + +@interface LookinCustomDisplayItemInfo : NSObject + +/// 该属性可能有值(CGRect)也可能是 nil(nil 时则表示无图像) +@property(nonatomic, strong) NSValue *frameInWindow; +@property(nonatomic, copy) NSString *title; +@property(nonatomic, copy) NSString *subtitle; +@property(nonatomic, copy) NSString *danceuiSource; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.m b/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.m new file mode 100644 index 00000000..a59778ab --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinCustomDisplayItemInfo.m @@ -0,0 +1,59 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinCustomDisplayItemInfo.m +// LookinServer +// +// Created by likai.123 on 2023/11/1. +// + +#import "LookinCustomDisplayItemInfo.h" +#if TARGET_OS_IPHONE +#import +#endif + +@implementation LookinCustomDisplayItemInfo + +- (id)copyWithZone:(NSZone *)zone { + LookinCustomDisplayItemInfo *newInstance = [[LookinCustomDisplayItemInfo allocWithZone:zone] init]; + + if (self.frameInWindow) { +#if TARGET_OS_IPHONE + CGRect rect = [self.frameInWindow CGRectValue]; + newInstance.frameInWindow = [NSValue valueWithCGRect:rect]; +#elif TARGET_OS_MAC + CGRect rect = [self.frameInWindow rectValue]; + newInstance.frameInWindow = [NSValue valueWithRect:rect]; +#endif + } + newInstance.title = self.title; + newInstance.subtitle = self.subtitle; + newInstance.danceuiSource = self.danceuiSource; + + return newInstance; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.frameInWindow forKey:@"frameInWindow"]; + [aCoder encodeObject:self.title forKey:@"title"]; + [aCoder encodeObject:self.subtitle forKey:@"subtitle"]; + [aCoder encodeObject:self.danceuiSource forKey:@"danceuiSource"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.frameInWindow = [aDecoder decodeObjectForKey:@"frameInWindow"]; + self.title = [aDecoder decodeObjectForKey:@"title"]; + self.subtitle = [aDecoder decodeObjectForKey:@"subtitle"]; + self.danceuiSource = [aDecoder decodeObjectForKey:@"danceuiSource"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.h b/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.h new file mode 100644 index 00000000..361789a1 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.h @@ -0,0 +1,77 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDashboardBlueprint.h +// Lookin +// +// Created by Li Kai on 2019/6/5. +// https://lookin.work +// + + + +#import +#import "LookinAttrIdentifiers.h" +#import "LookinAttrType.h" + +/** + 该对象定义了: + - 每一个 Attr 的信息 + - 哪些 GroupID, SectionID, AttrID 是合法的 + - 这些 ID 的父子顺序,比如 LookinAttrGroup_Frame 包含哪些 Section + - 这些 ID 展示顺序(比如哪个 Group 在前、哪个 Group 在后) + */ +@interface LookinDashboardBlueprint : NSObject + ++ (NSArray *)groupIDs; + ++ (NSArray *)sectionIDsForGroupID:(LookinAttrGroupIdentifier)groupID; + ++ (NSArray *)attrIDsForSectionID:(LookinAttrSectionIdentifier)sectionID; + +/// 返回包含目标 attr 的 groupID 和 sectionID ++ (void)getHostGroupID:(inout LookinAttrGroupIdentifier *)groupID sectionID:(inout LookinAttrSectionIdentifier *)sectionID fromAttrID:(LookinAttrIdentifier)attrID; + +/// 返回某个 group 的标题 ++ (NSString *)groupTitleWithGroupID:(LookinAttrGroupIdentifier)groupID; + +/// 返回某个 section 的标题,nil 则表示不显示标题 ++ (NSString *)sectionTitleWithSectionID:(LookinAttrSectionIdentifier)secID; + +/// 当某个 LookinAttribute 确定是 NSObject 类型时,该方法返回它具体是什么对象,比如 UIColor 等 ++ (LookinAttrType)objectAttrTypeWithAttrID:(LookinAttrIdentifier)attrID; + +/// 返回某个 LookinAttribute 代表的属性是哪一个类拥有的,比如 LookinAttrSec_UILabel_TextColor 是 UILabel 才有的 ++ (NSString *)classNameWithAttrID:(LookinAttrIdentifier)attrID; + +/// 一个 attr 要么属于 UIView 要么属于 CALayer,如果它属于 UIView 那么该方法返回 YES ++ (BOOL)isUIViewPropertyWithAttrID:(LookinAttrIdentifier)attrID; + +/// 如果某个 attribute 是 enum,则这里会返回相应的 enum 的名称(如 @"NSTextAlignment"),进而可通过这个名称查询可用的枚举值列表 ++ (NSString *)enumListNameWithAttrID:(LookinAttrIdentifier)attrID; + +/// 如果返回 YES,则说明用户在 Lookin 里修改了该 Attribute 的值后,应该重新拉取和更新相关图层的位置、截图等信息 ++ (BOOL)needPatchAfterModificationWithAttrID:(LookinAttrIdentifier)attrID; + +/// 完整的名字 ++ (NSString *)fullTitleWithAttrID:(LookinAttrIdentifier)attrID; + +/// 在某些 textField 和 checkbox 里会显示这里返回的 title ++ (NSString *)briefTitleWithAttrID:(LookinAttrIdentifier)attrID; + +/// 获取 getter 方法 ++ (SEL)getterWithAttrID:(LookinAttrIdentifier)attrID; + +/// 获取 setter 方法 ++ (SEL)setterWithAttrID:(LookinAttrIdentifier)attrID; + +/// 获取 “hideIfNil” 的值。如果为 YES,则当读取 getter 获取的 value 为 nil 时,Lookin 不会传输该 attr +/// 如果为 NO,则即使 value 为 nil 也会传输(比如 label 的 text 属性,即使它是 nil 我们也要显示,所以它的 hideIfNil 应该为 NO) ++ (BOOL)hideIfNilWithAttrID:(LookinAttrIdentifier)attrID; + +/// 该属性需要的最低的 iOS 版本,比如 safeAreaInsets 从 iOS 11.0 开始出现,则该方法返回 11,如果返回 0 则表示不限制 iOS 版本(注意 Lookin 项目仅支持 iOS 8.0+) ++ (NSInteger)minAvailableOSVersionWithAttrID:(LookinAttrIdentifier)attrID; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.m b/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.m new file mode 100644 index 00000000..3daf0358 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDashboardBlueprint.m @@ -0,0 +1,1196 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDashboardBlueprint.m +// Lookin +// +// Created by Li Kai on 2019/6/5. +// https://lookin.work +// + + + +#import "LookinDashboardBlueprint.h" + +@implementation LookinDashboardBlueprint + ++ (NSArray *)groupIDs { + static NSArray *array; + static dispatch_once_t onceToken; + dispatch_once(&onceToken,^{ + array = @[ + LookinAttrGroup_Class, + LookinAttrGroup_Relation, + LookinAttrGroup_Layout, + LookinAttrGroup_AutoLayout, + LookinAttrGroup_ViewLayer, + LookinAttrGroup_UIStackView, + LookinAttrGroup_UIVisualEffectView, + LookinAttrGroup_UIImageView, + LookinAttrGroup_UILabel, + LookinAttrGroup_UIControl, + LookinAttrGroup_UIButton, + LookinAttrGroup_UIScrollView, + LookinAttrGroup_UITableView, + LookinAttrGroup_UITextView, + LookinAttrGroup_UITextField + ]; + }); + return array; +} + ++ (NSArray *)sectionIDsForGroupID:(LookinAttrGroupIdentifier)groupID { + static NSDictionary *> *dict; + static dispatch_once_t onceToken; + dispatch_once(&onceToken,^{ + dict = @{ + LookinAttrGroup_Class: @[LookinAttrSec_Class_Class], + + LookinAttrGroup_Relation: @[LookinAttrSec_Relation_Relation], + + LookinAttrGroup_Layout: @[LookinAttrSec_Layout_Frame, + LookinAttrSec_Layout_Bounds, + LookinAttrSec_Layout_SafeArea, + LookinAttrSec_Layout_Position, + LookinAttrSec_Layout_AnchorPoint], + + LookinAttrGroup_AutoLayout: @[LookinAttrSec_AutoLayout_Constraints, + LookinAttrSec_AutoLayout_IntrinsicSize, + LookinAttrSec_AutoLayout_Hugging, + LookinAttrSec_AutoLayout_Resistance], + + LookinAttrGroup_ViewLayer: @[ + LookinAttrSec_ViewLayer_Visibility, + LookinAttrSec_ViewLayer_InterationAndMasks, + LookinAttrSec_ViewLayer_BgColor, + LookinAttrSec_ViewLayer_Border, + LookinAttrSec_ViewLayer_Corner, + LookinAttrSec_ViewLayer_Shadow, + LookinAttrSec_ViewLayer_ContentMode, + LookinAttrSec_ViewLayer_TintColor, + LookinAttrSec_ViewLayer_Tag + ], + + LookinAttrGroup_UIStackView: @[ + LookinAttrSec_UIStackView_Axis, + LookinAttrSec_UIStackView_Distribution, + LookinAttrSec_UIStackView_Alignment, + LookinAttrSec_UIStackView_Spacing + ], + + LookinAttrGroup_UIVisualEffectView: @[ + LookinAttrSec_UIVisualEffectView_Style, + LookinAttrSec_UIVisualEffectView_QMUIForegroundColor + ], + + LookinAttrGroup_UIImageView: @[LookinAttrSec_UIImageView_Name, + LookinAttrSec_UIImageView_Open], + + LookinAttrGroup_UILabel: @[ + LookinAttrSec_UILabel_Text, + LookinAttrSec_UILabel_Font, + LookinAttrSec_UILabel_NumberOfLines, + LookinAttrSec_UILabel_TextColor, + LookinAttrSec_UILabel_BreakMode, + LookinAttrSec_UILabel_Alignment, + LookinAttrSec_UILabel_CanAdjustFont], + + LookinAttrGroup_UIControl: @[LookinAttrSec_UIControl_EnabledSelected, + LookinAttrSec_UIControl_QMUIOutsideEdge, + LookinAttrSec_UIControl_VerAlignment, + LookinAttrSec_UIControl_HorAlignment], + + LookinAttrGroup_UIButton: @[LookinAttrSec_UIButton_ContentInsets, + LookinAttrSec_UIButton_TitleInsets, + LookinAttrSec_UIButton_ImageInsets], + + LookinAttrGroup_UIScrollView: @[LookinAttrSec_UIScrollView_ContentInset, + LookinAttrSec_UIScrollView_AdjustedInset, + LookinAttrSec_UIScrollView_QMUIInitialInset, + LookinAttrSec_UIScrollView_IndicatorInset, + LookinAttrSec_UIScrollView_Offset, + LookinAttrSec_UIScrollView_ContentSize, + LookinAttrSec_UIScrollView_Behavior, + LookinAttrSec_UIScrollView_ShowsIndicator, + LookinAttrSec_UIScrollView_Bounce, + LookinAttrSec_UIScrollView_ScrollPaging, + LookinAttrSec_UIScrollView_ContentTouches, + LookinAttrSec_UIScrollView_Zoom], + + LookinAttrGroup_UITableView: @[LookinAttrSec_UITableView_Style, + LookinAttrSec_UITableView_SectionsNumber, + LookinAttrSec_UITableView_RowsNumber, + LookinAttrSec_UITableView_SeparatorStyle, + LookinAttrSec_UITableView_SeparatorColor, + LookinAttrSec_UITableView_SeparatorInset], + + LookinAttrGroup_UITextView: @[LookinAttrSec_UITextView_Basic, + LookinAttrSec_UITextView_Text, + LookinAttrSec_UITextView_Font, + LookinAttrSec_UITextView_TextColor, + LookinAttrSec_UITextView_Alignment, + LookinAttrSec_UITextView_ContainerInset], + + LookinAttrGroup_UITextField: @[LookinAttrSec_UITextField_Text, + LookinAttrSec_UITextField_Placeholder, + LookinAttrSec_UITextField_Font, + LookinAttrSec_UITextField_TextColor, + LookinAttrSec_UITextField_Alignment, + LookinAttrSec_UITextField_Clears, + LookinAttrSec_UITextField_CanAdjustFont, + LookinAttrSec_UITextField_ClearButtonMode], + + }; + }); + return dict[groupID]; +} + ++ (NSArray *)attrIDsForSectionID:(LookinAttrSectionIdentifier)sectionID { + static NSDictionary *> *dict; + static dispatch_once_t onceToken; + dispatch_once(&onceToken,^{ + dict = @{ + LookinAttrSec_Class_Class: @[LookinAttr_Class_Class_Class], + + LookinAttrSec_Relation_Relation: @[LookinAttr_Relation_Relation_Relation], + + LookinAttrSec_Layout_Frame: @[LookinAttr_Layout_Frame_Frame], + LookinAttrSec_Layout_Bounds: @[LookinAttr_Layout_Bounds_Bounds], + LookinAttrSec_Layout_SafeArea: @[LookinAttr_Layout_SafeArea_SafeArea], + LookinAttrSec_Layout_Position: @[LookinAttr_Layout_Position_Position], + LookinAttrSec_Layout_AnchorPoint: @[LookinAttr_Layout_AnchorPoint_AnchorPoint], + + LookinAttrSec_AutoLayout_Hugging: @[LookinAttr_AutoLayout_Hugging_Hor, + LookinAttr_AutoLayout_Hugging_Ver], + LookinAttrSec_AutoLayout_Resistance: @[LookinAttr_AutoLayout_Resistance_Hor, + LookinAttr_AutoLayout_Resistance_Ver], + LookinAttrSec_AutoLayout_Constraints: @[LookinAttr_AutoLayout_Constraints_Constraints], + LookinAttrSec_AutoLayout_IntrinsicSize: @[LookinAttr_AutoLayout_IntrinsicSize_Size], + + LookinAttrSec_ViewLayer_Visibility: @[LookinAttr_ViewLayer_Visibility_Hidden, + LookinAttr_ViewLayer_Visibility_Opacity], + + LookinAttrSec_ViewLayer_InterationAndMasks: @[LookinAttr_ViewLayer_InterationAndMasks_Interaction, + LookinAttr_ViewLayer_InterationAndMasks_MasksToBounds], + + LookinAttrSec_ViewLayer_Corner: @[LookinAttr_ViewLayer_Corner_Radius], + + LookinAttrSec_ViewLayer_BgColor: @[LookinAttr_ViewLayer_BgColor_BgColor], + + LookinAttrSec_ViewLayer_Border: @[LookinAttr_ViewLayer_Border_Color, + LookinAttr_ViewLayer_Border_Width], + + LookinAttrSec_ViewLayer_Shadow: @[LookinAttr_ViewLayer_Shadow_Color, + LookinAttr_ViewLayer_Shadow_Opacity, + LookinAttr_ViewLayer_Shadow_Radius, + LookinAttr_ViewLayer_Shadow_OffsetW, + LookinAttr_ViewLayer_Shadow_OffsetH], + + LookinAttrSec_ViewLayer_ContentMode: @[LookinAttr_ViewLayer_ContentMode_Mode], + + LookinAttrSec_ViewLayer_TintColor: @[LookinAttr_ViewLayer_TintColor_Color, + LookinAttr_ViewLayer_TintColor_Mode], + + LookinAttrSec_ViewLayer_Tag: @[LookinAttr_ViewLayer_Tag_Tag], + + LookinAttrSec_UIStackView_Axis: @[LookinAttr_UIStackView_Axis_Axis], + + LookinAttrSec_UIStackView_Distribution: @[LookinAttr_UIStackView_Distribution_Distribution], + + LookinAttrSec_UIStackView_Alignment: @[LookinAttr_UIStackView_Alignment_Alignment], + + LookinAttrSec_UIStackView_Spacing: @[LookinAttr_UIStackView_Spacing_Spacing], + + LookinAttrSec_UIVisualEffectView_Style: @[LookinAttr_UIVisualEffectView_Style_Style], + + LookinAttrSec_UIVisualEffectView_QMUIForegroundColor: @[LookinAttr_UIVisualEffectView_QMUIForegroundColor_Color], + + LookinAttrSec_UIImageView_Name: @[LookinAttr_UIImageView_Name_Name], + + LookinAttrSec_UIImageView_Open: @[LookinAttr_UIImageView_Open_Open], + + LookinAttrSec_UILabel_Font: @[LookinAttr_UILabel_Font_Name, + LookinAttr_UILabel_Font_Size], + + LookinAttrSec_UILabel_NumberOfLines: @[LookinAttr_UILabel_NumberOfLines_NumberOfLines], + + LookinAttrSec_UILabel_Text: @[LookinAttr_UILabel_Text_Text], + + LookinAttrSec_UILabel_TextColor: @[LookinAttr_UILabel_TextColor_Color], + + LookinAttrSec_UILabel_BreakMode: @[LookinAttr_UILabel_BreakMode_Mode], + + LookinAttrSec_UILabel_Alignment: @[LookinAttr_UILabel_Alignment_Alignment], + + LookinAttrSec_UILabel_CanAdjustFont: @[LookinAttr_UILabel_CanAdjustFont_CanAdjustFont], + + LookinAttrSec_UIControl_EnabledSelected: @[LookinAttr_UIControl_EnabledSelected_Enabled, + LookinAttr_UIControl_EnabledSelected_Selected], + + LookinAttrSec_UIControl_QMUIOutsideEdge: @[LookinAttr_UIControl_QMUIOutsideEdge_Edge], + + LookinAttrSec_UIControl_VerAlignment: @[LookinAttr_UIControl_VerAlignment_Alignment], + + LookinAttrSec_UIControl_HorAlignment: @[LookinAttr_UIControl_HorAlignment_Alignment], + + LookinAttrSec_UIButton_ContentInsets: @[LookinAttr_UIButton_ContentInsets_Insets], + + LookinAttrSec_UIButton_TitleInsets: @[LookinAttr_UIButton_TitleInsets_Insets], + + LookinAttrSec_UIButton_ImageInsets: @[LookinAttr_UIButton_ImageInsets_Insets], + + LookinAttrSec_UIScrollView_ContentInset: @[LookinAttr_UIScrollView_ContentInset_Inset], + + LookinAttrSec_UIScrollView_AdjustedInset: @[LookinAttr_UIScrollView_AdjustedInset_Inset], + + LookinAttrSec_UIScrollView_QMUIInitialInset: @[LookinAttr_UIScrollView_QMUIInitialInset_Inset], + + LookinAttrSec_UIScrollView_IndicatorInset: @[LookinAttr_UIScrollView_IndicatorInset_Inset], + + LookinAttrSec_UIScrollView_Offset: @[LookinAttr_UIScrollView_Offset_Offset], + + LookinAttrSec_UIScrollView_ContentSize: @[LookinAttr_UIScrollView_ContentSize_Size], + + LookinAttrSec_UIScrollView_Behavior: @[LookinAttr_UIScrollView_Behavior_Behavior], + + LookinAttrSec_UIScrollView_ShowsIndicator: @[LookinAttr_UIScrollView_ShowsIndicator_Hor, + LookinAttr_UIScrollView_ShowsIndicator_Ver], + + LookinAttrSec_UIScrollView_Bounce: @[LookinAttr_UIScrollView_Bounce_Hor, + LookinAttr_UIScrollView_Bounce_Ver], + + LookinAttrSec_UIScrollView_ScrollPaging: @[LookinAttr_UIScrollView_ScrollPaging_ScrollEnabled, + LookinAttr_UIScrollView_ScrollPaging_PagingEnabled], + + LookinAttrSec_UIScrollView_ContentTouches: @[LookinAttr_UIScrollView_ContentTouches_Delay, + LookinAttr_UIScrollView_ContentTouches_CanCancel], + + LookinAttrSec_UIScrollView_Zoom: @[LookinAttr_UIScrollView_Zoom_Bounce, + LookinAttr_UIScrollView_Zoom_Scale, + LookinAttr_UIScrollView_Zoom_MinScale, + LookinAttr_UIScrollView_Zoom_MaxScale], + + LookinAttrSec_UITableView_Style: @[LookinAttr_UITableView_Style_Style], + + LookinAttrSec_UITableView_SectionsNumber: @[LookinAttr_UITableView_SectionsNumber_Number], + + LookinAttrSec_UITableView_RowsNumber: @[LookinAttr_UITableView_RowsNumber_Number], + + LookinAttrSec_UITableView_SeparatorInset: @[LookinAttr_UITableView_SeparatorInset_Inset], + + LookinAttrSec_UITableView_SeparatorColor: @[LookinAttr_UITableView_SeparatorColor_Color], + + LookinAttrSec_UITableView_SeparatorStyle: @[LookinAttr_UITableView_SeparatorStyle_Style], + + LookinAttrSec_UITextView_Basic: @[LookinAttr_UITextView_Basic_Editable, + LookinAttr_UITextView_Basic_Selectable], + + LookinAttrSec_UITextView_Text: @[LookinAttr_UITextView_Text_Text], + + LookinAttrSec_UITextView_Font: @[LookinAttr_UITextView_Font_Name, + LookinAttr_UITextView_Font_Size], + + LookinAttrSec_UITextView_TextColor: @[LookinAttr_UITextView_TextColor_Color], + + LookinAttrSec_UITextView_Alignment: @[LookinAttr_UITextView_Alignment_Alignment], + + LookinAttrSec_UITextView_ContainerInset: @[LookinAttr_UITextView_ContainerInset_Inset], + + LookinAttrSec_UITextField_Text: @[LookinAttr_UITextField_Text_Text], + + LookinAttrSec_UITextField_Placeholder: @[LookinAttr_UITextField_Placeholder_Placeholder], + + LookinAttrSec_UITextField_Font: @[LookinAttr_UITextField_Font_Name, + LookinAttr_UITextField_Font_Size], + + LookinAttrSec_UITextField_TextColor: @[LookinAttr_UITextField_TextColor_Color], + + LookinAttrSec_UITextField_Alignment: @[LookinAttr_UITextField_Alignment_Alignment], + + LookinAttrSec_UITextField_Clears: @[LookinAttr_UITextField_Clears_ClearsOnBeginEditing, + LookinAttr_UITextField_Clears_ClearsOnInsertion], + + LookinAttrSec_UITextField_CanAdjustFont: @[LookinAttr_UITextField_CanAdjustFont_CanAdjustFont, + LookinAttr_UITextField_CanAdjustFont_MinSize], + + LookinAttrSec_UITextField_ClearButtonMode: @[LookinAttr_UITextField_ClearButtonMode_Mode] + }; + }); + return dict[sectionID]; +} + ++ (void)getHostGroupID:(inout LookinAttrGroupIdentifier *)groupID_inout sectionID:(inout LookinAttrSectionIdentifier *)sectionID_inout fromAttrID:(LookinAttrIdentifier)targetAttrID { + __block LookinAttrGroupIdentifier targetGroupID = nil; + __block LookinAttrSectionIdentifier targetSecID = nil; + [[self groupIDs] enumerateObjectsUsingBlock:^(LookinAttrGroupIdentifier _Nonnull groupID, NSUInteger idx, BOOL * _Nonnull stop0) { + [[self sectionIDsForGroupID:groupID] enumerateObjectsUsingBlock:^(LookinAttrSectionIdentifier _Nonnull secID, NSUInteger idx, BOOL * _Nonnull stop1) { + [[self attrIDsForSectionID:secID] enumerateObjectsUsingBlock:^(LookinAttrIdentifier _Nonnull attrID, NSUInteger idx, BOOL * _Nonnull stop2) { + if ([attrID isEqualToString:targetAttrID]) { + targetGroupID = groupID; + targetSecID = secID; + *stop0 = YES; + *stop1 = YES; + *stop2 = YES; + } + }]; + }]; + }]; + + if (groupID_inout && targetGroupID) { + *groupID_inout = targetGroupID; + } + if (sectionID_inout && targetSecID) { + *sectionID_inout = targetSecID; + } +} + ++ (NSString *)groupTitleWithGroupID:(LookinAttrGroupIdentifier)groupID { + static dispatch_once_t onceToken; + static NSDictionary *rawInfo = nil; + dispatch_once(&onceToken,^{ + rawInfo = @{ + LookinAttrGroup_Class: @"Class", + LookinAttrGroup_Relation: @"Relation", + LookinAttrGroup_Layout: @"Layout", + LookinAttrGroup_AutoLayout: @"AutoLayout", + LookinAttrGroup_ViewLayer: @"CALayer / UIView", + LookinAttrGroup_UIImageView: @"UIImageView", + LookinAttrGroup_UILabel: @"UILabel", + LookinAttrGroup_UIControl: @"UIControl", + LookinAttrGroup_UIButton: @"UIButton", + LookinAttrGroup_UIScrollView: @"UIScrollView", + LookinAttrGroup_UITableView: @"UITableView", + LookinAttrGroup_UITextView: @"UITextView", + LookinAttrGroup_UITextField: @"UITextField", + LookinAttrGroup_UIVisualEffectView: @"UIVisualEffectView", + LookinAttrGroup_UIStackView: @"UIStackView" + }; + }); + NSString *title = rawInfo[groupID]; + NSAssert(title.length, @""); + return title; +} + ++ (NSString *)sectionTitleWithSectionID:(LookinAttrSectionIdentifier)secID { + static dispatch_once_t onceToken; + static NSDictionary *rawInfo = nil; + dispatch_once(&onceToken,^{ + rawInfo = @{ + LookinAttrSec_Layout_Frame: @"Frame", + LookinAttrSec_Layout_Bounds: @"Bounds", + LookinAttrSec_Layout_SafeArea: @"SafeArea", + LookinAttrSec_Layout_Position: @"Position", + LookinAttrSec_Layout_AnchorPoint: @"AnchorPoint", + LookinAttrSec_AutoLayout_Hugging: @"HuggingPriority", + LookinAttrSec_AutoLayout_Resistance: @"ResistancePriority", + LookinAttrSec_AutoLayout_IntrinsicSize: @"IntrinsicSize", + LookinAttrSec_ViewLayer_Corner: @"CornerRadius", + LookinAttrSec_ViewLayer_BgColor: @"BackgroundColor", + LookinAttrSec_ViewLayer_Border: @"Border", + LookinAttrSec_ViewLayer_Shadow: @"Shadow", + LookinAttrSec_ViewLayer_ContentMode: @"ContentMode", + LookinAttrSec_ViewLayer_TintColor: @"TintColor", + LookinAttrSec_ViewLayer_Tag: @"Tag", + LookinAttrSec_UIStackView_Axis: @"Axis", + LookinAttrSec_UIStackView_Distribution: @"Distribution", + LookinAttrSec_UIStackView_Alignment: @"Alignment", + LookinAttrSec_UIVisualEffectView_Style: @"Style", + LookinAttrSec_UIVisualEffectView_QMUIForegroundColor: @"ForegroundColor", + LookinAttrSec_UIImageView_Name: @"ImageName", + LookinAttrSec_UILabel_TextColor: @"TextColor", + LookinAttrSec_UITextView_TextColor: @"TextColor", + LookinAttrSec_UITextField_TextColor: @"TextColor", + LookinAttrSec_UILabel_BreakMode: @"LineBreakMode", + LookinAttrSec_UILabel_NumberOfLines: @"NumberOfLines", + LookinAttrSec_UILabel_Text: @"Text", + LookinAttrSec_UITextView_Text: @"Text", + LookinAttrSec_UITextField_Text: @"Text", + LookinAttrSec_UITextField_Placeholder: @"Placeholder", + LookinAttrSec_UILabel_Alignment: @"TextAlignment", + LookinAttrSec_UITextView_Alignment: @"TextAlignment", + LookinAttrSec_UITextField_Alignment: @"TextAlignment", + LookinAttrSec_UIControl_HorAlignment: @"HorizontalAlignment", + LookinAttrSec_UIControl_VerAlignment: @"VerticalAlignment", + LookinAttrSec_UIControl_QMUIOutsideEdge: @"QMUI_outsideEdge", + LookinAttrSec_UIButton_ContentInsets: @"ContentInsets", + LookinAttrSec_UIButton_TitleInsets: @"TitleInsets", + LookinAttrSec_UIButton_ImageInsets: @"ImageInsets", + LookinAttrSec_UIScrollView_QMUIInitialInset: @"QMUI_initialContentInset", + LookinAttrSec_UIScrollView_ContentInset: @"ContentInset", + LookinAttrSec_UIScrollView_AdjustedInset: @"AdjustedContentInset", + LookinAttrSec_UIScrollView_IndicatorInset: @"ScrollIndicatorInsets", + LookinAttrSec_UIScrollView_Offset: @"ContentOffset", + LookinAttrSec_UIScrollView_ContentSize: @"ContentSize", + LookinAttrSec_UIScrollView_Behavior: @"InsetAdjustmentBehavior", + LookinAttrSec_UIScrollView_ShowsIndicator: @"ShowsScrollIndicator", + LookinAttrSec_UIScrollView_Bounce: @"AlwaysBounce", + LookinAttrSec_UIScrollView_Zoom: @"Zoom", + LookinAttrSec_UITableView_Style: @"Style", + LookinAttrSec_UITableView_SectionsNumber: @"NumberOfSections", + LookinAttrSec_UITableView_RowsNumber: @"NumberOfRows", + LookinAttrSec_UITableView_SeparatorColor: @"SeparatorColor", + LookinAttrSec_UITableView_SeparatorInset: @"SeparatorInset", + LookinAttrSec_UITableView_SeparatorStyle: @"SeparatorStyle", + LookinAttrSec_UILabel_Font: @"Font", + LookinAttrSec_UITextField_Font: @"Font", + LookinAttrSec_UITextView_Font: @"Font", + LookinAttrSec_UITextView_ContainerInset: @"ContainerInset", + LookinAttrSec_UITextField_ClearButtonMode: @"ClearButtonMode", + }; + }); + return rawInfo[secID]; +} + +/** + className: 必填项,标识该属性是哪一个类拥有的 + + fullTitle: 完整的名字,将作为搜索的 keywords,也会展示在搜索结果中,如果为 nil 则不会被搜索到 + + briefTitle:简略的名字,仅 checkbox 和那种自带标题的 input 才需要这个属性,如果需要该属性但该属性又为空,则会读取 fullTitle + + setterString:用户试图修改属性值时会用到,若该字段为空字符串(即 @“”)则该属性不可修改,若该字段为 nil 则会在 fullTitle 的基础上自动生成(自动改首字母大小写、加前缀后缀,比如 alpha 会被转换为 setAlpha:) + + getterString:必填项,业务中读取属性值时会用到。如果该字段为 nil ,则会在 fullTitle 的基础上自动生成(自动把 fullTitle 的第一个字母改成小写,比如 Alpha 会被转换为 alpha)。如果该字段为空字符串(比如 image_open_open)则属性值会被固定为 nil,attrType 会被指为 LookinAttrTypeCustomObj + + typeIfObj:当某个 LookinAttribute 确定是 NSObject 类型时,该方法返回它具体是什么对象,比如 UIColor、NSString + + enumList:如果某个 attribute 是 enum,则这里标识了相应的 enum 的名称(如 "NSTextAlignment"),业务可通过这个名称进而查询可用的枚举值列表 + + patch:如果为 YES,则用户修改了该 Attribute 的值后,Lookin 会重新拉取和更新相关图层的位置、截图等信息,如果为 nil 则默认是 NO + + hideIfNil:如果为 YES,则当获取的 value 为 nil 时,Lookin 不会传输该 attr。如果为 NO,则即使 value 为 nil 也会传输(比如 label 的 text 属性,即使它是 nil 我们也要显示,所以它的 hideIfNil 应该为 NO)。如果该字段为 nil 则默认是 NO + + osVersion: 该属性需要的最低的 iOS 版本,比如 safeAreaInsets 从 iOS 11.0 开始出现,则该属性应该为 @11,如果为 nil 则表示不限制 iOS 版本 + + */ ++ (NSDictionary *)_infoForAttrID:(LookinAttrIdentifier)attrID { + static NSDictionary *> *dict; + static dispatch_once_t onceToken; + dispatch_once(&onceToken,^{ + dict = @{ + LookinAttr_Class_Class_Class: @{ + @"className": @"CALayer", + @"getterString": @"lks_relatedClassChainList", + @"setterString": @"", + @"typeIfObj": @(LookinAttrTypeCustomObj) + }, + + LookinAttr_Relation_Relation_Relation: @{ + @"className": @"CALayer", + @"getterString": @"lks_selfRelation", + @"setterString": @"", + @"typeIfObj": @(LookinAttrTypeCustomObj), + @"hideIfNil": @(YES) + }, + + LookinAttr_Layout_Frame_Frame: @{ + @"className": @"CALayer", + @"fullTitle": @"Frame", + @"patch": @(YES) + }, + LookinAttr_Layout_Bounds_Bounds: @{ + @"className": @"CALayer", + @"fullTitle": @"Bounds", + @"patch": @(YES) + }, + LookinAttr_Layout_SafeArea_SafeArea: @{ + @"className": @"UIView", + @"fullTitle": @"SafeAreaInsets", + @"setterString": @"", + @"osVersion": @(11) + }, + LookinAttr_Layout_Position_Position: @{ + @"className": @"CALayer", + @"fullTitle": @"Position", + @"patch": @(YES) + }, + LookinAttr_Layout_AnchorPoint_AnchorPoint: @{ + @"className": @"CALayer", + @"fullTitle": @"AnchorPoint", + @"patch": @(YES) + }, + + LookinAttr_AutoLayout_Hugging_Hor: @{ + @"className": @"UIView", + @"fullTitle": @"ContentHuggingPriority(Horizontal)", + @"getterString": @"lks_horizontalContentHuggingPriority", + @"setterString": @"setLks_horizontalContentHuggingPriority:", + @"briefTitle": @"H", + @"patch": @(YES) + }, + LookinAttr_AutoLayout_Hugging_Ver: @{ + @"className": @"UIView", + @"fullTitle": @"ContentHuggingPriority(Vertical)", + @"getterString": @"lks_verticalContentHuggingPriority", + @"setterString": @"setLks_verticalContentHuggingPriority:", + @"briefTitle": @"V", + @"patch": @(YES) + }, + LookinAttr_AutoLayout_Resistance_Hor: @{ + @"className": @"UIView", + @"fullTitle": @"ContentCompressionResistancePriority(Horizontal)", + @"getterString": @"lks_horizontalContentCompressionResistancePriority", + @"setterString": @"setLks_horizontalContentCompressionResistancePriority:", + @"briefTitle": @"H", + @"patch": @(YES) + }, + LookinAttr_AutoLayout_Resistance_Ver: @{ + @"className": @"UIView", + @"fullTitle": @"ContentCompressionResistancePriority(Vertical)", + @"getterString": @"lks_verticalContentCompressionResistancePriority", + @"setterString": @"setLks_verticalContentCompressionResistancePriority:", + @"briefTitle": @"V", + @"patch": @(YES) + }, + LookinAttr_AutoLayout_Constraints_Constraints: @{ + @"className": @"UIView", + @"getterString": @"lks_constraints", + @"setterString": @"", + @"typeIfObj": @(LookinAttrTypeCustomObj), + @"hideIfNil": @(YES) + }, + LookinAttr_AutoLayout_IntrinsicSize_Size: @{ + @"className": @"UIView", + @"fullTitle": @"IntrinsicContentSize", + @"setterString": @"" + }, + + LookinAttr_ViewLayer_Visibility_Hidden: @{ + @"className": @"CALayer", + @"fullTitle": @"Hidden", + @"getterString": @"isHidden", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Visibility_Opacity: @{ + @"className": @"CALayer", + @"fullTitle": @"Opacity / Alpha", + @"setterString": @"setOpacity:", + @"getterString": @"opacity", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_InterationAndMasks_Interaction: @{ + @"className": @"UIView", + @"fullTitle": @"UserInteractionEnabled", + @"getterString": @"isUserInteractionEnabled", + @"patch": @(NO) + }, + LookinAttr_ViewLayer_InterationAndMasks_MasksToBounds: @{ + @"className": @"CALayer", + @"fullTitle": @"MasksToBounds / ClipsToBounds", + @"briefTitle": @"MasksToBounds", + @"setterString": @"setMasksToBounds:", + @"getterString": @"masksToBounds", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Corner_Radius: @{ + @"className": @"CALayer", + @"fullTitle": @"CornerRadius", + @"briefTitle": @"", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_BgColor_BgColor: @{ + @"className": @"CALayer", + @"fullTitle": @"BackgroundColor", + @"setterString": @"setLks_backgroundColor:", + @"getterString": @"lks_backgroundColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Border_Color: @{ + @"className": @"CALayer", + @"fullTitle": @"BorderColor", + @"setterString": @"setLks_borderColor:", + @"getterString": @"lks_borderColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Border_Width: @{ + @"className": @"CALayer", + @"fullTitle": @"BorderWidth", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Shadow_Color: @{ + @"className": @"CALayer", + @"fullTitle": @"ShadowColor", + @"setterString": @"setLks_shadowColor:", + @"getterString": @"lks_shadowColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Shadow_Opacity: @{ + @"className": @"CALayer", + @"fullTitle": @"ShadowOpacity", + @"briefTitle": @"Opacity", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Shadow_Radius: @{ + @"className": @"CALayer", + @"fullTitle": @"ShadowRadius", + @"briefTitle": @"Radius", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Shadow_OffsetW: @{ + @"className": @"CALayer", + @"fullTitle": @"ShadowOffsetWidth", + @"briefTitle": @"OffsetW", + @"setterString": @"setLks_shadowOffsetWidth:", + @"getterString": @"lks_shadowOffsetWidth", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Shadow_OffsetH: @{ + @"className": @"CALayer", + @"fullTitle": @"ShadowOffsetHeight", + @"briefTitle": @"OffsetH", + @"setterString": @"setLks_shadowOffsetHeight:", + @"getterString": @"lks_shadowOffsetHeight", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_ContentMode_Mode: @{ + @"className": @"UIView", + @"fullTitle": @"ContentMode", + @"enumList": @"UIViewContentMode", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_TintColor_Color: @{ + @"className": @"UIView", + @"fullTitle": @"TintColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_ViewLayer_TintColor_Mode: @{ + @"className": @"UIView", + @"fullTitle": @"TintAdjustmentMode", + @"enumList": @"UIViewTintAdjustmentMode", + @"patch": @(YES) + }, + LookinAttr_ViewLayer_Tag_Tag: @{ + @"className": @"UIView", + @"fullTitle": @"Tag", + @"briefTitle": @"", + @"patch": @(NO) + }, + + LookinAttr_UIStackView_Axis_Axis: @{ + @"className": @"UIStackView", + @"fullTitle": @"Axis", + @"enumList": @"UILayoutConstraintAxis", + @"patch": @(YES) + }, + + LookinAttr_UIStackView_Distribution_Distribution: @{ + @"className": @"UIStackView", + @"fullTitle": @"Distribution", + @"enumList": @"UIStackViewDistribution", + @"patch": @(YES) + }, + + LookinAttr_UIStackView_Alignment_Alignment: @{ + @"className": @"UIStackView", + @"fullTitle": @"Alignment", + @"enumList": @"UIStackViewAlignment", + @"patch": @(YES) + }, + + LookinAttr_UIStackView_Spacing_Spacing: @{ + @"className": @"UIStackView", + @"fullTitle": @"Spacing", + @"patch": @(YES) + }, + + LookinAttr_UIVisualEffectView_Style_Style: @{ + @"className": @"UIVisualEffectView", + @"setterString": @"setLks_blurEffectStyleNumber:", + @"getterString": @"lks_blurEffectStyleNumber", + @"enumList": @"UIBlurEffectStyle", + @"typeIfObj": @(LookinAttrTypeCustomObj), + @"patch": @(YES), + @"hideIfNil": @(YES) + }, + + LookinAttr_UIVisualEffectView_QMUIForegroundColor_Color: @{ + @"className": @"QMUIVisualEffectView", + @"fullTitle": @"ForegroundColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES), + }, + + LookinAttr_UIImageView_Name_Name: @{ + @"className": @"UIImageView", + @"fullTitle": @"ImageName", + @"setterString": @"", + @"getterString": @"lks_imageSourceName", + @"typeIfObj": @(LookinAttrTypeNSString), + @"hideIfNil": @(YES) + }, + LookinAttr_UIImageView_Open_Open: @{ + @"className": @"UIImageView", + @"setterString": @"", + @"getterString": @"lks_imageViewOidIfHasImage", + @"typeIfObj": @(LookinAttrTypeCustomObj), + @"hideIfNil": @(YES) + }, + + LookinAttr_UILabel_Text_Text: @{ + @"className": @"UILabel", + @"fullTitle": @"Text", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(YES) + }, + LookinAttr_UILabel_NumberOfLines_NumberOfLines: @{ + @"className": @"UILabel", + @"fullTitle": @"NumberOfLines", + @"briefTitle": @"", + @"patch": @(YES) + }, + LookinAttr_UILabel_Font_Size: @{ + @"className": @"UILabel", + @"fullTitle": @"FontSize", + @"briefTitle": @"FontSize", + @"setterString": @"setLks_fontSize:", + @"getterString": @"lks_fontSize", + @"patch": @(YES) + }, + LookinAttr_UILabel_Font_Name: @{ + @"className": @"UILabel", + @"fullTitle": @"FontName", + @"setterString": @"", + @"getterString": @"lks_fontName", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(NO) + }, + LookinAttr_UILabel_TextColor_Color: @{ + @"className": @"UILabel", + @"fullTitle": @"TextColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_UILabel_Alignment_Alignment: @{ + @"className": @"UILabel", + @"fullTitle": @"TextAlignment", + @"enumList": @"NSTextAlignment", + @"patch": @(YES) + }, + LookinAttr_UILabel_BreakMode_Mode: @{ + @"className": @"UILabel", + @"fullTitle": @"LineBreakMode", + @"enumList": @"NSLineBreakMode", + @"patch": @(YES) + }, + LookinAttr_UILabel_CanAdjustFont_CanAdjustFont: @{ + @"className": @"UILabel", + @"fullTitle": @"AdjustsFontSizeToFitWidth", + @"patch": @(YES) + }, + + LookinAttr_UIControl_EnabledSelected_Enabled: @{ + @"className": @"UIControl", + @"fullTitle": @"Enabled", + @"getterString": @"isEnabled", + @"patch": @(NO) + }, + LookinAttr_UIControl_EnabledSelected_Selected: @{ + @"className": @"UIControl", + @"fullTitle": @"Selected", + @"getterString": @"isSelected", + @"patch": @(YES) + }, + LookinAttr_UIControl_VerAlignment_Alignment: @{ + @"className": @"UIControl", + @"fullTitle": @"ContentVerticalAlignment", + @"enumList": @"UIControlContentVerticalAlignment", + @"patch": @(YES) + }, + LookinAttr_UIControl_HorAlignment_Alignment: @{ + @"className": @"UIControl", + @"fullTitle": @"ContentHorizontalAlignment", + @"enumList": @"UIControlContentHorizontalAlignment", + @"patch": @(YES) + }, + LookinAttr_UIControl_QMUIOutsideEdge_Edge: @{ + @"className": @"UIControl", + @"fullTitle": @"qmui_outsideEdge" + }, + + LookinAttr_UIButton_ContentInsets_Insets: @{ + @"className": @"UIButton", + @"fullTitle": @"ContentEdgeInsets", + @"patch": @(YES) + }, + LookinAttr_UIButton_TitleInsets_Insets: @{ + @"className": @"UIButton", + @"fullTitle": @"TitleEdgeInsets", + @"patch": @(YES) + }, + LookinAttr_UIButton_ImageInsets_Insets: @{ + @"className": @"UIButton", + @"fullTitle": @"ImageEdgeInsets", + @"patch": @(YES) + }, + + LookinAttr_UIScrollView_Offset_Offset: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ContentOffset", + @"patch": @(YES) + }, + LookinAttr_UIScrollView_ContentSize_Size: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ContentSize", + @"patch": @(YES) + }, + LookinAttr_UIScrollView_ContentInset_Inset: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ContentInset", + @"patch": @(YES) + }, + LookinAttr_UIScrollView_QMUIInitialInset_Inset: @{ + @"className": @"UIScrollView", + @"fullTitle": @"qmui_initialContentInset", + @"patch": @(YES) + }, + LookinAttr_UIScrollView_AdjustedInset_Inset: @{ + @"className": @"UIScrollView", + @"fullTitle": @"AdjustedContentInset", + @"setterString": @"", + @"osVersion": @(11) + }, + LookinAttr_UIScrollView_Behavior_Behavior: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ContentInsetAdjustmentBehavior", + @"enumList": @"UIScrollViewContentInsetAdjustmentBehavior", + @"patch": @(YES), + @"osVersion": @(11) + }, + LookinAttr_UIScrollView_IndicatorInset_Inset: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ScrollIndicatorInsets", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ScrollPaging_ScrollEnabled: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ScrollEnabled", + @"getterString": @"isScrollEnabled", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ScrollPaging_PagingEnabled: @{ + @"className": @"UIScrollView", + @"fullTitle": @"PagingEnabled", + @"getterString": @"isPagingEnabled", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_Bounce_Ver: @{ + @"className": @"UIScrollView", + @"fullTitle": @"AlwaysBounceVertical", + @"briefTitle": @"Vertical", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_Bounce_Hor: @{ + @"className": @"UIScrollView", + @"fullTitle": @"AlwaysBounceHorizontal", + @"briefTitle": @"Horizontal", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ShowsIndicator_Hor: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ShowsHorizontalScrollIndicator", + @"briefTitle": @"Horizontal", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ShowsIndicator_Ver: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ShowsVerticalScrollIndicator", + @"briefTitle": @"Vertical", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ContentTouches_Delay: @{ + @"className": @"UIScrollView", + @"fullTitle": @"DelaysContentTouches", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_ContentTouches_CanCancel: @{ + @"className": @"UIScrollView", + @"fullTitle": @"CanCancelContentTouches", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_Zoom_MinScale: @{ + @"className": @"UIScrollView", + @"fullTitle": @"MinimumZoomScale", + @"briefTitle": @"MinScale", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_Zoom_MaxScale: @{ + @"className": @"UIScrollView", + @"fullTitle": @"MaximumZoomScale", + @"briefTitle": @"MaxScale", + @"patch": @(NO) + }, + LookinAttr_UIScrollView_Zoom_Scale: @{ + @"className": @"UIScrollView", + @"fullTitle": @"ZoomScale", + @"briefTitle": @"Scale", + @"patch": @(YES) + }, + LookinAttr_UIScrollView_Zoom_Bounce: @{ + @"className": @"UIScrollView", + @"fullTitle": @"BouncesZoom", + @"patch": @(NO) + }, + + LookinAttr_UITableView_Style_Style: @{ + @"className": @"UITableView", + @"fullTitle": @"Style", + @"setterString": @"", + @"enumList": @"UITableViewStyle", + @"patch": @(YES) + }, + LookinAttr_UITableView_SectionsNumber_Number: @{ + @"className": @"UITableView", + @"fullTitle": @"NumberOfSections", + @"setterString": @"", + @"patch": @(YES) + }, + LookinAttr_UITableView_RowsNumber_Number: @{ + @"className": @"UITableView", + @"setterString": @"", + @"getterString": @"lks_numberOfRows", + @"typeIfObj": @(LookinAttrTypeCustomObj) + }, + LookinAttr_UITableView_SeparatorInset_Inset: @{ + @"className": @"UITableView", + @"fullTitle": @"SeparatorInset", + @"patch": @(NO) + }, + LookinAttr_UITableView_SeparatorColor_Color: @{ + @"className": @"UITableView", + @"fullTitle": @"SeparatorColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_UITableView_SeparatorStyle_Style: @{ + @"className": @"UITableView", + @"fullTitle": @"SeparatorStyle", + @"enumList": @"UITableViewCellSeparatorStyle", + @"patch": @(YES) + }, + + LookinAttr_UITextView_Text_Text: @{ + @"className": @"UITextView", + @"fullTitle": @"Text", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(YES) + }, + LookinAttr_UITextView_Font_Name: @{ + @"className": @"UITextView", + @"fullTitle": @"FontName", + @"setterString": @"", + @"getterString": @"lks_fontName", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(NO) + }, + LookinAttr_UITextView_Font_Size: @{ + @"className": @"UITextView", + @"fullTitle": @"FontSize", + @"setterString": @"setLks_fontSize:", + @"getterString": @"lks_fontSize", + @"patch": @(YES) + }, + LookinAttr_UITextView_Basic_Editable: @{ + @"className": @"UITextView", + @"fullTitle": @"Editable", + @"getterString": @"isEditable", + @"patch": @(NO) + }, + LookinAttr_UITextView_Basic_Selectable: @{ + @"className": @"UITextView", + @"fullTitle": @"Selectable", + @"getterString": @"isSelectable", + @"patch": @(NO) + }, + LookinAttr_UITextView_TextColor_Color: @{ + @"className": @"UITextView", + @"fullTitle": @"TextColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_UITextView_Alignment_Alignment: @{ + @"className": @"UITextView", + @"fullTitle": @"TextAlignment", + @"enumList": @"NSTextAlignment", + @"patch": @(YES) + }, + LookinAttr_UITextView_ContainerInset_Inset: @{ + @"className": @"UITextView", + @"fullTitle": @"TextContainerInset", + @"patch": @(YES) + }, + + LookinAttr_UITextField_Font_Name: @{ + @"className": @"UITextField", + @"fullTitle": @"FontName", + @"setterString": @"", + @"getterString": @"lks_fontName", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(NO) + }, + LookinAttr_UITextField_Font_Size: @{ + @"className": @"UITextField", + @"fullTitle": @"FontSize", + @"setterString": @"setLks_fontSize:", + @"getterString": @"lks_fontSize", + @"patch": @(YES) + }, + LookinAttr_UITextField_TextColor_Color: @{ + @"className": @"UITextField", + @"fullTitle": @"TextColor", + @"typeIfObj": @(LookinAttrTypeUIColor), + @"patch": @(YES) + }, + LookinAttr_UITextField_Alignment_Alignment: @{ + @"className": @"UITextField", + @"fullTitle": @"TextAlignment", + @"enumList": @"NSTextAlignment", + @"patch": @(YES) + }, + LookinAttr_UITextField_Text_Text: @{ + @"className": @"UITextField", + @"fullTitle": @"Text", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(YES) + }, + LookinAttr_UITextField_Placeholder_Placeholder: @{ + @"className": @"UITextField", + @"fullTitle": @"Placeholder", + @"typeIfObj": @(LookinAttrTypeNSString), + @"patch": @(YES) + }, + LookinAttr_UITextField_Clears_ClearsOnBeginEditing: @{ + @"className": @"UITextField", + @"fullTitle": @"ClearsOnBeginEditing", + @"patch": @(NO) + }, + LookinAttr_UITextField_Clears_ClearsOnInsertion: @{ + @"className": @"UITextField", + @"fullTitle": @"ClearsOnInsertion", + @"patch": @(NO) + }, + LookinAttr_UITextField_CanAdjustFont_CanAdjustFont: @{ + @"className": @"UITextField", + @"fullTitle": @"AdjustsFontSizeToFitWidth", + @"patch": @(YES) + }, + LookinAttr_UITextField_CanAdjustFont_MinSize: @{ + @"className": @"UITextField", + @"fullTitle": @"MinimumFontSize", + @"patch": @(YES) + }, + LookinAttr_UITextField_ClearButtonMode_Mode: @{ + @"className": @"UITextField", + @"fullTitle": @"ClearButtonMode", + @"enumList": @"UITextFieldViewMode", + @"patch": @(NO) + }, + }; + }); + + NSDictionary *targetInfo = dict[attrID]; + return targetInfo; +} + ++ (LookinAttrType)objectAttrTypeWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSNumber *typeIfObj = attrInfo[@"typeIfObj"]; + return [typeIfObj integerValue]; +} + ++ (NSString *)classNameWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *className = attrInfo[@"className"]; + + NSAssert(className.length > 0, @""); + + return className; +} + ++ (BOOL)isUIViewPropertyWithAttrID:(LookinAttrIdentifier)attrID { + NSString *className = [self classNameWithAttrID:attrID]; + + if ([className isEqualToString:@"CALayer"]) { + return NO; + } + return YES; +} + ++ (NSString *)enumListNameWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *name = attrInfo[@"enumList"]; + return name; +} + ++ (BOOL)needPatchAfterModificationWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSNumber *needPatch = attrInfo[@"patch"]; + return [needPatch boolValue]; +} + ++ (NSString *)fullTitleWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *fullTitle = attrInfo[@"fullTitle"]; + return fullTitle; +} + ++ (NSString *)briefTitleWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *briefTitle = attrInfo[@"briefTitle"]; + if (!briefTitle) { + briefTitle = attrInfo[@"fullTitle"]; + } + return briefTitle; +} + ++ (SEL)getterWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *getterString = attrInfo[@"getterString"]; + if (getterString && getterString.length == 0) { + // 空字符串,比如 image_open_open + return nil; + } + if (!getterString) { + NSString *fullTitle = attrInfo[@"fullTitle"]; + NSAssert(fullTitle.length > 0, @""); + + getterString = [NSString stringWithFormat:@"%@%@", [fullTitle substringToIndex:1].lowercaseString, [fullTitle substringFromIndex:1]].copy; + } + return NSSelectorFromString(getterString); +} + ++ (SEL)setterWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSString *setterString = attrInfo[@"setterString"]; + if ([setterString isEqualToString:@""]) { + // 该属性不可在 Lookin 客户端中被修改 + return nil; + } + if (!setterString) { + NSString *fullTitle = attrInfo[@"fullTitle"]; + NSAssert(fullTitle.length > 0, @""); + + setterString = [NSString stringWithFormat:@"set%@%@:", [fullTitle substringToIndex:1].uppercaseString, [fullTitle substringFromIndex:1]]; + } + return NSSelectorFromString(setterString); +} + ++ (BOOL)hideIfNilWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSNumber *boolValue = attrInfo[@"hideIfNil"]; + return boolValue.boolValue; +} + ++ (NSInteger)minAvailableOSVersionWithAttrID:(LookinAttrIdentifier)attrID { + NSDictionary *attrInfo = [self _infoForAttrID:attrID]; + NSNumber *minVerNum = attrInfo[@"osVersion"]; + NSInteger minVer = [minVerNum integerValue]; + return minVer; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDefines.h b/Pods/LookinServer/Src/Main/Shared/LookinDefines.h new file mode 100644 index 00000000..f00540de --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDefines.h @@ -0,0 +1,172 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinMessageProtocol.h +// Lookin +// +// Created by Li Kai on 2018/8/6. +// https://lookin.work +// + +#import "TargetConditionals.h" +#if TARGET_OS_IPHONE +#import +#elif TARGET_OS_MAC +#import +#endif + +#include + +#pragma mark - Version + +/// current connection protocol version of LookinServer +static const int LOOKIN_SERVER_VERSION = 7; + +/// current release version of LookinServer +static NSString * const LOOKIN_SERVER_READABLE_VERSION = @"1.2.8"; + +/// current connection protocol version of LookinClient +static const int LOOKIN_CLIENT_VERSION = 7; + +/// the minimum connection protocol version supported by current LookinClient +static const int LOOKIN_SUPPORTED_SERVER_MIN = 7; +/// the maximum connection protocol version supported by current LookinClient +static const int LOOKIN_SUPPORTED_SERVER_MAX = 7; + +#pragma mark - Connection + +/// LookinServer 在真机上会依次尝试监听 47175 ~ 47179 这几个端口 +static const int LookinUSBDeviceIPv4PortNumberStart = 47175; +static const int LookinUSBDeviceIPv4PortNumberEnd = 47179; + +/// LookinServer 在模拟器中会依次尝试监听 47164 ~ 47169 这几个端口 +static const int LookinSimulatorIPv4PortNumberStart = 47164; +static const int LookinSimulatorIPv4PortNumberEnd = 47169; + +enum { + /// 确认两端是否可以响应通讯 + LookinRequestTypePing = 200, + /// 请求 App 的截图、设备型号等信息 + LookinRequestTypeApp = 201, + /// 请求 Hierarchy 信息 + LookinRequestTypeHierarchy = 202, + /// 请求 screenshots 和 attrGroups 信息 + LookinRequestTypeHierarchyDetails = 203, + /// 请求修改某个内置的 Attribute 的值 + LookinRequestTypeInbuiltAttrModification = 204, + /// 修改某个 attr 后,请求一系列最新的 Screenshots、属性值等信息 + LookinRequestTypeAttrModificationPatch = 205, + /// 执行某个方法 + LookinRequestTypeInvokeMethod = 206, + /** + @request: @{@"oid":} + @response: LookinObject * + */ + LookinRequestTypeFetchObject = 207, + + LookinRequestTypeFetchImageViewImage = 208, + + LookinRequestTypeModifyRecognizerEnable = 209, + + /// 请求 attribute group list + LookinRequestTypeAllAttrGroups = 210, + + /// 请求 iOS App 里某个 class 的所有 selector 名字列表(包括 superclass) + LookinRequestTypeAllSelectorNames = 213, + + /// 请求修改某个自定义 Attribute 的值 + LookinRequestTypeCustomAttrModification = 214, + + /// 从 LookinServer 1.2.7 & Lookin 1.0.7 开始,该属性被废弃、不再使用 + LookinPush_BringForwardScreenshotTask = 303, + + // 用户在 Lookin 客户端取消了之前 HierarchyDetails 的拉取 + LookinPush_CanceHierarchyDetails = 304, +}; + +static NSString * const LookinParam_ViewLayerTag = @"tag"; + +static NSString * const LookinParam_SelectorName = @"sn"; +static NSString * const LookinParam_MethodType = @"mt"; +static NSString * const LookinParam_SelectorClassName = @"scn"; + +static NSString * const LookinStringFlag_VoidReturn = @"LOOKIN_TAG_RETURN_VALUE_VOID"; + +#pragma mark - Error + +static NSString * const LookinErrorDomain = @"LookinError"; + +enum { + LookinErrCode_Default = -400, + /// Lookin 内部业务逻辑错误 + LookinErrCode_Inner = -401, + /// PeerTalk 内部错误 + LookinErrCode_PeerTalk = -402, + /// 连接不存在或已断开 + LookinErrCode_NoConnect = -403, + /// ping 失败了,原因是 ping 请求超时 + LookinErrCode_PingFailForTimeout = -404, + /// 请求超时未返回 + LookinErrCode_Timeout = -405, + /// 有相同 Type 的新请求被发出,因此旧请求被丢弃 + LookinErrCode_Discard = -406, + /// ping 失败了,原因是 app 主动报告自身正处于后台模式 + LookinErrCode_PingFailForBackgroundState = -407, + + /// 没有找到对应的对象,可能已被释放 + LookinErrCode_ObjectNotFound = -500, + /// 不支持修改当前类型的 LookinCodingValueType + LookinErrCode_ModifyValueTypeInvalid = -501, + LookinErrCode_Exception = -502, + + // LookinServer 版本过高,要升级 client + LookinErrCode_ServerVersionTooHigh = -600, + // LookinServer 版本过低,要升级 server + LookinErrCode_ServerVersionTooLow = -601, + + // 不支持的文件类型 + LookinErrCode_UnsupportedFileType = -700, +}; + +#define LookinErr_ObjNotFound [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_ObjectNotFound userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"Failed to get target object in iOS app", nil), NSLocalizedRecoverySuggestionErrorKey:NSLocalizedString(@"Perhaps the related object was deallocated. You can reload Lookin to get newest data.", nil)}] + +#define LookinErr_NoConnect [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_NoConnect userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"The operation failed due to disconnection with the iOS app.", nil)}] + +#define LookinErr_Inner [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_Inner userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"The operation failed due to an inner error.", nil)}] + +#define LookinErrorMake(errorTitle, errorDetail) [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_Default userInfo:@{NSLocalizedDescriptionKey:errorTitle, NSLocalizedRecoverySuggestionErrorKey:errorDetail}] + +#define LookinErrorText_Timeout NSLocalizedString(@"Perhaps your iOS app is paused with breakpoint in Xcode, blocked by other tasks in main thread, or moved to background state.", nil) + +#pragma mark - Colors + +#if TARGET_OS_IPHONE +#define LookinColor UIColor +#define LookinInsets UIEdgeInsets +#define LookinImage UIImage +#elif TARGET_OS_MAC +#define LookinColor NSColor +#define LookinInsets NSEdgeInsets +#define LookinImage NSImage +#endif + +#define LookinColorRGBAMake(r, g, b, a) [LookinColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] +#define LookinColorMake(r, g, b) [LookinColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1] + +#pragma mark - Preview + +/// SCNNode 所允许的图片的最大的长和宽,单位是 px,这个值是 Scenekit 自身指定的 +/// Max pixel size of a SCNNode object. It is designated by SceneKit. +static const double LookinNodeImageMaxLengthInPx = 16384; + +typedef NS_OPTIONS(NSUInteger, LookinPreviewBitMask) { + LookinPreviewBitMask_None = 0, + + LookinPreviewBitMask_Selectable = 1 << 1, + LookinPreviewBitMask_Unselectable = 1 << 2, + + LookinPreviewBitMask_HasLight = 1 << 3, + LookinPreviewBitMask_NoLight = 1 << 4 +}; + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.h b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.h new file mode 100644 index 00000000..cea72471 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.h @@ -0,0 +1,186 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayItem.h +// qmuidemo +// +// Created by Li Kai on 2018/11/15. +// Copyright © 2018 QMUI Team. All rights reserved. +// + +#import "TargetConditionals.h" +#import "LookinObject.h" +#import "LookinDefines.h" +#import "LookinCustomDisplayItemInfo.h" +#if TARGET_OS_IPHONE +#import +#elif TARGET_OS_MAC +#import +#endif + +@class LookinAttributesGroup, LookinIvarTrace, LookinPreviewItemLayer, LookinEventHandler, LKDisplayItemNode, LookinDisplayItem; + +typedef NS_ENUM(NSUInteger, LookinDisplayItemImageEncodeType) { + LookinDisplayItemImageEncodeTypeNone, // 不进行 encode + LookinDisplayItemImageEncodeTypeNSData, // 转换为 NSData + LookinDisplayItemImageEncodeTypeImage // 使用 NSImage / UIImage 自身的 encode 方法 +}; + +typedef NS_ENUM(NSUInteger, LookinDoNotFetchScreenshotReason) { + // can sync screenshot + LookinFetchScreenshotPermitted, + // layer is too large + LookinDoNotFetchScreenshotForTooLarge, + // refused by user config in LookinServer + LookinDoNotFetchScreenshotForUserConfig +}; + + +typedef NS_ENUM(NSUInteger, LookinDisplayItemProperty) { + // 当初次设置 delegate 对象时,会立即以该值触发一次 displayItem:propertyDidChange: + LookinDisplayItemProperty_None, + LookinDisplayItemProperty_FrameToRoot, + LookinDisplayItemProperty_DisplayingInHierarchy, + LookinDisplayItemProperty_InHiddenHierarchy, + LookinDisplayItemProperty_IsExpandable, + LookinDisplayItemProperty_IsExpanded, + LookinDisplayItemProperty_SoloScreenshot, + LookinDisplayItemProperty_GroupScreenshot, + LookinDisplayItemProperty_IsSelected, + LookinDisplayItemProperty_IsHovered, + LookinDisplayItemProperty_AvoidSyncScreenshot, + LookinDisplayItemProperty_InNoPreviewHierarchy, + LookinDisplayItemProperty_IsInSearch, + LookinDisplayItemProperty_HighlightedSearchString, +}; + +@protocol LookinDisplayItemDelegate + +- (void)displayItem:(LookinDisplayItem *)displayItem propertyDidChange:(LookinDisplayItemProperty)property; + +@end + +@interface LookinDisplayItem : NSObject + +/// 当 customInfo 不为 nil 时,意思是该 DisplayItem 为 UserCustom 配置的。此时,Encode 属性中仅 subitems 和 customAttrGroupList 属性有意义,其它几乎所有属性都无意义 +@property(nonatomic, strong) LookinCustomDisplayItemInfo *customInfo; + +@property(nonatomic, copy) NSArray *subitems; + +@property(nonatomic, assign) BOOL isHidden; + +@property(nonatomic, assign) float alpha; + +@property(nonatomic, assign) CGRect frame; + +@property(nonatomic, assign) CGRect bounds; + +/// 不存在 subitems 时,该属性的值为 nil +@property(nonatomic, strong) LookinImage *soloScreenshot; +/// 无论是否存在 subitems,该属性始终存在 +@property(nonatomic, strong) LookinImage *groupScreenshot; + +@property(nonatomic, strong) LookinObject *viewObject; +@property(nonatomic, strong) LookinObject *layerObject; +@property(nonatomic, strong) LookinObject *hostViewControllerObject; + +/// attrGroups 列表 +@property(nonatomic, copy) NSArray *attributesGroupList; +/// 通过 lookin_customDebugInfos 返回的属性列表 +@property(nonatomic, copy) NSArray *customAttrGroupList; +/// attributesGroupList + customAttrGroupList +- (NSArray *)queryAllAttrGroupList; + +@property(nonatomic, copy) NSArray *eventHandlers; + +// 如果当前 item 代表 UIWindow 且是 keyWindow,则该属性为 YES +@property(nonatomic, assign) BOOL representedAsKeyWindow; + + +/// view 或 layer 的 backgroundColor,利用该属性来提前渲染 node 的背景色,使得用户感觉加载的快一点 +/// 注意有一个缺点是,理论上应该像 screenshot 一样拆成 soloBackgroundColor 和 groupBackgroundColor,这里的 backgroundColor 实际上是 soloBackgroundColor,因此某些场景的显示会有瑕疵 +@property(nonatomic, strong) LookinColor *backgroundColor; + +/// 用户可以在 iOS 项目中添加 Lookin 自定义配置来显式地拒绝传输某些图层的图像,通常是屏蔽一些不重要的 View 以提升刷新速度。如果用户这么配置了,那么这个 shouldCaptureImage 就会被置为 NO +/// 默认为 YES +@property(nonatomic, assign) BOOL shouldCaptureImage; + +/// 用户通过重写 lookin_customDebugInfos 而自定义的该实例的名字 +/// 可能为 nil +@property(nonatomic, copy) NSString *customDisplayTitle; + +/// 为 DanceUI SDK 预留的内部字段,用于文件跳转 +/// 可能为 nil +@property(nonatomic, copy) NSString *danceuiSource; + +#pragma mark - No Encode/Decode + +@property(nonatomic, weak) id previewItemDelegate; +@property(nonatomic, weak) id rowViewDelegate; + +/// 父节点 +@property(nonatomic, weak) LookinDisplayItem *superItem; + +/// 如果存在 viewObject 则返回 viewObject,否则返回 layerObject +- (LookinObject *)displayingObject; + +/// 在 hierarchy 中的层级,比如顶层的 UIWindow.indentLevel 为 0,UIWindow 的 subitem 的 indentLevel 为 1 +- (NSInteger)indentLevel; + +/** + 该项是否被展开 + @note 假如自己没有被折叠,但是 superItem 被折叠了,则自己仍然不会被看到,但是 self.isExpanded 值仍然为 NO + @note 如果 item 没有 subitems(也就是 isExpandable 为 NO),则该值没有意义。换句话说,在获取该值之前,必须先判断一下 isExpandable + */ +@property(nonatomic, assign) BOOL isExpanded; + +/// 如果有 subitems,则该属性返回 YES,否则返回 NO +@property(nonatomic, assign, readonly) BOOL isExpandable; + +/** + 是否能在 hierarchy panel 上被看到,假如有任意一层的父级元素的 isExpanded 为 NO,则 displayingInHierarchy 为 NO。如果所有父级元素的 isExpanded 均为 YES,则 displayingInHierarchy 为 YES + */ +@property(nonatomic, assign, readonly) BOOL displayingInHierarchy; + +/** + 如果自身或任意一个上层元素的 isHidden 为 YES 或 alpha 为 0,则该属性返回 YES + */ +@property(nonatomic, assign, readonly) BOOL inHiddenHierarchy; + +@property(nonatomic, assign) LookinDisplayItemImageEncodeType screenshotEncodeType; + +/// Whether to fetch screenshot and why. Default to LookinFetchScreenshotPermitted. +@property(nonatomic, assign) LookinDoNotFetchScreenshotReason doNotFetchScreenshotReason; + +@property(nonatomic, weak) LookinPreviewItemLayer *previewLayer; + +@property(nonatomic, weak) LKDisplayItemNode *previewNode; + +/// 如果该值为 YES,则该 item 及所有子 item 均不会在 preview 中被显示出来,只能在 hierarchy 中选择。默认为 NO +@property(nonatomic, assign) BOOL noPreview; + +/// 如果自身或某个上级元素的 noPreview 值为 YES,则该方法返回 YES +/// 注意:当 userCustom 为 YES 时,该属性也可能返回 YES +@property(nonatomic, assign, readonly) BOOL inNoPreviewHierarchy; + +/// 当小于 0 时表示未被设置 +@property(nonatomic, assign) NSInteger previewZIndex; + +@property(nonatomic, assign) BOOL preferToBeCollapsed; + +- (void)notifySelectionChangeToDelegates; +- (void)notifyHoverChangeToDelegates; + +/// 根据 subItems 属性将 items 打平为一维数组 ++ (NSArray *)flatItemsFromHierarchicalItems:(NSArray *)items; + +@property(nonatomic, assign) BOOL hasDeterminedExpansion; + +/// 设置当前是否处于搜索状态 +@property(nonatomic, assign) BOOL isInSearch; +/// 因为搜索而应该被高亮的字符串 +@property(nonatomic, copy) NSString *highlightedSearchString; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.m b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.m new file mode 100644 index 00000000..82ef8d97 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItem.m @@ -0,0 +1,450 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayItem.m +// qmuidemo +// +// Created by Li Kai on 2018/11/15. +// Copyright © 2018 QMUI Team. All rights reserved. +// + +#import "LookinDisplayItem.h" +#import "LookinAttributesGroup.h" +#import "LookinAttributesSection.h" +#import "LookinAttribute.h" +#import "LookinEventHandler.h" +#import "LookinIvarTrace.h" +#import "Color+Lookin.h" +#import "NSArray+Lookin.h" +#import "NSObject+Lookin.h" +#import "LookinDashboardBlueprint.h" + +#if TARGET_OS_IPHONE +#import "UIColor+LookinServer.h" +#import "UIImage+LookinServer.h" +#elif TARGET_OS_MAC +#endif + +@interface LookinDisplayItem () + +@property(nonatomic, assign, readwrite) CGRect frameToRoot; +@property(nonatomic, assign, readwrite) BOOL inNoPreviewHierarchy; +@property(nonatomic, assign) NSInteger indentLevel; +@property(nonatomic, assign, readwrite) BOOL isExpandable; +@property(nonatomic, assign, readwrite) BOOL inHiddenHierarchy; +@property(nonatomic, assign, readwrite) BOOL displayingInHierarchy; + +@end + +@implementation LookinDisplayItem + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinDisplayItem *newDisplayItem = [[LookinDisplayItem allocWithZone:zone] init]; + newDisplayItem.subitems = [self.subitems lookin_map:^id(NSUInteger idx, LookinDisplayItem *value) { + return value.copy; + }]; + newDisplayItem.customInfo = self.customInfo.copy; + newDisplayItem.isHidden = self.isHidden; + newDisplayItem.alpha = self.alpha; + newDisplayItem.frame = self.frame; + newDisplayItem.bounds = self.bounds; + newDisplayItem.soloScreenshot = self.soloScreenshot; + newDisplayItem.groupScreenshot = self.groupScreenshot; + newDisplayItem.viewObject = self.viewObject.copy; + newDisplayItem.layerObject = self.layerObject.copy; + newDisplayItem.hostViewControllerObject = self.hostViewControllerObject.copy; + newDisplayItem.attributesGroupList = [self.attributesGroupList lookin_map:^id(NSUInteger idx, LookinAttributesGroup *value) { + return value.copy; + }]; + newDisplayItem.customAttrGroupList = [self.customAttrGroupList lookin_map:^id(NSUInteger idx, LookinAttributesGroup *value) { + return value.copy; + }]; + newDisplayItem.eventHandlers = [self.eventHandlers lookin_map:^id(NSUInteger idx, LookinEventHandler *value) { + return value.copy; + }]; + newDisplayItem.shouldCaptureImage = self.shouldCaptureImage; + newDisplayItem.representedAsKeyWindow = self.representedAsKeyWindow; + newDisplayItem.customDisplayTitle = self.customDisplayTitle; + newDisplayItem.danceuiSource = self.danceuiSource; + [newDisplayItem _updateDisplayingInHierarchyProperty]; + return newDisplayItem; +} +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.customInfo forKey:@"customInfo"]; + [aCoder encodeObject:self.subitems forKey:@"subitems"]; + [aCoder encodeBool:self.isHidden forKey:@"hidden"]; + [aCoder encodeFloat:self.alpha forKey:@"alpha"]; + [aCoder encodeObject:self.viewObject forKey:@"viewObject"]; + [aCoder encodeObject:self.layerObject forKey:@"layerObject"]; + [aCoder encodeObject:self.hostViewControllerObject forKey:@"hostViewControllerObject"]; + [aCoder encodeObject:self.attributesGroupList forKey:@"attributesGroupList"]; + [aCoder encodeObject:self.customAttrGroupList forKey:@"customAttrGroupList"]; + [aCoder encodeBool:self.representedAsKeyWindow forKey:@"representedAsKeyWindow"]; + [aCoder encodeObject:self.eventHandlers forKey:@"eventHandlers"]; + [aCoder encodeBool:self.shouldCaptureImage forKey:@"shouldCaptureImage"]; + if (self.screenshotEncodeType == LookinDisplayItemImageEncodeTypeNSData) { + [aCoder encodeObject:[self.soloScreenshot lookin_encodedObjectWithType:LookinCodingValueTypeImage] forKey:@"soloScreenshot"]; + [aCoder encodeObject:[self.groupScreenshot lookin_encodedObjectWithType:LookinCodingValueTypeImage] forKey:@"groupScreenshot"]; + } else if (self.screenshotEncodeType == LookinDisplayItemImageEncodeTypeImage) { + [aCoder encodeObject:self.soloScreenshot forKey:@"soloScreenshot"]; + [aCoder encodeObject:self.groupScreenshot forKey:@"groupScreenshot"]; + } + [aCoder encodeObject:self.customDisplayTitle forKey:@"customDisplayTitle"]; + [aCoder encodeObject:self.danceuiSource forKey:@"danceuiSource"]; +#if TARGET_OS_IPHONE + [aCoder encodeCGRect:self.frame forKey:@"frame"]; + [aCoder encodeCGRect:self.bounds forKey:@"bounds"]; + [aCoder encodeObject:self.backgroundColor.lks_rgbaComponents forKey:@"backgroundColor"]; + +#elif TARGET_OS_MAC + [aCoder encodeRect:self.frame forKey:@"frame"]; + [aCoder encodeRect:self.bounds forKey:@"bounds"]; + [aCoder encodeObject:self.backgroundColor.lookin_rgbaComponents forKey:@"backgroundColor"]; +#endif +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.customInfo = [aDecoder decodeObjectForKey:@"customInfo"]; + self.subitems = [aDecoder decodeObjectForKey:@"subitems"]; + self.isHidden = [aDecoder decodeBoolForKey:@"hidden"]; + self.alpha = [aDecoder decodeFloatForKey:@"alpha"]; + self.viewObject = [aDecoder decodeObjectForKey:@"viewObject"]; + self.layerObject = [aDecoder decodeObjectForKey:@"layerObject"]; + self.hostViewControllerObject = [aDecoder decodeObjectForKey:@"hostViewControllerObject"]; + self.attributesGroupList = [aDecoder decodeObjectForKey:@"attributesGroupList"]; + self.customAttrGroupList = [aDecoder decodeObjectForKey:@"customAttrGroupList"]; + self.representedAsKeyWindow = [aDecoder decodeBoolForKey:@"representedAsKeyWindow"]; + + id soloScreenshotObj = [aDecoder decodeObjectForKey:@"soloScreenshot"]; + if (soloScreenshotObj) { + if ([soloScreenshotObj isKindOfClass:[NSData class]]) { + self.soloScreenshot = [soloScreenshotObj lookin_decodedObjectWithType:LookinCodingValueTypeImage]; + } else if ([soloScreenshotObj isKindOfClass:[LookinImage class]]) { + self.soloScreenshot = soloScreenshotObj; + } else { + NSAssert(NO, @""); + } + } + + id groupScreenshotObj = [aDecoder decodeObjectForKey:@"groupScreenshot"]; + if (groupScreenshotObj) { + if ([groupScreenshotObj isKindOfClass:[NSData class]]) { + self.groupScreenshot = [groupScreenshotObj lookin_decodedObjectWithType:LookinCodingValueTypeImage]; + } else if ([groupScreenshotObj isKindOfClass:[LookinImage class]]) { + self.groupScreenshot = groupScreenshotObj; + } else { + NSAssert(NO, @""); + } + } + + self.eventHandlers = [aDecoder decodeObjectForKey:@"eventHandlers"]; + /// this property was added in LookinServer 1.1.3 + self.shouldCaptureImage = [aDecoder containsValueForKey:@"shouldCaptureImage"] ? [aDecoder decodeBoolForKey:@"shouldCaptureImage"] : YES; + self.customDisplayTitle = [aDecoder decodeObjectForKey:@"customDisplayTitle"]; + self.danceuiSource = [aDecoder decodeObjectForKey:@"danceuiSource"]; +#if TARGET_OS_IPHONE + self.frame = [aDecoder decodeCGRectForKey:@"frame"]; + self.bounds = [aDecoder decodeCGRectForKey:@"bounds"]; + self.backgroundColor = [UIColor lks_colorFromRGBAComponents:[aDecoder decodeObjectForKey:@"backgroundColor"]]; +#elif TARGET_OS_MAC + self.frame = [aDecoder decodeRectForKey:@"frame"]; + self.bounds = [aDecoder decodeRectForKey:@"bounds"]; + self.backgroundColor = [NSColor lookin_colorFromRGBAComponents:[aDecoder decodeObjectForKey:@"backgroundColor"]]; + +#endif + [self _updateDisplayingInHierarchyProperty]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)init { + if (self = [super init]) { + /// 在手机端,displayItem 被创建时会调用这个方法 + [self _updateDisplayingInHierarchyProperty]; + } + return self; +} + +- (LookinObject *)displayingObject { + return self.viewObject ? : self.layerObject; +} + +- (void)setAttributesGroupList:(NSArray *)attributesGroupList { + _attributesGroupList = attributesGroupList; + + [_attributesGroupList enumerateObjectsUsingBlock:^(LookinAttributesGroup * _Nonnull group, NSUInteger idx, BOOL * _Nonnull stop) { + [group.attrSections enumerateObjectsUsingBlock:^(LookinAttributesSection * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) { + [section.attributes enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) { + attr.targetDisplayItem = self; + }]; + }]; + }]; +} + +- (void)setCustomAttrGroupList:(NSArray *)customAttrGroupList { + _customAttrGroupList = customAttrGroupList; + // 传进来的时候就已经排好序了 + [customAttrGroupList enumerateObjectsUsingBlock:^(LookinAttributesGroup * _Nonnull group, NSUInteger idx, BOOL * _Nonnull stop) { + [group.attrSections enumerateObjectsUsingBlock:^(LookinAttributesSection * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) { + [section.attributes enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) { + attr.targetDisplayItem = self; + }]; + }]; + }]; +} + +- (void)setSubitems:(NSArray *)subitems { + [_subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + obj.superItem = nil; + }]; + + _subitems = subitems; + + self.isExpandable = (subitems.count > 0); + + [subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSAssert(!obj.superItem, @""); + obj.superItem = self; + + [obj _updateInHiddenHierarchyProperty]; + [obj _updateDisplayingInHierarchyProperty]; + }]; +} + +- (void)setIsExpandable:(BOOL)isExpandable { + if (_isExpandable == isExpandable) { + return; + } + _isExpandable = isExpandable; + [self _notifyDelegatesWith:LookinDisplayItemProperty_IsExpandable]; +} + +- (void)setIsExpanded:(BOOL)isExpanded { + if (_isExpanded == isExpanded) { + return; + } + _isExpanded = isExpanded; + [self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [obj _updateDisplayingInHierarchyProperty]; + }]; + [self _notifyDelegatesWith:LookinDisplayItemProperty_IsExpanded]; +} + +- (void)setSoloScreenshot:(LookinImage *)soloScreenshot { + if (_soloScreenshot == soloScreenshot) { + return; + } + _soloScreenshot = soloScreenshot; + [self _notifyDelegatesWith:LookinDisplayItemProperty_SoloScreenshot]; +} + +- (void)notifySelectionChangeToDelegates { + [self _notifyDelegatesWith:LookinDisplayItemProperty_IsSelected]; +} + +- (void)notifyHoverChangeToDelegates { + [self _notifyDelegatesWith:LookinDisplayItemProperty_IsHovered]; +} + +- (void)setDoNotFetchScreenshotReason:(LookinDoNotFetchScreenshotReason)doNotFetchScreenshotReason { + if (_doNotFetchScreenshotReason == doNotFetchScreenshotReason) { + return; + } + _doNotFetchScreenshotReason = doNotFetchScreenshotReason; + [self _notifyDelegatesWith:LookinDisplayItemProperty_AvoidSyncScreenshot]; +} + +- (void)setGroupScreenshot:(LookinImage *)groupScreenshot { + if (_groupScreenshot == groupScreenshot) { + return; + } + _groupScreenshot = groupScreenshot; + [self _notifyDelegatesWith:LookinDisplayItemProperty_GroupScreenshot]; +} + +- (void)setDisplayingInHierarchy:(BOOL)displayingInHierarchy { + if (_displayingInHierarchy == displayingInHierarchy) { + return; + } + _displayingInHierarchy = displayingInHierarchy; + [self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [obj _updateDisplayingInHierarchyProperty]; + }]; + + [self _notifyDelegatesWith:LookinDisplayItemProperty_DisplayingInHierarchy]; +} + +- (void)_updateDisplayingInHierarchyProperty { + if (self.superItem && (!self.superItem.displayingInHierarchy || !self.superItem.isExpanded)) { + self.displayingInHierarchy = NO; + } else { + self.displayingInHierarchy = YES; + } +} + +- (void)setIsHidden:(BOOL)isHidden { + _isHidden = isHidden; + [self _updateInHiddenHierarchyProperty]; +} + +- (void)setAlpha:(float)alpha { + _alpha = alpha; + [self _updateInHiddenHierarchyProperty]; +} + +- (void)setInHiddenHierarchy:(BOOL)inHiddenHierarchy { + if (_inHiddenHierarchy == inHiddenHierarchy) { + return; + } + _inHiddenHierarchy = inHiddenHierarchy; + [self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [obj _updateInHiddenHierarchyProperty]; + }]; + + [self _notifyDelegatesWith:LookinDisplayItemProperty_InHiddenHierarchy]; +} + +- (void)_updateInHiddenHierarchyProperty { + if (self.superItem.inHiddenHierarchy || self.isHidden || self.alpha <= 0) { + self.inHiddenHierarchy = YES; + } else { + self.inHiddenHierarchy = NO; + } +} + ++ (NSArray *)flatItemsFromHierarchicalItems:(NSArray *)items { + NSMutableArray *resultArray = [NSMutableArray array]; + + [items enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (obj.superItem) { + obj.indentLevel = obj.superItem.indentLevel + 1; + } + [resultArray addObject:obj]; + if (obj.subitems.count) { + [resultArray addObjectsFromArray:[self flatItemsFromHierarchicalItems:obj.subitems]]; + } + }]; + + return resultArray; +} + +- (NSString *)description { + if (self.viewObject) { + return self.viewObject.rawClassName; + } else if (self.layerObject) { + return self.layerObject.rawClassName; + } else { + return [super description]; + } +} + +- (void)setPreviewItemDelegate:(id)previewItemDelegate { + _previewItemDelegate = previewItemDelegate; + + if (![previewItemDelegate respondsToSelector:@selector(displayItem:propertyDidChange:)]) { + NSAssert(NO, @""); + _previewItemDelegate = nil; + return; + } + [self.previewItemDelegate displayItem:self propertyDidChange:LookinDisplayItemProperty_None]; +} + +- (void)setRowViewDelegate:(id)rowViewDelegate { + if (_rowViewDelegate == rowViewDelegate) { + return; + } + _rowViewDelegate = rowViewDelegate; + + if (![rowViewDelegate respondsToSelector:@selector(displayItem:propertyDidChange:)]) { + NSAssert(NO, @""); + _rowViewDelegate = nil; + return; + } + [self.rowViewDelegate displayItem:self propertyDidChange:LookinDisplayItemProperty_None]; +} + +- (void)setFrame:(CGRect)frame { + _frame = frame; + [self recursivelyNotifyFrameToRootMayChange]; +} + +- (void)recursivelyNotifyFrameToRootMayChange { + [self _notifyDelegatesWith:LookinDisplayItemProperty_FrameToRoot]; + + [self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [obj recursivelyNotifyFrameToRootMayChange]; + }]; +} + +- (void)setBounds:(CGRect)bounds { + _bounds = bounds; + [self recursivelyNotifyFrameToRootMayChange]; +} + +- (void)setInNoPreviewHierarchy:(BOOL)inNoPreviewHierarchy { + if (_inNoPreviewHierarchy == inNoPreviewHierarchy) { + return; + } + _inNoPreviewHierarchy = inNoPreviewHierarchy; + [self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [obj _updateInNoPreviewHierarchy]; + }]; + [self _notifyDelegatesWith:LookinDisplayItemProperty_InNoPreviewHierarchy]; +} + +- (void)setNoPreview:(BOOL)noPreview { + _noPreview = noPreview; + [self _updateInNoPreviewHierarchy]; +} + +- (void)_updateInNoPreviewHierarchy { + if (self.superItem.inNoPreviewHierarchy || self.noPreview) { + self.inNoPreviewHierarchy = YES; + } else { + self.inNoPreviewHierarchy = NO; + } +} + +- (void)_notifyDelegatesWith:(LookinDisplayItemProperty)property { + [self.previewItemDelegate displayItem:self propertyDidChange:property]; + [self.rowViewDelegate displayItem:self propertyDidChange:property]; +} + +- (void)setIsInSearch:(BOOL)isInSearch { + _isInSearch = isInSearch; + [self _notifyDelegatesWith:LookinDisplayItemProperty_IsInSearch]; +} + +- (void)setHighlightedSearchString:(NSString *)highlightedSearchString { + _highlightedSearchString = highlightedSearchString; + [self _notifyDelegatesWith:LookinDisplayItemProperty_HighlightedSearchString]; +} + +- (NSArray *)queryAllAttrGroupList { + NSMutableArray *array = [NSMutableArray array]; + if (self.attributesGroupList) { + [array addObjectsFromArray:self.attributesGroupList]; + } + if (self.customAttrGroupList) { + [array addObjectsFromArray:self.customAttrGroupList]; + } + return array; +} + +//- (void)dealloc +//{ +// NSLog(@"moss dealloc -%@", self); +//} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.h b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.h new file mode 100644 index 00000000..adb60c38 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.h @@ -0,0 +1,51 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayItemDetail.h +// Lookin +// +// Created by Li Kai on 2019/2/19. +// https://lookin.work +// + +#import "LookinDefines.h" + +@class LookinAttributesGroup; +@class LookinDisplayItem; + +@interface LookinDisplayItemDetail : NSObject + +@property(nonatomic, assign) unsigned long displayItemOid; + +@property(nonatomic, strong) LookinImage *groupScreenshot; + +@property(nonatomic, strong) LookinImage *soloScreenshot; + +@property(nonatomic, strong) NSValue *frameValue; + +@property(nonatomic, strong) NSValue *boundsValue; + +@property(nonatomic, strong) NSNumber *hiddenValue; + +@property(nonatomic, strong) NSNumber *alphaValue; + +@property(nonatomic, copy) NSString *customDisplayTitle; + +@property(nonatomic, copy) NSString *danceUISource; + +@property(nonatomic, copy) NSArray *attributesGroupList; +@property(nonatomic, copy) NSArray *customAttrGroupList; + +/// 注意 nil 和空数组的区别:nil 表示该属性无意义,空数组表示 subviews 为空 +/// Client 1.0.7 & Server 1.2.7 开始支持该属性 +/// 默认为 nil +@property(nonatomic, copy) NSArray *subitems; + +/// 当 Server 找不到 task 对应的图层时,会返回一个特殊的 LookinDisplayItemDetail 对象,这个对象会被设置 displayItemOid 和 failureCode,其中 failureCode 会被置为 -1 +/// Client 1.0.7 & Server 1.2.7 开始支持该属性 +/// 默认为 0 +@property(nonatomic, assign) NSInteger failureCode; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.m b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.m new file mode 100644 index 00000000..195c03c9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinDisplayItemDetail.m @@ -0,0 +1,71 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayItemDetail.m +// Lookin +// +// Created by Li Kai on 2019/2/19. +// https://lookin.work +// + +#import "LookinDisplayItemDetail.h" +#import "Image+Lookin.h" + +#if TARGET_OS_IPHONE +#import "UIImage+LookinServer.h" +#endif + +@implementation LookinDisplayItemDetail + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:@(self.displayItemOid) forKey:@"displayItemOid"]; + [aCoder encodeObject:self.groupScreenshot.lookin_data forKey:@"groupScreenshot"]; + [aCoder encodeObject:self.soloScreenshot.lookin_data forKey:@"soloScreenshot"]; + [aCoder encodeObject:self.frameValue forKey:@"frameValue"]; + [aCoder encodeObject:self.boundsValue forKey:@"boundsValue"]; + [aCoder encodeObject:self.hiddenValue forKey:@"hiddenValue"]; + [aCoder encodeObject:self.alphaValue forKey:@"alphaValue"]; + [aCoder encodeObject:self.attributesGroupList forKey:@"attributesGroupList"]; + [aCoder encodeObject:self.customAttrGroupList forKey:@"customAttrGroupList"]; + [aCoder encodeObject:self.customDisplayTitle forKey:@"customDisplayTitle"]; + [aCoder encodeObject:self.danceUISource forKey:@"danceUISource"]; + [aCoder encodeInteger:self.failureCode forKey:@"failureCode"]; + if (self.subitems) { + [aCoder encodeObject:self.subitems forKey:@"subitems"]; + } +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.displayItemOid = [[aDecoder decodeObjectForKey:@"displayItemOid"] unsignedLongValue]; + self.groupScreenshot = [[LookinImage alloc] initWithData:[aDecoder decodeObjectForKey:@"groupScreenshot"]]; + self.soloScreenshot = [[LookinImage alloc] initWithData:[aDecoder decodeObjectForKey:@"soloScreenshot"]]; + self.frameValue = [aDecoder decodeObjectForKey:@"frameValue"]; + self.boundsValue = [aDecoder decodeObjectForKey:@"boundsValue"]; + self.hiddenValue = [aDecoder decodeObjectForKey:@"hiddenValue"]; + self.alphaValue = [aDecoder decodeObjectForKey:@"alphaValue"]; + self.attributesGroupList = [aDecoder decodeObjectForKey:@"attributesGroupList"]; + self.customAttrGroupList = [aDecoder decodeObjectForKey:@"customAttrGroupList"]; + self.customDisplayTitle = [aDecoder decodeObjectForKey:@"customDisplayTitle"]; + self.danceUISource = [aDecoder decodeObjectForKey:@"danceUISource"]; + + if ([aDecoder containsValueForKey:@"failureCode"]) { + self.failureCode = [aDecoder decodeIntegerForKey:@"failureCode"]; + } else { + self.failureCode = 0; + } + + if ([aDecoder containsValueForKey:@"subitems"]) { + self.subitems = [aDecoder decodeObjectForKey:@"subitems"]; + } + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.h b/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.h new file mode 100644 index 00000000..cf44b76c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.h @@ -0,0 +1,43 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinEventHandler.h +// Lookin +// +// Created by Li Kai on 2019/8/7. +// https://lookin.work +// + + + +#import + +@class LookinObject, LookinIvarTrace, LookinStringTwoTuple; + +typedef NS_ENUM(NSInteger, LookinEventHandlerType) { + LookinEventHandlerTypeTargetAction, + LookinEventHandlerTypeGesture +}; + +@interface LookinEventHandler : NSObject + +@property(nonatomic, assign) LookinEventHandlerType handlerType; + +/// 比如 "UIControlEventTouchUpInside", "UITapGestureRecognizer" +@property(nonatomic, copy) NSString *eventName; +/// tuple.first => @"",tuple.second => @"handleTap" +@property(nonatomic, copy) NSArray *targetActions; + +/// 返回当前 recognizer 是继承自哪一个基本款 recognizer。 +/// 基本款 recognizer 指的是 TapRecognizer, PinchRecognizer 之类的常见 recognizer +/// 如果当前 recognizer 本身就是基本款 recognizer,则该属性为 nil +@property(nonatomic, copy) NSString *inheritedRecognizerName; +@property(nonatomic, assign) BOOL gestureRecognizerIsEnabled; +@property(nonatomic, copy) NSString *gestureRecognizerDelegator; +@property(nonatomic, copy) NSArray *recognizerIvarTraces; +/// recognizer 对象 +@property(nonatomic, assign) unsigned long long recognizerOid; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.m b/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.m new file mode 100644 index 00000000..8a1576cb --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinEventHandler.m @@ -0,0 +1,71 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinEventHandler.m +// Lookin +// +// Created by Li Kai on 2019/8/7. +// https://lookin.work +// + + + +#import "LookinEventHandler.h" +#import "LookinObject.h" +#import "LookinTuple.h" + +#import "NSArray+Lookin.h" + +@implementation LookinEventHandler + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinEventHandler *newHandler = [[LookinEventHandler allocWithZone:zone] init]; + newHandler.handlerType = self.handlerType; + newHandler.eventName = self.eventName; + newHandler.targetActions = [self.targetActions lookin_map:^id(NSUInteger idx, LookinStringTwoTuple *value) { + return value.copy; + }]; + newHandler.gestureRecognizerIsEnabled = self.gestureRecognizerIsEnabled; + newHandler.gestureRecognizerDelegator = self.gestureRecognizerDelegator; + newHandler.inheritedRecognizerName = self.inheritedRecognizerName; + newHandler.recognizerIvarTraces = self.recognizerIvarTraces.copy; + newHandler.recognizerOid = self.recognizerOid; + return newHandler; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInteger:self.handlerType forKey:@"handlerType"]; + [aCoder encodeBool:self.gestureRecognizerIsEnabled forKey:@"gestureRecognizerIsEnabled"]; + [aCoder encodeObject:self.eventName forKey:@"eventName"]; + [aCoder encodeObject:self.gestureRecognizerDelegator forKey:@"gestureRecognizerDelegator"]; + [aCoder encodeObject:self.targetActions forKey:@"targetActions"]; + [aCoder encodeObject:self.inheritedRecognizerName forKey:@"inheritedRecognizerName"]; + [aCoder encodeObject:self.recognizerIvarTraces forKey:@"recognizerIvarTraces"]; + [aCoder encodeObject:@(self.recognizerOid) forKey:@"recognizerOid"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.handlerType = [aDecoder decodeIntegerForKey:@"handlerType"]; + self.gestureRecognizerIsEnabled = [aDecoder decodeBoolForKey:@"gestureRecognizerIsEnabled"]; + self.eventName = [aDecoder decodeObjectForKey:@"eventName"]; + self.gestureRecognizerDelegator = [aDecoder decodeObjectForKey:@"gestureRecognizerDelegator"]; + self.targetActions = [aDecoder decodeObjectForKey:@"targetActions"]; + self.inheritedRecognizerName = [aDecoder decodeObjectForKey:@"inheritedRecognizerName"]; + self.recognizerIvarTraces = [aDecoder decodeObjectForKey:@"recognizerIvarTraces"]; + self.recognizerOid = ((NSNumber *)[aDecoder decodeObjectForKey:@"recognizerOid"]).unsignedLongValue; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.h b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.h new file mode 100644 index 00000000..afa02cd2 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.h @@ -0,0 +1,32 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinHierarchyFile.h +// Lookin +// +// Created by Li Kai on 2019/5/12. +// https://lookin.work +// + + + +#import + +@class LookinHierarchyInfo; + +@interface LookinHierarchyFile : NSObject + +/// 记录创建该文件的 LookinServer 的版本 +@property(nonatomic, assign) int serverVersion; + +@property(nonatomic, strong) LookinHierarchyInfo *hierarchyInfo; + +@property(nonatomic, copy) NSDictionary *soloScreenshots; +@property(nonatomic, copy) NSDictionary *groupScreenshots; + +/// 验证 file 的版本之类的是否和当前 Lookin 客户端匹配,如果没有问题则返回 nil,如果有问题则返回 error ++ (NSError *)verifyHierarchyFile:(LookinHierarchyFile *)file; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.m b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.m new file mode 100644 index 00000000..4b07e4a9 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyFile.m @@ -0,0 +1,64 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinHierarchyFile.m +// Lookin +// +// Created by Li Kai on 2019/5/12. +// https://lookin.work +// + + + +#import "LookinHierarchyFile.h" + +#import "NSArray+Lookin.h" + +@implementation LookinHierarchyFile + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInt:self.serverVersion forKey:@"serverVersion"]; + [aCoder encodeObject:self.hierarchyInfo forKey:@"hierarchyInfo"]; + [aCoder encodeObject:self.soloScreenshots forKey:@"soloScreenshots"]; + [aCoder encodeObject:self.groupScreenshots forKey:@"groupScreenshots"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.serverVersion = [aDecoder decodeIntForKey:@"serverVersion"]; + self.hierarchyInfo = [aDecoder decodeObjectForKey:@"hierarchyInfo"]; + self.soloScreenshots = [aDecoder decodeObjectForKey:@"soloScreenshots"]; + self.groupScreenshots = [aDecoder decodeObjectForKey:@"groupScreenshots"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + ++ (NSError *)verifyHierarchyFile:(LookinHierarchyFile *)hierarchyFile { + if (![hierarchyFile isKindOfClass:[LookinHierarchyFile class]]) { + return LookinErr_Inner; + } + + if (hierarchyFile.serverVersion < LOOKIN_SUPPORTED_SERVER_MIN) { + // 文件版本太旧 + // 如果不存在 serverVersion 这个字段,说明版本是 6 + int fileVersion = hierarchyFile.serverVersion ? : 6; + NSString *detail = [NSString stringWithFormat:NSLocalizedString(@"The document was created by a Lookin app with too old version. Current Lookin app version is %@, but the document version is %@.", nil), @(LOOKIN_CLIENT_VERSION), @(fileVersion)]; + return [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_ServerVersionTooLow userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"Failed to open the document.", nil), NSLocalizedRecoverySuggestionErrorKey:detail}]; + } + + if (hierarchyFile.serverVersion > LOOKIN_SUPPORTED_SERVER_MAX) { + // 文件版本太新 + NSString *detail = [NSString stringWithFormat:NSLocalizedString(@"Current Lookin app is too old to open this document. Current Lookin app version is %@, but the document version is %@.", nil), @(LOOKIN_CLIENT_VERSION), @(hierarchyFile.serverVersion)]; + return [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_ServerVersionTooHigh userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"Failed to open the document.", nil), NSLocalizedRecoverySuggestionErrorKey:detail}]; + } + + return nil; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.h b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.h new file mode 100644 index 00000000..048d2f6b --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.h @@ -0,0 +1,47 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayInfo.h +// WeRead +// +// Created by Li Kai on 2018/10/22. +// Copyright © 2018年 tencent. All rights reserved. +// + + + +#import "LookinDefines.h" +#import "TargetConditionals.h" +#if TARGET_OS_IPHONE +#import +#elif TARGET_OS_MAC +#import +#endif + +@class LookinDisplayItem, LookinAttributesGroup, LookinAppInfo; + +@interface LookinHierarchyInfo : NSObject + +#if TARGET_OS_IPHONE + +/// version 可能为 nil,此时说明 Client 版本号 < 1.0.4 ++ (instancetype)staticInfoWithLookinVersion:(NSString *)version; + ++ (instancetype)exportedInfo; + +#endif + +/// 这里其实就是顶端的那几个 UIWindow +@property(nonatomic, copy) NSArray *displayItems; + +@property(nonatomic, copy) NSDictionary *colorAlias; + +@property(nonatomic, copy) NSArray *collapsedClassList; + +@property(nonatomic, strong) LookinAppInfo *appInfo; + +@property(nonatomic, assign) int serverVersion; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.m b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.m new file mode 100644 index 00000000..10482600 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinHierarchyInfo.m @@ -0,0 +1,106 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinDisplayInfo.m +// WeRead +// +// Created by Li Kai on 2018/10/22. +// Copyright © 2018年 tencent. All rights reserved. +// + +#import +#import "LookinHierarchyInfo.h" +#import "LookinAttributesGroup.h" +#import "LookinDisplayItem.h" +#import "LookinAppInfo.h" +#import "NSArray+Lookin.h" +#import "NSString+Lookin.h" + +#if TARGET_OS_IPHONE +#import "LKS_HierarchyDisplayItemsMaker.h" +#import "LKSConfigManager.h" +#import "LKS_CustomAttrSetterManager.h" +#endif + +@implementation LookinHierarchyInfo + +#if TARGET_OS_IPHONE + ++ (instancetype)staticInfoWithLookinVersion:(NSString *)version { + BOOL readCustomInfo = NO; + // Client 1.0.4 开始支持 customInfo + if (version && [version lookin_numbericOSVersion] >= 10004) { + readCustomInfo = YES; + } + + [[LKS_CustomAttrSetterManager sharedInstance] removeAll]; + + LookinHierarchyInfo *info = [LookinHierarchyInfo new]; + info.serverVersion = LOOKIN_SERVER_VERSION; + info.displayItems = [LKS_HierarchyDisplayItemsMaker itemsWithScreenshots:NO attrList:NO lowImageQuality:NO readCustomInfo:readCustomInfo saveCustomSetter:YES]; + info.appInfo = [LookinAppInfo currentInfoWithScreenshot:NO icon:YES localIdentifiers:nil]; + info.collapsedClassList = [LKSConfigManager collapsedClassList]; + info.colorAlias = [LKSConfigManager colorAlias]; + return info; +} + ++ (instancetype)exportedInfo { + LookinHierarchyInfo *info = [LookinHierarchyInfo new]; + info.serverVersion = LOOKIN_SERVER_VERSION; + info.displayItems = [LKS_HierarchyDisplayItemsMaker itemsWithScreenshots:YES attrList:YES lowImageQuality:YES readCustomInfo:YES saveCustomSetter:NO]; + info.appInfo = [LookinAppInfo currentInfoWithScreenshot:NO icon:YES localIdentifiers:nil]; + info.collapsedClassList = [LKSConfigManager collapsedClassList]; + info.colorAlias = [LKSConfigManager colorAlias]; + return info; +} + +#endif + +#pragma mark - + +static NSString * const LookinHierarchyInfoCodingKey_DisplayItems = @"1"; +static NSString * const LookinHierarchyInfoCodingKey_AppInfo = @"2"; +static NSString * const LookinHierarchyInfoCodingKey_ColorAlias = @"3"; +static NSString * const LookinHierarchyInfoCodingKey_CollapsedClassList = @"4"; + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.displayItems forKey:LookinHierarchyInfoCodingKey_DisplayItems]; + [aCoder encodeObject:self.colorAlias forKey:LookinHierarchyInfoCodingKey_ColorAlias]; + [aCoder encodeObject:self.collapsedClassList forKey:LookinHierarchyInfoCodingKey_CollapsedClassList]; + [aCoder encodeObject:self.appInfo forKey:LookinHierarchyInfoCodingKey_AppInfo]; + [aCoder encodeInt:self.serverVersion forKey:@"serverVersion"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.displayItems = [aDecoder decodeObjectForKey:LookinHierarchyInfoCodingKey_DisplayItems]; + self.colorAlias = [aDecoder decodeObjectForKey:LookinHierarchyInfoCodingKey_ColorAlias]; + self.collapsedClassList = [aDecoder decodeObjectForKey:LookinHierarchyInfoCodingKey_CollapsedClassList]; + self.appInfo = [aDecoder decodeObjectForKey:LookinHierarchyInfoCodingKey_AppInfo]; + self.serverVersion = [aDecoder decodeIntForKey:@"serverVersion"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinHierarchyInfo *newAppInfo = [[LookinHierarchyInfo allocWithZone:zone] init]; + newAppInfo.serverVersion = self.serverVersion; + newAppInfo.appInfo = self.appInfo.copy; + newAppInfo.collapsedClassList = self.collapsedClassList; + newAppInfo.colorAlias = self.colorAlias; + newAppInfo.displayItems = [self.displayItems lookin_map:^id(NSUInteger idx, LookinDisplayItem *oldItem) { + return oldItem.copy; + }]; + + return newAppInfo; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinObject.h b/Pods/LookinServer/Src/Main/Shared/LookinObject.h new file mode 100644 index 00000000..285749d4 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinObject.h @@ -0,0 +1,42 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinObject.h +// Lookin +// +// Created by Li Kai on 2019/4/20. +// https://lookin.work +// + + + +#import + +@class LookinObjectIvar, LookinIvarTrace; + +@interface LookinObject : NSObject + +#if TARGET_OS_IPHONE ++ (instancetype)instanceWithObject:(NSObject *)object; +#endif + +@property(nonatomic, assign) unsigned long oid; + +@property(nonatomic, copy) NSString *memoryAddress; + +/** + 比如有一个 UILabel 对象,则它的 classChainList 为 @[@"UILabel", @"UIView", @"UIResponder", @"NSObject"],而它的 ivarList 长度为 4,idx 从小到大分别是 UILabel 层级的 ivars, UIView 层级的 ivars..... + */ +@property(nonatomic, copy) NSArray *classChainList; + +@property(nonatomic, copy) NSString *specialTrace; + +@property(nonatomic, copy) NSArray *ivarTraces; + +/// 没有 demangle,会包含 Swift Module Name +/// 在 Lookin 的展示中,绝大多数情况下应该使用 lk_demangledSwiftName +- (NSString *)rawClassName; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinObject.m b/Pods/LookinServer/Src/Main/Shared/LookinObject.m new file mode 100644 index 00000000..89d8fedf --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinObject.m @@ -0,0 +1,82 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinObject.m +// Lookin +// +// Created by Li Kai on 2019/4/20. +// https://lookin.work +// + +#import "LookinObject.h" +#import "LookinIvarTrace.h" +#import "NSArray+Lookin.h" +#import "NSString+Lookin.h" + +#if TARGET_OS_IPHONE +#import "NSObject+LookinServer.h" +#endif + +@implementation LookinObject + +#if TARGET_OS_IPHONE ++ (instancetype)instanceWithObject:(NSObject *)object { + LookinObject *lookinObj = [LookinObject new]; + lookinObj.oid = [object lks_registerOid]; + + lookinObj.memoryAddress = [NSString stringWithFormat:@"%p", object]; + lookinObj.classChainList = [object lks_classChainList]; + + lookinObj.specialTrace = object.lks_specialTrace; + lookinObj.ivarTraces = object.lks_ivarTraces; + + return lookinObj; +} +#endif + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinObject *newObject = [[LookinObject allocWithZone:zone] init]; + newObject.oid = self.oid; + newObject.memoryAddress = self.memoryAddress; + newObject.classChainList = self.classChainList; + newObject.specialTrace = self.specialTrace; + newObject.ivarTraces = [self.ivarTraces lookin_map:^id(NSUInteger idx, LookinIvarTrace *value) { + return value.copy; + }]; + return newObject; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:@(self.oid) forKey:@"oid"]; + [aCoder encodeObject:self.memoryAddress forKey:@"memoryAddress"]; + [aCoder encodeObject:self.classChainList forKey:@"classChainList"]; + [aCoder encodeObject:self.specialTrace forKey:@"specialTrace"]; + [aCoder encodeObject:self.ivarTraces forKey:@"ivarTraces"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.oid = [(NSNumber *)[aDecoder decodeObjectForKey:@"oid"] unsignedLongValue]; + self.memoryAddress = [aDecoder decodeObjectForKey:@"memoryAddress"]; + self.classChainList = [aDecoder decodeObjectForKey:@"classChainList"]; + self.specialTrace = [aDecoder decodeObjectForKey:@"specialTrace"]; + self.ivarTraces = [aDecoder decodeObjectForKey:@"ivarTraces"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (NSString *)rawClassName { + return self.classChainList.firstObject; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.h b/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.h new file mode 100644 index 00000000..85e1925c --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.h @@ -0,0 +1,67 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinStaticAsyncUpdateTask.h +// Lookin +// +// Created by Li Kai on 2019/6/21. +// https://lookin.work +// + + + +#import "LookinDefines.h" + +typedef NS_ENUM(NSInteger, LookinStaticAsyncUpdateTaskType) { + LookinStaticAsyncUpdateTaskTypeNoScreenshot, + LookinStaticAsyncUpdateTaskTypeSoloScreenshot, + LookinStaticAsyncUpdateTaskTypeGroupScreenshot +}; + +typedef NS_ENUM(NSInteger, LookinDetailUpdateTaskAttrRequest) { + /// 由 Server 端自己决定:同一批 task 里,server 端会保证同一个 layer 只会构造一次 attr + /// 在 Lookin turbo 模式下,由于同一个 layer 的 task 可能位于不同批的 task 里,因此这会导致冗余的 attr 构造行为、浪费一定时间 + LookinDetailUpdateTaskAttrRequest_Automatic, + /// 需要返回 attr + LookinDetailUpdateTaskAttrRequest_Need, + /// 不需要返回 attr + LookinDetailUpdateTaskAttrRequest_NotNeed +}; + +/// 业务重写了 isEqual +@interface LookinStaticAsyncUpdateTask : NSObject + +@property(nonatomic, assign) unsigned long oid; + +@property(nonatomic, assign) LookinStaticAsyncUpdateTaskType taskType; + +/// 是否需要返回 attr 数据,默认为 Automatic +/// Client 1.0.7 & Server 1.2.7 开始支持这个参数 +@property(nonatomic, assign) LookinDetailUpdateTaskAttrRequest attrRequest; + +/// 如果置为 YES,则 server 侧会返回这些基础信息:frameValue, boundsValue, hiddenValue, alphaValue +/// 默认为 NO +/// Client 1.0.7 & Server 1.2.7 开始支持这个参数 +@property(nonatomic, assign) BOOL needBasisVisualInfo; + +/// 如果置为 YES,则 server 侧会返回 subitems +/// 默认为 NO +/// Client 1.0.7 & Server 1.2.7 开始支持这个参数 +@property(nonatomic, assign) BOOL needSubitems; + +/// Client 1.0.4 开始加入这个参数 +@property(nonatomic, copy) NSString *clientReadableVersion; + +#pragma mark - Non Coding + +@property(nonatomic, assign) CGSize frameSize; + +@end + +@interface LookinStaticAsyncUpdateTasksPackage : NSObject + +@property(nonatomic, copy) NSArray *tasks; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.m b/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.m new file mode 100644 index 00000000..aef73a11 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinStaticAsyncUpdateTask.m @@ -0,0 +1,105 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinStaticAsyncUpdateTask.m +// Lookin +// +// Created by Li Kai on 2019/6/21. +// https://lookin.work +// + + + +#import "LookinStaticAsyncUpdateTask.h" + +@implementation LookinStaticAsyncUpdateTask + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:@(self.oid) forKey:@"oid"]; + [aCoder encodeInteger:self.taskType forKey:@"taskType"]; + [aCoder encodeObject:self.clientReadableVersion forKey:@"clientReadableVersion"]; + [aCoder encodeInteger:self.attrRequest forKey:@"attrRequest"]; + [aCoder encodeBool:self.needBasisVisualInfo forKey:@"needBasisVisualInfo"]; + [aCoder encodeBool:self.needSubitems forKey:@"needSubitems"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.oid = [[aDecoder decodeObjectForKey:@"oid"] unsignedLongValue]; + self.taskType = [aDecoder decodeIntegerForKey:@"taskType"]; + self.clientReadableVersion = [aDecoder decodeObjectForKey:@"clientReadableVersion"]; + if ([aDecoder containsValueForKey:@"attrRequest"]) { + NSInteger value = [aDecoder decodeIntegerForKey:@"attrRequest"]; + if (value >= LookinDetailUpdateTaskAttrRequest_Automatic && value <= LookinDetailUpdateTaskAttrRequest_NotNeed) { + self.attrRequest = value; + } else { + self.attrRequest = LookinDetailUpdateTaskAttrRequest_Automatic; + } + } else { + self.attrRequest = LookinDetailUpdateTaskAttrRequest_Automatic; + } + + if ([aDecoder containsValueForKey:@"needBasisVisualInfo"]) { + self.needBasisVisualInfo = [aDecoder decodeBoolForKey:@"needBasisVisualInfo"]; + } else { + self.needBasisVisualInfo = NO; + } + + if ([aDecoder containsValueForKey:@"needSubitems"]) { + self.needSubitems = [aDecoder decodeBoolForKey:@"needSubitems"]; + } else { + self.needSubitems = NO; + } + + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (NSUInteger)hash { + return self.oid ^ self.taskType ^ self.attrRequest ^ self.needBasisVisualInfo ^ self.needSubitems; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinStaticAsyncUpdateTask class]]) { + return NO; + } + LookinStaticAsyncUpdateTask *targetTask = object; + if (self.oid == targetTask.oid + && self.taskType == targetTask.taskType + && self.attrRequest == targetTask.attrRequest + && self.needBasisVisualInfo == targetTask.needBasisVisualInfo + && self.needSubitems == targetTask.needSubitems) { + return YES; + } + return NO; +} + +@end + +@implementation LookinStaticAsyncUpdateTasksPackage + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.tasks forKey:@"tasks"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.tasks = [aDecoder decodeObjectForKey:@"tasks"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinTuple.h b/Pods/LookinServer/Src/Main/Shared/LookinTuple.h new file mode 100644 index 00000000..296a4b80 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinTuple.h @@ -0,0 +1,31 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinTuples.h +// Lookin +// +// Created by Li Kai on 2019/8/14. +// https://lookin.work +// + + + +#import + +@interface LookinTwoTuple : NSObject + +@property(nonatomic, strong) NSObject *first; +@property(nonatomic, strong) NSObject *second; + +@end + +@interface LookinStringTwoTuple : NSObject + ++ (instancetype)tupleWithFirst:(NSString *)firstString second:(NSString *)secondString; + +@property(nonatomic, copy) NSString *first; +@property(nonatomic, copy) NSString *second; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinTuple.m b/Pods/LookinServer/Src/Main/Shared/LookinTuple.m new file mode 100644 index 00000000..b84a960b --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinTuple.m @@ -0,0 +1,93 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinTuples.m +// Lookin +// +// Created by Li Kai on 2019/8/14. +// https://lookin.work +// + + + +#import "LookinTuple.h" + +@implementation LookinTwoTuple + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.first forKey:@"first"]; + [aCoder encodeObject:self.second forKey:@"second"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.first = [aDecoder decodeObjectForKey:@"first"]; + self.second = [aDecoder decodeObjectForKey:@"second"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (NSUInteger)hash { + return self.first.hash ^ self.second.hash; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinTwoTuple class]]) { + return NO; + } + LookinTwoTuple *comparedObj = object; + if ([self.first isEqual:comparedObj.first] && [self.second isEqual:comparedObj.second]) { + return YES; + } + return NO; +} + +@end + +@implementation LookinStringTwoTuple + ++ (instancetype)tupleWithFirst:(NSString *)firstString second:(NSString *)secondString { + LookinStringTwoTuple *tuple = [LookinStringTwoTuple new]; + tuple.first = firstString; + tuple.second = secondString; + return tuple; +} + +#pragma mark - + +- (id)copyWithZone:(NSZone *)zone { + LookinStringTwoTuple *newTuple = [[LookinStringTwoTuple allocWithZone:zone] init]; + newTuple.first = self.first; + newTuple.second = self.second; + return newTuple; +} + +#pragma mark - + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.first forKey:@"first"]; + [aCoder encodeObject:self.second forKey:@"second"]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.first = [aDecoder decodeObjectForKey:@"first"]; + self.second = [aDecoder decodeObjectForKey:@"second"]; + } + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.h b/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.h new file mode 100644 index 00000000..af7b2ffe --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.h @@ -0,0 +1,23 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinWeakContainer.h +// Lookin +// +// Created by Li Kai on 2019/8/14. +// https://lookin.work +// + + + +#import + +@interface LookinWeakContainer : NSObject + ++ (instancetype)containerWithObject:(id)object; + +@property (nonatomic, weak) id object; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.m b/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.m new file mode 100644 index 00000000..ff9d2aa1 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/LookinWeakContainer.m @@ -0,0 +1,43 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// LookinWeakContainer.m +// Lookin +// +// Created by Li Kai on 2019/8/14. +// https://lookin.work +// + + + +#import "LookinWeakContainer.h" + +@implementation LookinWeakContainer + ++ (instancetype)containerWithObject:(id)object { + LookinWeakContainer *container = [LookinWeakContainer new]; + container.object = object; + return container; +} + +- (NSUInteger)hash { + return [self.object hash]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[LookinWeakContainer class]]) { + return NO; + } + LookinWeakContainer *comparedObj = object; + if ([self.object isEqual:comparedObj.object]) { + return YES; + } + return NO; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.h b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.h new file mode 100644 index 00000000..498a604e --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.h @@ -0,0 +1,136 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + + + +// +// Represents a communication channel between two endpoints talking the same +// Lookin_PTProtocol. +// +#import +#import +#import +#import + +#import "Lookin_PTProtocol.h" +#import "Lookin_PTUSBHub.h" + +@class Lookin_PTData, Lookin_PTAddress; +@protocol Lookin_PTChannelDelegate; + +@interface Lookin_PTChannel : NSObject + +// Delegate +@property (strong) id delegate; + +// Communication protocol. Must not be nil. +@property Lookin_PTProtocol *protocol; + +// YES if this channel is a listening server +@property (readonly) BOOL isListening; + +// YES if this channel is a connected peer +@property (readonly) BOOL isConnected; + +// Arbitrary attachment. Note that if you set this, the object will grow by +// 8 bytes (64 bits). +@property (strong) id userInfo; + +@property(nonatomic, assign) int uniqueID; +@property(nonatomic, assign) NSInteger targetPort; +- (NSString *)debugTag; + +// Create a new channel using the shared Lookin_PTProtocol for the current dispatch +// queue, with *delegate*. ++ (Lookin_PTChannel*)channelWithDelegate:(id)delegate; + + +// Initialize a new frame channel, configuring it to use the calling queue's +// protocol instance (as returned by [Lookin_PTProtocol sharedProtocolForQueue: +// dispatch_get_current_queue()]) +- (id)init; + +// Initialize a new frame channel with a specific protocol. +- (id)initWithProtocol:(Lookin_PTProtocol*)protocol; + +// Initialize a new frame channel with a specific protocol and delegate. +- (id)initWithProtocol:(Lookin_PTProtocol*)protocol delegate:(id)delegate; + + +// Connect to a TCP port on a device connected over USB +- (void)connectToPort:(int)port overUSBHub:(Lookin_PTUSBHub*)usbHub deviceID:(NSNumber*)deviceID callback:(void(^)(NSError *error))callback; + +// Connect to a TCP port at IPv4 address. Provided port must NOT be in network +// byte order. Provided in_addr_t must NOT be in network byte order. A value returned +// from inet_aton() will be in network byte order. You can use a value of inet_aton() +// as the address parameter here, but you must flip the byte order before passing the +// in_addr_t to this function. +- (void)connectToPort:(in_port_t)port IPv4Address:(in_addr_t)address callback:(void(^)(NSError *error, Lookin_PTAddress *address))callback; + +// Listen for connections on port and address, effectively starting a socket +// server. Provided port must NOT be in network byte order. Provided in_addr_t +// must NOT be in network byte order. +// For this to make sense, you should provide a onAccept block handler +// or a delegate implementing ioFrameChannel:didAcceptConnection:. +- (void)listenOnPort:(in_port_t)port IPv4Address:(in_addr_t)address callback:(void(^)(NSError *error))callback; + +// Send a frame with an optional payload and optional callback. +// If *callback* is not NULL, the block is invoked when either an error occured +// or when the frame (and payload, if any) has been completely sent. +- (void)sendFrameOfType:(uint32_t)frameType tag:(uint32_t)tag withPayload:(dispatch_data_t)payload callback:(void(^)(NSError *error))callback; + +// Lower-level method to assign a connected dispatch IO channel to this channel +- (BOOL)startReadingFromConnectedChannel:(dispatch_io_t)channel error:(__autoreleasing NSError**)error; + +// Close the channel, preventing further reading and writing. Any ongoing and +// queued reads and writes will be aborted. +- (void)close; + +// "graceful" close -- any ongoing and queued reads and writes will complete +// before the channel ends. +- (void)cancel; + +@end + + +// Wraps a mapped dispatch_data_t object. The memory pointed to by *data* is +// valid until *dispatchData* is deallocated (normally when the receiver is +// deallocated). +@interface Lookin_PTData : NSObject +@property (readonly) dispatch_data_t dispatchData; +@property (readonly) void *data; +@property (readonly) size_t length; +@end + + +// Represents a peer's address +@interface Lookin_PTAddress : NSObject +// For network addresses, this is the IP address in textual format +@property (readonly) NSString *name; +// For network addresses, this is the port number. Otherwise 0 (zero). +@property (readonly) NSInteger port; +@end + + +// Protocol for Lookin_PTChannel delegates +@protocol Lookin_PTChannelDelegate + +@required +// Invoked when a new frame has arrived on a channel. +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(Lookin_PTData*)payload; + +@optional +// Invoked to accept an incoming frame on a channel. Reply NO ignore the +// incoming frame. If not implemented by the delegate, all frames are accepted. +- (BOOL)ioFrameChannel:(Lookin_PTChannel*)channel shouldAcceptFrameOfType:(uint32_t)type tag:(uint32_t)tag payloadSize:(uint32_t)payloadSize; + +// Invoked when the channel closed. If it closed because of an error, *error* is +// a non-nil NSError object. +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didEndWithError:(NSError*)error; + +// For listening channels, this method is invoked when a new connection has been +// accepted. +- (void)ioFrameChannel:(Lookin_PTChannel*)channel didAcceptConnection:(Lookin_PTChannel*)otherChannel fromAddress:(Lookin_PTAddress*)address; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.m b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.m new file mode 100644 index 00000000..bb8529ed --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTChannel.m @@ -0,0 +1,675 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +#import "Lookin_PTChannel.h" +#import "Lookin_PTPrivate.h" +#include +#include +#include +#include +#include +#import + +// Read member of sockaddr_in without knowing the family +#define PT_SOCKADDR_ACCESS(ss, member4, member6) \ + (((ss)->ss_family == AF_INET) ? ( \ + ((const struct sockaddr_in *)(ss))->member4 \ + ) : ( \ + ((const struct sockaddr_in6 *)(ss))->member6 \ + )) + +// Connection state (storage: uint8_t) +#define kConnStateNone 0 +#define kConnStateConnecting 1 +#define kConnStateConnected 2 +#define kConnStateListening 3 + +// Delegate support optimization (storage: uint8_t) +#define kDelegateFlagImplements_ioFrameChannel_shouldAcceptFrameOfType_tag_payloadSize 1 +#define kDelegateFlagImplements_ioFrameChannel_didEndWithError 2 +#define kDelegateFlagImplements_ioFrameChannel_didAcceptConnection_fromAddress 4 + + +static int ChannelInstanceCount = 0; +static int ChannelUniqueID = 0; + +#pragma mark - +// Note: We are careful about the size of this struct as each connected peer +// implies one allocation of this struct. +@interface Lookin_PTChannel () { + dispatch_io_t dispatchObj_channel_; + dispatch_source_t dispatchObj_source_; + NSError *endError_; // 64 bit +@public // here be hacks + id delegate_; // 64 bit + uint8_t delegateFlags_; // 8 bit +@private + uint8_t connState_; // 8 bit + //char padding_[6]; // 48 bit -- only if allocation speed is important +} +- (id)initWithProtocol:(Lookin_PTProtocol*)protocol delegate:(id)delegate; +- (BOOL)acceptIncomingConnection:(dispatch_fd_t)serverSocketFD; +@end +static const uint8_t kUserInfoKey; + +#pragma mark - +@interface Lookin_PTData () +- (id)initWithMappedDispatchData:(dispatch_data_t)mappedContiguousData data:(void*)data length:(size_t)length; +@end + +#pragma mark - +@interface Lookin_PTAddress () { + struct sockaddr_storage sockaddr_; +} +- (id)initWithSockaddr:(const struct sockaddr_storage*)addr; +@end + +#pragma mark - +@implementation Lookin_PTChannel + +@synthesize protocol = protocol_; + + ++ (Lookin_PTChannel*)channelWithDelegate:(id)delegate { + return [[Lookin_PTChannel alloc] initWithProtocol:[Lookin_PTProtocol sharedProtocolForQueue:dispatch_get_main_queue()] delegate:delegate]; +} + + +- (id)initWithProtocol:(Lookin_PTProtocol*)protocol delegate:(id)delegate { + if (!(self = [super init])) return nil; + protocol_ = protocol; + self.delegate = delegate; + + [self didInit]; + + return self; +} + + +- (id)initWithProtocol:(Lookin_PTProtocol*)protocol { + if (!(self = [super init])) return nil; + protocol_ = protocol; + + [self didInit]; + + return self; +} + + +- (id)init { + [self didInit]; + + return [self initWithProtocol:[Lookin_PTProtocol sharedProtocolForQueue:dispatch_get_main_queue()]]; +} + +- (void)didInit { + ChannelUniqueID++; + ChannelInstanceCount++; + self.uniqueID = ChannelUniqueID; +// NSLog(@"LookinServer - Init channel(ID: %@). Total count: %@", @(self.uniqueID), @(ChannelInstanceCount)); +} + +- (void)dealloc { + ChannelInstanceCount--; +// NSLog(@"LookinServer - Dealloc channel%@. Still lives count: %@", self.debugTag, @(ChannelInstanceCount)); +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchObj_channel_) dispatch_release(dispatchObj_channel_); + else if (dispatchObj_source_) dispatch_release(dispatchObj_source_); +#endif +} + + +- (BOOL)isConnected { + return connState_ == kConnStateConnecting || connState_ == kConnStateConnected; +} + + +- (BOOL)isListening { + return connState_ == kConnStateListening; +} + + +- (id)userInfo { + return objc_getAssociatedObject(self, (void*)&kUserInfoKey); +} + +- (void)setUserInfo:(id)userInfo { + objc_setAssociatedObject(self, (const void*)&kUserInfoKey, userInfo, OBJC_ASSOCIATION_RETAIN); +} + + +- (void)setConnState:(char)connState { + connState_ = connState; +} + + +- (void)setDispatchChannel:(dispatch_io_t)channel { + assert(connState_ == kConnStateConnecting || connState_ == kConnStateConnected || connState_ == kConnStateNone); + dispatch_io_t prevChannel = dispatchObj_channel_; + if (prevChannel != channel) { + dispatchObj_channel_ = channel; +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchObj_channel_) dispatch_retain(dispatchObj_channel_); + if (prevChannel) dispatch_release(prevChannel); +#endif + if (!dispatchObj_channel_ && !dispatchObj_source_) { + connState_ = kConnStateNone; + } + } +} + + +- (void)setDispatchSource:(dispatch_source_t)source { + assert(connState_ == kConnStateListening || connState_ == kConnStateNone); + dispatch_source_t prevSource = dispatchObj_source_; + if (prevSource != source) { + dispatchObj_source_ = source; +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchObj_source_) dispatch_retain(dispatchObj_source_); + if (prevSource) dispatch_release(prevSource); +#endif + if (!dispatchObj_channel_ && !dispatchObj_source_) { + connState_ = kConnStateNone; + } + } +} + + +- (id)delegate { + return delegate_; +} + + +- (void)setDelegate:(id)delegate { + delegate_ = delegate; + delegateFlags_ = 0; + if (!delegate_) { + return; + } + + if ([delegate respondsToSelector:@selector(ioFrameChannel:shouldAcceptFrameOfType:tag:payloadSize:)]) { + delegateFlags_ |= kDelegateFlagImplements_ioFrameChannel_shouldAcceptFrameOfType_tag_payloadSize; + } + + if (delegate_ && [delegate respondsToSelector:@selector(ioFrameChannel:didEndWithError:)]) { + delegateFlags_ |= kDelegateFlagImplements_ioFrameChannel_didEndWithError; + } + + if (delegate_ && [delegate respondsToSelector:@selector(ioFrameChannel:didAcceptConnection:fromAddress:)]) { + delegateFlags_ |= kDelegateFlagImplements_ioFrameChannel_didAcceptConnection_fromAddress; + } +} + +- (NSString *)debugTag { + NSString *state = @""; + if (connState_ == kConnStateNone) { + state = @"None"; + } else if (connState_ == kConnStateConnecting) { + state = @"Connecting"; + } else if (connState_ == kConnStateConnected) { + state = @"Connected"; + } else if (connState_ == kConnStateListening) { + state = @"Listening"; + } else { + state = @"Undefined"; + } + return [NSString stringWithFormat:@"[%@-%@,%@]", @(self.uniqueID), @(self.targetPort), state]; +} + + +//- (void)setFileDescriptor:(dispatch_fd_t)fd { +// [self setDispatchChannel:dispatch_io_create(DISPATCH_IO_STREAM, fd, protocol_.queue, ^(int error) { +// close(fd); +// })]; +//} + + +#pragma mark - Connecting + + +- (void)connectToPort:(int)port overUSBHub:(Lookin_PTUSBHub*)usbHub deviceID:(NSNumber*)deviceID callback:(void(^)(NSError *error))callback { + assert(protocol_ != NULL); + if (connState_ != kConnStateNone) { + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:EPERM userInfo:nil]); + return; + } + connState_ = kConnStateConnecting; + [usbHub connectToDevice:deviceID port:port onStart:^(NSError *err, dispatch_io_t dispatchChannel) { + NSError *error = err; + if (!error) { + [self startReadingFromConnectedChannel:dispatchChannel error:&error]; + } else { + self->connState_ = kConnStateNone; + } + if (callback) callback(error); + } onEnd:^(NSError *error) { + if (self->delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_didEndWithError) { + [self->delegate_ ioFrameChannel:self didEndWithError:error]; + } + self->endError_ = nil; + }]; +} + + +- (void)connectToPort:(in_port_t)port IPv4Address:(in_addr_t)address callback:(void(^)(NSError *error, Lookin_PTAddress *address))callback { + assert(protocol_ != NULL); + if (connState_ != kConnStateNone) { + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:EPERM userInfo:nil], nil); + return; + } + connState_ = kConnStateConnecting; + + int error = 0; + + // Create socket + dispatch_fd_t fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + perror("socket(AF_INET, SOCK_STREAM, 0) failed"); + error = errno; + if (callback) callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil], nil); + return; + } + + // Connect socket + struct sockaddr_in addr; + bzero((char *)&addr, sizeof(addr)); + + addr.sin_len = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + //addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + //addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_addr.s_addr = htonl(address); + + // prevent SIGPIPE + int on = 1; + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); + + // int socket, const struct sockaddr *address, socklen_t address_len + if (connect(fd, (const struct sockaddr *)&addr, addr.sin_len) == -1) { + //perror("connect"); + error = errno; + close(fd); + if (callback) callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], nil); + return; + } + + // get actual address + //if (getsockname(fd, (struct sockaddr*)&addr, (socklen_t*)&addr.sin_len) == -1) { + // error = errno; + // close(fd); + // if (callback) callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], nil); + // return; + //} + + dispatch_io_t dispatchChannel = dispatch_io_create(DISPATCH_IO_STREAM, fd, protocol_.queue, ^(int error) { + close(fd); + if (self->delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_didEndWithError) { + NSError *err = error == 0 ? self->endError_ : [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil]; + [self->delegate_ ioFrameChannel:self didEndWithError:err]; + self->endError_ = nil; + } + }); + + if (!dispatchChannel) { + close(fd); + if (callback) callback([[NSError alloc] initWithDomain:@"PTError" code:0 userInfo:nil], nil); + return; + } + + // Success + NSError *err = nil; + Lookin_PTAddress *ptAddr = [[Lookin_PTAddress alloc] initWithSockaddr:(struct sockaddr_storage*)&addr]; + [self startReadingFromConnectedChannel:dispatchChannel error:&err]; + if (callback) callback(err, ptAddr); +} + + +#pragma mark - Listening and serving + + +- (void)listenOnPort:(in_port_t)port IPv4Address:(in_addr_t)address callback:(void(^)(NSError *error))callback { + assert(dispatchObj_source_ == nil); + + // Create socket + dispatch_fd_t fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]); + return; + } + + // Connect socket + struct sockaddr_in addr; + bzero((char *)&addr, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + //addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + //addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_addr.s_addr = htonl(address); + + socklen_t socklen = sizeof(addr); + + int on = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { + close(fd); + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]); + return; + } + + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { + close(fd); + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]); + return; + } + + if (bind(fd, (struct sockaddr*)&addr, socklen) != 0) { + close(fd); + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]); + return; + } + + if (listen(fd, 512) != 0) { + close(fd); + if (callback) callback([NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]); + return; + } + + [self setDispatchSource:dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, protocol_.queue)]; + + dispatch_source_set_event_handler(dispatchObj_source_, ^{ + unsigned long nconns = dispatch_source_get_data(self->dispatchObj_source_); + while ([self acceptIncomingConnection:fd] && --nconns); + }); + + dispatch_source_set_cancel_handler(dispatchObj_source_, ^{ + // Captures *self*, effectively holding a reference to *self* until cancelled. + self->dispatchObj_source_ = nil; + close(fd); + if (self->delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_didEndWithError) { + [self->delegate_ ioFrameChannel:self didEndWithError:self->endError_]; + self->endError_ = nil; + } + }); + + dispatch_resume(dispatchObj_source_); + //NSLog(@"%@ opened on fd #%d", self, fd); + + connState_ = kConnStateListening; + if (callback) callback(nil); +} + + +- (BOOL)acceptIncomingConnection:(dispatch_fd_t)serverSocketFD { + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + dispatch_fd_t clientSocketFD = accept(serverSocketFD, (struct sockaddr*)&addr, &addrLen); + + if (clientSocketFD == -1) { + perror("accept()"); + return NO; + } + + // prevent SIGPIPE + int on = 1; + setsockopt(clientSocketFD, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); + + if (fcntl(clientSocketFD, F_SETFL, O_NONBLOCK) == -1) { + perror("fcntl(.. O_NONBLOCK)"); + close(clientSocketFD); + return NO; + } + + if (delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_didAcceptConnection_fromAddress) { + Lookin_PTChannel *peerChannel = [[Lookin_PTChannel alloc] initWithProtocol:protocol_ delegate:delegate_]; + __block Lookin_PTChannel *localChannelRef = self; + dispatch_io_t dispatchChannel = dispatch_io_create(DISPATCH_IO_STREAM, clientSocketFD, protocol_.queue, ^(int error) { + // Important note: This block captures *self*, thus a reference is held to + // *self* until the fd is truly closed. + localChannelRef = nil; + + close(clientSocketFD); + + if (peerChannel->delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_didEndWithError) { + NSError *err = error == 0 ? peerChannel->endError_ : [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil]; + [peerChannel->delegate_ ioFrameChannel:peerChannel didEndWithError:err]; + peerChannel->endError_ = nil; + } + }); + + [peerChannel setConnState:kConnStateConnected]; + [peerChannel setDispatchChannel:dispatchChannel]; + + assert(((struct sockaddr_storage*)&addr)->ss_len == addrLen); + Lookin_PTAddress *address = [[Lookin_PTAddress alloc] initWithSockaddr:(struct sockaddr_storage*)&addr]; + [delegate_ ioFrameChannel:self didAcceptConnection:peerChannel fromAddress:address]; + + NSError *err = nil; + if (![peerChannel startReadingFromConnectedChannel:dispatchChannel error:&err]) { +// NSLog(@"startReadingFromConnectedChannel failed in accept: %@", err); + } + } else { + close(clientSocketFD); + } + return YES; +} + + +#pragma mark - Closing the channel + + +- (void)close { +// NSLog(@"LookinServer - Will close chanel: %@", self.debugTag); + + if ((connState_ == kConnStateConnecting || connState_ == kConnStateConnected) && dispatchObj_channel_) { + dispatch_io_close(dispatchObj_channel_, DISPATCH_IO_STOP); + [self setDispatchChannel:NULL]; + } else if (connState_ == kConnStateListening && dispatchObj_source_) { + dispatch_source_cancel(dispatchObj_source_); + } +} + +/// 曾经连接上 Client,然后 Client 端关闭时,Peertalk 内部会对之前 connect 的 channel 调用该方法 +- (void)cancel { +// NSLog(@"LookinServer - Will cancel chanel: %@", self.debugTag); + + if ((connState_ == kConnStateConnecting || connState_ == kConnStateConnected) && dispatchObj_channel_) { + dispatch_io_close(dispatchObj_channel_, 0); + [self setDispatchChannel:NULL]; + } else if (connState_ == kConnStateListening && dispatchObj_source_) { + dispatch_source_cancel(dispatchObj_source_); + } +} + + +#pragma mark - Reading + + +- (BOOL)startReadingFromConnectedChannel:(dispatch_io_t)channel error:(__autoreleasing NSError**)error { + if (connState_ != kConnStateNone && connState_ != kConnStateConnecting && connState_ != kConnStateConnected) { + if (error) *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:EPERM userInfo:nil]; + return NO; + } + + if (dispatchObj_channel_ != channel) { + [self close]; + [self setDispatchChannel:channel]; + } + + connState_ = kConnStateConnected; + + // helper + BOOL(^handleError)(NSError*,BOOL) = ^BOOL(NSError *error, BOOL isEOS) { + if (error) { + //NSLog(@"Error while communicating: %@", error); + self->endError_ = error; + [self close]; + return YES; + } else if (isEOS) { + [self cancel]; + return YES; + } + return NO; + }; + + [protocol_ readFramesOverChannel:channel onFrame:^(NSError *error, uint32_t type, uint32_t tag, uint32_t payloadSize, dispatch_block_t resumeReadingFrames) { + if (handleError(error, type == PTFrameTypeEndOfStream)) { + return; + } + + BOOL accepted = (channel == self->dispatchObj_channel_); + if (accepted && (self->delegateFlags_ & kDelegateFlagImplements_ioFrameChannel_shouldAcceptFrameOfType_tag_payloadSize)) { + accepted = [self->delegate_ ioFrameChannel:self shouldAcceptFrameOfType:type tag:tag payloadSize:payloadSize]; + } + + if (payloadSize == 0) { + if (accepted && self->delegate_) { + [self->delegate_ ioFrameChannel:self didReceiveFrameOfType:type tag:tag payload:nil]; + } else { + // simply ignore the frame + } + resumeReadingFrames(); + } else { + // has payload + if (!accepted) { + // Read and discard payload, ignoring frame + [self->protocol_ readAndDiscardDataOfSize:payloadSize overChannel:channel callback:^(NSError *error, BOOL endOfStream) { + if (!handleError(error, endOfStream)) { + resumeReadingFrames(); + } + }]; + } else { + [self->protocol_ readPayloadOfSize:payloadSize overChannel:channel callback:^(NSError *error, dispatch_data_t contiguousData, const uint8_t *buffer, size_t bufferSize) { + if (handleError(error, bufferSize == 0)) { + return; + } + + if (self->delegate_) { + Lookin_PTData *payload = [[Lookin_PTData alloc] initWithMappedDispatchData:contiguousData data:(void*)buffer length:bufferSize]; + [self->delegate_ ioFrameChannel:self didReceiveFrameOfType:type tag:tag payload:payload]; + } + + resumeReadingFrames(); + }]; + } + } + }]; + + return YES; +} + + +#pragma mark - Sending + +- (void)sendFrameOfType:(uint32_t)frameType tag:(uint32_t)tag withPayload:(dispatch_data_t)payload callback:(void(^)(NSError *error))callback { + if (connState_ == kConnStateConnecting || connState_ == kConnStateConnected) { + [protocol_ sendFrameOfType:frameType tag:tag withPayload:payload overChannel:dispatchObj_channel_ callback:callback]; + } else if (callback) { + callback([NSError errorWithDomain:NSPOSIXErrorDomain code:EPERM userInfo:nil]); + } +} + +#pragma mark - NSObject + +- (NSString*)description { + id userInfo = objc_getAssociatedObject(self, (void*)&kUserInfoKey); + return [NSString stringWithFormat:@"", self, ( connState_ == kConnStateConnecting ? @"connecting" + : connState_ == kConnStateConnected ? @"connected" + : connState_ == kConnStateListening ? @"listening" + : @"closed"), + userInfo ? " " : "", userInfo ? userInfo : @""]; +} + + +@end + + +#pragma mark - +@implementation Lookin_PTAddress + +- (id)initWithSockaddr:(const struct sockaddr_storage*)addr { + if (!(self = [super init])) return nil; + assert(addr); + memcpy((void*)&sockaddr_, (const void*)addr, addr->ss_len); + return self; +} + + +- (NSString*)name { + if (sockaddr_.ss_len) { + const void *sin_addr = NULL; + size_t bufsize = 0; + if (sockaddr_.ss_family == AF_INET6) { + bufsize = INET6_ADDRSTRLEN; + sin_addr = (const void *)&((const struct sockaddr_in6*)&sockaddr_)->sin6_addr; + } else { + bufsize = INET_ADDRSTRLEN; + sin_addr = (const void *)&((const struct sockaddr_in*)&sockaddr_)->sin_addr; + } + char *buf = CFAllocatorAllocate(kCFAllocatorDefault, bufsize+1, 0); + if (inet_ntop(sockaddr_.ss_family, sin_addr, buf, (unsigned int)bufsize-1) == NULL) { + CFAllocatorDeallocate(kCFAllocatorDefault, buf); + return nil; + } + return [[NSString alloc] initWithBytesNoCopy:(void*)buf length:strlen(buf) encoding:NSUTF8StringEncoding freeWhenDone:YES]; + } else { + return nil; + } +} + + +- (NSInteger)port { + if (sockaddr_.ss_len) { + return ntohs(PT_SOCKADDR_ACCESS(&sockaddr_, sin_port, sin6_port)); + } else { + return 0; + } +} + + +- (NSString*)description { + if (sockaddr_.ss_len) { + return [NSString stringWithFormat:@"%@:%u", self.name, (unsigned)self.port]; + } else { + return @"(?)"; + } +} + +@end + + +#pragma mark - +@implementation Lookin_PTData + +@synthesize dispatchData = dispatchData_; +@synthesize data = data_; +@synthesize length = length_; + +- (id)initWithMappedDispatchData:(dispatch_data_t)mappedContiguousData data:(void*)data length:(size_t)length { + if (!(self = [super init])) return nil; + dispatchData_ = mappedContiguousData; +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchData_) dispatch_retain(dispatchData_); +#endif + data_ = data; + length_ = length; + return self; +} + +- (void)dealloc { +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchData_) dispatch_release(dispatchData_); +#endif + data_ = NULL; + length_ = 0; +} + +#pragma mark - NSObject + +- (NSString*)description { + return [NSString stringWithFormat:@"", self, length_]; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTPrivate.h b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTPrivate.h new file mode 100644 index 00000000..6480de85 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTPrivate.h @@ -0,0 +1,20 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + + + +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && (!defined(__IPHONE_6_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0)) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && (!defined(__MAC_10_8) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8)) +#define PT_DISPATCH_RETAIN_RELEASE 1 +#else +#define PT_DISPATCH_RETAIN_RELEASE 0 +#endif + +#if PT_DISPATCH_RETAIN_RELEASE +#define PT_PRECISE_LIFETIME +#define PT_PRECISE_LIFETIME_UNUSED +#else +#define PT_PRECISE_LIFETIME __attribute__((objc_precise_lifetime)) +#define PT_PRECISE_LIFETIME_UNUSED __attribute__((objc_precise_lifetime, unused)) +#endif + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.h b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.h new file mode 100644 index 00000000..b0207d37 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.h @@ -0,0 +1,122 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + + + +// +// A universal frame-based communication protocol which can be used to exchange +// arbitrary structured data. +// +// In short: +// +// - Each transmission is comprised by one fixed-size frame. +// - Each frame contains a protocol version number. +// - Each frame contains an application frame type. +// - Each frame can contain an identifying tag. +// - Each frame can have application-specific data of up to UINT32_MAX size. +// - Transactions style messaging can be modeled on top using frame tags. +// - Lightweight API on top of libdispatch (aka GCD) -- close to the metal. +// +#include +#import + +// Special frame tag that signifies "no tag". Your implementation should never +// create a reply for a frame with this tag. +static const uint32_t PTFrameNoTag = 0; + +// Special frame type that signifies that the stream has ended. +static const uint32_t PTFrameTypeEndOfStream = 0; + +// NSError domain +FOUNDATION_EXPORT NSString * const Lookin_PTProtocolErrorDomain; + + +@interface Lookin_PTProtocol : NSObject + +// Queue on which to run data processing blocks. +@property dispatch_queue_t queue; + +// Get the shared protocol object for *queue* ++ (Lookin_PTProtocol*)sharedProtocolForQueue:(dispatch_queue_t)queue; + +// Initialize a new protocol object to use a specific queue. +- (id)initWithDispatchQueue:(dispatch_queue_t)queue; + +// Initialize a new protocol object to use the current calling queue. +- (id)init; + +#pragma mark Sending frames + +// Generate a new tag that is unique within this protocol object. +- (uint32_t)newTag; + +// Send a frame over *channel* with an optional payload and optional callback. +// If *callback* is not NULL, the block is invoked when either an error occured +// or when the frame (and payload, if any) has been completely sent. +- (void)sendFrameOfType:(uint32_t)frameType + tag:(uint32_t)tag + withPayload:(dispatch_data_t)payload + overChannel:(dispatch_io_t)channel + callback:(void(^)(NSError *error))callback; + +#pragma mark Receiving frames + +// Read frames over *channel* as they arrive. +// The onFrame handler is responsible for reading (or discarding) any payload +// and call *resumeReadingFrames* afterwards to resume reading frames. +// To stop reading frames, simply do not invoke *resumeReadingFrames*. +// When the stream ends, a frame of type PTFrameTypeEndOfStream is received. +- (void)readFramesOverChannel:(dispatch_io_t)channel + onFrame:(void(^)(NSError *error, + uint32_t type, + uint32_t tag, + uint32_t payloadSize, + dispatch_block_t resumeReadingFrames))onFrame; + +// Read a single frame over *channel*. A frame of type PTFrameTypeEndOfStream +// denotes the stream has ended. +- (void)readFrameOverChannel:(dispatch_io_t)channel + callback:(void(^)(NSError *error, + uint32_t frameType, + uint32_t frameTag, + uint32_t payloadSize))callback; + +#pragma mark Receiving frame payloads + +// Read a complete payload. It's the callers responsibility to make sure +// payloadSize is not too large since memory will be automatically allocated +// where only payloadSize is the limit. +// The returned dispatch_data_t object owns *buffer* and thus you need to call +// dispatch_retain on *contiguousData* if you plan to keep *buffer* around after +// returning from the callback. +- (void)readPayloadOfSize:(size_t)payloadSize + overChannel:(dispatch_io_t)channel + callback:(void(^)(NSError *error, + dispatch_data_t contiguousData, + const uint8_t *buffer, + size_t bufferSize))callback; + +// Discard data of *size* waiting on *channel*. *callback* can be NULL. +- (void)readAndDiscardDataOfSize:(size_t)size + overChannel:(dispatch_io_t)channel + callback:(void(^)(NSError *error, BOOL endOfStream))callback; + +@end + +@interface NSData (Lookin_PTProtocol) +// Creates a new dispatch_data_t object which references the receiver and uses +// the receivers bytes as its backing data. The returned dispatch_data_t object +// holds a reference to the recevier. It's the callers responsibility to call +// dispatch_release on the returned object when done. +- (dispatch_data_t)createReferencingDispatchData; ++ (NSData *)dataWithContentsOfDispatchData:(dispatch_data_t)data; +@end + +@interface NSDictionary (Lookin_PTProtocol) +// See description of -[NSData(Lookin_PTProtocol) createReferencingDispatchData] +- (dispatch_data_t)createReferencingDispatchData; + +// Decode *data* as a peroperty list-encoded dictionary. Returns nil on failure. ++ (NSDictionary*)dictionaryWithContentsOfDispatchData:(dispatch_data_t)data; +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.m b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.m new file mode 100644 index 00000000..72e85f8a --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTProtocol.m @@ -0,0 +1,428 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +#import "Lookin_PTProtocol.h" +#import "Lookin_PTPrivate.h" +#import + +static const uint32_t PTProtocolVersion1 = 1; + +NSString * const Lookin_PTProtocolErrorDomain = @"PTProtocolError"; + +// This is what we send as the header for each frame. +typedef struct _PTFrame { + // The version of the frame and protocol. + uint32_t version; + + // Type of frame + uint32_t type; + + // Unless zero, a tag is retained in frames that are responses to previous + // frames. Applications can use this to build transactions or request-response + // logic. + uint32_t tag; + + // If payloadSize is larger than zero, *payloadSize* number of bytes are + // following, constituting application-specific data. + uint32_t payloadSize; + +} PTFrame; + + +@interface Lookin_PTProtocol () { + uint32_t nextFrameTag_; + @public + dispatch_queue_t queue_; +} +- (dispatch_data_t)createDispatchDataWithFrameOfType:(uint32_t)type frameTag:(uint32_t)frameTag payload:(dispatch_data_t)payload; +@end + + +static void _release_queue_local_protocol(void *objcobj) { + if (objcobj) { + Lookin_PTProtocol *protocol = (__bridge_transfer id)objcobj; + protocol->queue_ = NULL; + } +} + + +@interface Lookin_RQueueLocalIOFrameProtocol : Lookin_PTProtocol +@end +@implementation Lookin_RQueueLocalIOFrameProtocol +- (void)setQueue:(dispatch_queue_t)queue { +} +@end + + +@implementation Lookin_PTProtocol + + ++ (Lookin_PTProtocol*)sharedProtocolForQueue:(dispatch_queue_t)queue { + static const char currentQueueFrameProtocolKey; + //dispatch_queue_t queue = dispatch_get_current_queue(); + Lookin_PTProtocol *currentQueueFrameProtocol = (__bridge Lookin_PTProtocol*)dispatch_queue_get_specific(queue, ¤tQueueFrameProtocolKey); + if (!currentQueueFrameProtocol) { + currentQueueFrameProtocol = [[Lookin_RQueueLocalIOFrameProtocol alloc] initWithDispatchQueue:NULL]; + currentQueueFrameProtocol->queue_ = queue; // reference, no retain, since we would create cyclic references + dispatch_queue_set_specific(queue, ¤tQueueFrameProtocolKey, (__bridge_retained void*)currentQueueFrameProtocol, &_release_queue_local_protocol); + return (__bridge Lookin_PTProtocol*)dispatch_queue_get_specific(queue, ¤tQueueFrameProtocolKey); // to avoid race conds + } else { + return currentQueueFrameProtocol; + } +} + + +- (id)initWithDispatchQueue:(dispatch_queue_t)queue { + if (!(self = [super init])) return nil; + queue_ = queue; +#if PT_DISPATCH_RETAIN_RELEASE + if (queue_) dispatch_retain(queue_); +#endif + return self; +} + +- (id)init { + return [self initWithDispatchQueue:dispatch_get_main_queue()]; +} + +- (void)dealloc { + if (queue_) { +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(queue_); +#endif + } +} + +- (dispatch_queue_t)queue { + return queue_; +} + +- (void)setQueue:(dispatch_queue_t)queue { +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_queue_t prev_queue = queue_; + queue_ = queue; + if (queue_) dispatch_retain(queue_); + if (prev_queue) dispatch_release(prev_queue); +#else + queue_ = queue; +#endif +} + + +- (uint32_t)newTag { + return ++nextFrameTag_; +} + + +#pragma mark - +#pragma mark Creating frames + + +- (dispatch_data_t)createDispatchDataWithFrameOfType:(uint32_t)type frameTag:(uint32_t)frameTag payload:(dispatch_data_t)payload { + PTFrame *frame = CFAllocatorAllocate(kCFAllocatorDefault, sizeof(PTFrame), 0); + frame->version = htonl(PTProtocolVersion1); + frame->type = htonl(type); + frame->tag = htonl(frameTag); + + if (payload) { + size_t payloadSize = dispatch_data_get_size(payload); + assert(payloadSize <= UINT32_MAX); + frame->payloadSize = htonl((uint32_t)payloadSize); + } else { + frame->payloadSize = 0; + } + + dispatch_data_t frameData = dispatch_data_create((const void*)frame, sizeof(PTFrame), queue_, ^{ + CFAllocatorDeallocate(kCFAllocatorDefault, (void*)frame); + }); + + if (payload && frame->payloadSize != 0) { + // chain frame + payload + dispatch_data_t data = dispatch_data_create_concat(frameData, payload); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(frameData); +#endif + frameData = data; + } + + return frameData; +} + + +#pragma mark - +#pragma mark Sending frames + + +- (void)sendFrameOfType:(uint32_t)frameType tag:(uint32_t)tag withPayload:(dispatch_data_t)payload overChannel:(dispatch_io_t)channel callback:(void(^)(NSError*))callback { + dispatch_data_t frame = [self createDispatchDataWithFrameOfType:frameType frameTag:tag payload:payload]; + dispatch_io_write(channel, 0, frame, queue_, ^(bool done, dispatch_data_t data, int _errno) { + if (done && callback) { + callback(_errno == 0 ? nil : [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:_errno userInfo:nil]); + } + }); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(frame); +#endif +} + + +#pragma mark - +#pragma mark Receiving frames + + +- (void)readFrameOverChannel:(dispatch_io_t)channel callback:(void(^)(NSError *error, uint32_t frameType, uint32_t frameTag, uint32_t payloadSize))callback { + __block dispatch_data_t allData = NULL; + + dispatch_io_read(channel, 0, sizeof(PTFrame), queue_, ^(bool done, dispatch_data_t data, int error) { + //NSLog(@"dispatch_io_read: done=%d data=%p error=%d", done, data, error); + size_t dataSize = data ? dispatch_data_get_size(data) : 0; + + if (dataSize) { + if (!allData) { + allData = data; +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_retain(allData); +#endif + } else { +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_data_t allDataPrev = allData; + allData = dispatch_data_create_concat(allData, data); + dispatch_release(allDataPrev); +#else + allData = dispatch_data_create_concat(allData, data); +#endif + } + } + + if (done) { + if (error != 0) { + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], 0, 0, 0); + return; + } + + if (dataSize == 0) { + callback(nil, PTFrameTypeEndOfStream, 0, 0); + return; + } + + if (!allData || dispatch_data_get_size(allData) < sizeof(PTFrame)) { +#if PT_DISPATCH_RETAIN_RELEASE + if (allData) dispatch_release(allData); +#endif + callback([[NSError alloc] initWithDomain:Lookin_PTProtocolErrorDomain code:0 userInfo:nil], 0, 0, 0); + return; + } + + PTFrame *frame = NULL; + size_t size = 0; + + PT_PRECISE_LIFETIME dispatch_data_t contiguousData = dispatch_data_create_map(allData, (const void **)&frame, &size); // precise lifetime guarantees bytes in frame will stay valid till the end of scope +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(allData); +#endif + if (!contiguousData) { + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:ENOMEM userInfo:nil], 0, 0, 0); + return; + } + + frame->version = ntohl(frame->version); + if (frame->version != PTProtocolVersion1) { + callback([[NSError alloc] initWithDomain:Lookin_PTProtocolErrorDomain code:0 userInfo:nil], 0, 0, 0); + } else { + frame->type = ntohl(frame->type); + frame->tag = ntohl(frame->tag); + frame->payloadSize = ntohl(frame->payloadSize); + callback(nil, frame->type, frame->tag, frame->payloadSize); + } + +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(contiguousData); +#endif + } + }); +} + + +- (void)readPayloadOfSize:(size_t)payloadSize overChannel:(dispatch_io_t)channel callback:(void(^)(NSError *error, dispatch_data_t contiguousData, const uint8_t *buffer, size_t bufferSize))callback { + __block dispatch_data_t allData = NULL; + dispatch_io_read(channel, 0, payloadSize, queue_, ^(bool done, dispatch_data_t data, int error) { + //NSLog(@"dispatch_io_read: done=%d data=%p error=%d", done, data, error); + size_t dataSize = dispatch_data_get_size(data); + + if (dataSize) { + if (!allData) { + allData = data; +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_retain(allData); +#endif + } else { +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_data_t allDataPrev = allData; + allData = dispatch_data_create_concat(allData, data); + dispatch_release(allDataPrev); +#else + allData = dispatch_data_create_concat(allData, data); +#endif + } + } + + if (done) { + if (error != 0) { +#if PT_DISPATCH_RETAIN_RELEASE + if (allData) dispatch_release(allData); +#endif + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], NULL, NULL, 0); + return; + } + + if (dataSize == 0) { +#if PT_DISPATCH_RETAIN_RELEASE + if (allData) dispatch_release(allData); +#endif + callback(nil, NULL, NULL, 0); + return; + } + + uint8_t *buffer = NULL; + size_t bufferSize = 0; + PT_PRECISE_LIFETIME dispatch_data_t contiguousData = NULL; + + if (allData) { + contiguousData = dispatch_data_create_map(allData, (const void **)&buffer, &bufferSize); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(allData); allData = NULL; +#endif + if (!contiguousData) { + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:ENOMEM userInfo:nil], NULL, NULL, 0); + return; + } + } + + callback(nil, contiguousData, buffer, bufferSize); +#if PT_DISPATCH_RETAIN_RELEASE + if (contiguousData) dispatch_release(contiguousData); +#endif + } + }); +} + + +- (void)readAndDiscardDataOfSize:(size_t)size overChannel:(dispatch_io_t)channel callback:(void(^)(NSError*, BOOL))callback { + dispatch_io_read(channel, 0, size, queue_, ^(bool done, dispatch_data_t data, int error) { + if (done && callback) { + size_t dataSize = data ? dispatch_data_get_size(data) : 0; + callback(error == 0 ? nil : [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], dataSize == 0); + } + }); +} + + +- (void)readFramesOverChannel:(dispatch_io_t)channel onFrame:(void(^)(NSError*, uint32_t, uint32_t, uint32_t, dispatch_block_t))onFrame { + [self readFrameOverChannel:channel callback:^(NSError *error, uint32_t type, uint32_t tag, uint32_t payloadSize) { + onFrame(error, type, tag, payloadSize, ^{ + if (type != PTFrameTypeEndOfStream) { + [self readFramesOverChannel:channel onFrame:onFrame]; + } + }); + }]; +} + + +@end + + +@interface Lookin_PTDispatchData : NSObject { + dispatch_data_t dispatchData_; +} +@end +@implementation Lookin_PTDispatchData +- (id)initWithDispatchData:(dispatch_data_t)dispatchData { + if (!(self = [super init])) return nil; + dispatchData_ = dispatchData; +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_retain(dispatchData_); +#endif + return self; +} +- (void)dealloc { +#if PT_DISPATCH_RETAIN_RELEASE + if (dispatchData_) dispatch_release(dispatchData_); +#endif +} +@end + +@implementation NSData (Lookin_PTProtocol) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-getter-return-value" + +- (dispatch_data_t)createReferencingDispatchData { + // Note: The queue is used to submit the destructor. Since we only perform an + // atomic release of self, it doesn't really matter which queue is used, thus + // we use the current calling queue. + return dispatch_data_create((const void*)self.bytes, self.length, dispatch_get_main_queue(), ^{ + // trick to have the block capture the data, thus retain/releasing + [self length]; + }); +} + +#pragma clang diagnostic pop + ++ (NSData *)dataWithContentsOfDispatchData:(dispatch_data_t)data { + if (!data) { + return nil; + } + uint8_t *buffer = NULL; + size_t bufferSize = 0; + PT_PRECISE_LIFETIME dispatch_data_t contiguousData = dispatch_data_create_map(data, (const void **)&buffer, &bufferSize); + if (!contiguousData) { + return nil; + } + + Lookin_PTDispatchData *dispatchDataRef = [[Lookin_PTDispatchData alloc] initWithDispatchData:contiguousData]; + NSData *newData = [NSData dataWithBytesNoCopy:(void*)buffer length:bufferSize freeWhenDone:NO]; +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(contiguousData); +#endif + static const bool kDispatchDataRefKey; + objc_setAssociatedObject(newData, (const void*)kDispatchDataRefKey, dispatchDataRef, OBJC_ASSOCIATION_RETAIN); + + return newData; +} + +@end + + +@implementation NSDictionary (Lookin_PTProtocol) + +- (dispatch_data_t)createReferencingDispatchData { + NSError *error = nil; + NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:self format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; + if (!plistData) { + NSLog(@"Failed to serialize property list: %@", error); + return nil; + } else { + return [plistData createReferencingDispatchData]; + } +} + +// Decode *data* as a peroperty list-encoded dictionary. Returns nil on failure. ++ (NSDictionary*)dictionaryWithContentsOfDispatchData:(dispatch_data_t)data { + if (!data) { + return nil; + } + uint8_t *buffer = NULL; + size_t bufferSize = 0; + PT_PRECISE_LIFETIME dispatch_data_t contiguousData = dispatch_data_create_map(data, (const void **)&buffer, &bufferSize); + if (!contiguousData) { + return nil; + } + NSDictionary *dict = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytesNoCopy:(void*)buffer length:bufferSize freeWhenDone:NO] options:NSPropertyListImmutable format:NULL error:nil]; +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(contiguousData); +#endif + return dict; +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.h b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.h new file mode 100644 index 00000000..30c97a7e --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.h @@ -0,0 +1,88 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + + + +#include +#import + +// Lookin_PTUSBDeviceDidAttachNotification +// Posted when a device has been attached. Also posted for each device that is +// already attached when the Lookin_PTUSBHub starts listening. +// +// .userInfo = { +// DeviceID = 3; +// MessageType = Attached; +// Properties = { +// ConnectionSpeed = 480000000; +// ConnectionType = USB; +// DeviceID = 3; +// LocationID = 1234567890; +// ProductID = 1234; +// SerialNumber = 0123456789abcdef0123456789abcdef01234567; +// }; +// } +// +FOUNDATION_EXPORT NSString * const Lookin_PTUSBDeviceDidAttachNotification; + +// Lookin_PTUSBDeviceDidDetachNotification +// Posted when a device has been detached. +// +// .userInfo = { +// DeviceID = 3; +// MessageType = Detached; +// } +// +FOUNDATION_EXPORT NSString * const Lookin_PTUSBDeviceDidDetachNotification; + +// NSError domain +FOUNDATION_EXPORT NSString * const Lookin_PTUSBHubErrorDomain; + +// Error codes returned with NSError.code for NSError domain Lookin_PTUSBHubErrorDomain +typedef enum { + PTUSBHubErrorBadDevice = 2, + PTUSBHubErrorConnectionRefused = 3, +} PTUSBHubError; + +@interface Lookin_PTUSBHub : NSObject + +// Shared, implicitly opened hub. ++ (Lookin_PTUSBHub*)sharedHub; + +// Connect to a TCP *port* on a device, while the actual transport is over USB. +// Upon success, *error* is nil and *channel* is a duplex I/O channel. +// You can retrieve the underlying file descriptor using +// dispatch_io_get_descriptor(channel). The dispatch_io_t channel behaves just +// like any stream type dispatch_io_t, making it possible to use the same logic +// for both USB bridged connections and e.g. ethernet-based connections. +// +// *onStart* is called either when a connection failed, in which case the error +// argument is non-nil, or when the connection was successfully established (the +// error argument is nil). Must not be NULL. +// +// *onEnd* is called when a connection was open and just did close. If the error +// argument is non-nil, the channel closed because of an error. Pass NULL for no +// callback. +// +- (void)connectToDevice:(NSNumber*)deviceID + port:(int)port + onStart:(void(^)(NSError *error, dispatch_io_t channel))onStart + onEnd:(void(^)(NSError *error))onEnd; + +// Start listening for devices. You only need to invoke this method on custom +// instances to start receiving notifications. The shared instance returned from +// +sharedHub is always in listening mode. +// +// *onStart* is called either when the system failed to start listening, in +// which case the error argument is non-nil, or when the receiver is listening. +// Pass NULL for no callback. +// +// *onEnd* is called when listening stopped. If the error argument is non-nil, +// listening stopped because of an error. Pass NULL for no callback. +// +- (void)listenOnQueue:(dispatch_queue_t)queue + onStart:(void(^)(NSError*))onStart + onEnd:(void(^)(NSError*))onEnd; + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.m b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.m new file mode 100644 index 00000000..cde0dd76 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Lookin_PTUSBHub.m @@ -0,0 +1,674 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +#import "Lookin_PTUSBHub.h" + + + +#import "Lookin_PTPrivate.h" + +#include +#include +#include +#include +#include + +NSString * const Lookin_PTUSBHubErrorDomain = @"PTUSBHubError"; + +typedef uint32_t USBMuxPacketType; +enum { + USBMuxPacketTypeResult = 1, + USBMuxPacketTypeConnect = 2, + USBMuxPacketTypeListen = 3, + USBMuxPacketTypeDeviceAdd = 4, + USBMuxPacketTypeDeviceRemove = 5, + // ? = 6, + // ? = 7, + USBMuxPacketTypePlistPayload = 8, +}; + +typedef uint32_t USBMuxPacketProtocol; +enum { + USBMuxPacketProtocolBinary = 0, + USBMuxPacketProtocolPlist = 1, +}; + +typedef uint32_t USBMuxReplyCode; +enum { + USBMuxReplyCodeOK = 0, + USBMuxReplyCodeBadCommand = 1, + USBMuxReplyCodeBadDevice = 2, + USBMuxReplyCodeConnectionRefused = 3, + // ? = 4, + // ? = 5, + USBMuxReplyCodeBadVersion = 6, +}; + + +typedef struct usbmux_packet { + uint32_t size; + USBMuxPacketProtocol protocol; + USBMuxPacketType type; + uint32_t tag; + char data[0]; +} __attribute__((__packed__)) usbmux_packet_t; + +static const uint32_t kUsbmuxPacketMaxPayloadSize = UINT32_MAX - (uint32_t)sizeof(usbmux_packet_t); + + +static uint32_t usbmux_packet_payload_size(usbmux_packet_t *upacket) { + return upacket->size - sizeof(usbmux_packet_t); +} + + +static void *usbmux_packet_payload(usbmux_packet_t *upacket) { + return (void*)upacket->data; +} + + +static void usbmux_packet_set_payload(usbmux_packet_t *upacket, + const void *payload, + uint32_t payloadLength) +{ + memcpy(usbmux_packet_payload(upacket), payload, payloadLength); +} + + +static usbmux_packet_t *usbmux_packet_alloc(uint32_t payloadSize) { + assert(payloadSize <= kUsbmuxPacketMaxPayloadSize); + uint32_t upacketSize = sizeof(usbmux_packet_t) + payloadSize; + usbmux_packet_t *upacket = CFAllocatorAllocate(kCFAllocatorDefault, upacketSize, 0); + memset(upacket, 0, sizeof(usbmux_packet_t)); + upacket->size = upacketSize; + return upacket; +} + + +static usbmux_packet_t *usbmux_packet_create(USBMuxPacketProtocol protocol, + USBMuxPacketType type, + uint32_t tag, + const void *payload, + uint32_t payloadSize) +{ + usbmux_packet_t *upacket = usbmux_packet_alloc(payloadSize); + if (!upacket) { + return NULL; + } + + upacket->protocol = protocol; + upacket->type = type; + upacket->tag = tag; + + if (payload && payloadSize) { + usbmux_packet_set_payload(upacket, payload, (uint32_t)payloadSize); + } + + return upacket; +} + + +static void usbmux_packet_free(usbmux_packet_t *upacket) { + CFAllocatorDeallocate(kCFAllocatorDefault, upacket); +} + + +NSString * const Lookin_PTUSBDeviceDidAttachNotification = @"Lookin_PTUSBDeviceDidAttachNotification"; +NSString * const Lookin_PTUSBDeviceDidDetachNotification = @"Lookin_PTUSBDeviceDidDetachNotification"; + +static NSString *kPlistPacketTypeListen = @"Listen"; +static NSString *kPlistPacketTypeConnect = @"Connect"; + + +// Represents a channel of communication between the host process and a remote +// (device) system. In practice, a Lookin_PTUSBChannel is connected to a usbmuxd +// endpoint which is configured to either listen for device changes (the +// PTUSBHub's channel is usually configured as a device notification listener) or +// configured as a TCP bridge (e.g. channels returned from PTUSBHub's +// connectToDevice:port:callback:). You should not create channels yourself, but +// let Lookin_PTUSBHub provide you with already configured channels. +@interface Lookin_PTUSBChannel : NSObject { + dispatch_io_t channel_; + dispatch_queue_t queue_; + uint32_t nextPacketTag_; + NSMutableDictionary *responseQueue_; + BOOL autoReadPackets_; + BOOL isReadingPackets_; +} + +// The underlying dispatch I/O channel. This is handy if you want to handle your +// own I/O logic without Lookin_PTUSBChannel. Remember to dispatch_retain() the channel +// if you plan on using it as it might be released from the Lookin_PTUSBChannel at any +// point in time. +@property (readonly) dispatch_io_t dispatchChannel; + +// The underlying file descriptor. +@property (readonly) dispatch_fd_t fileDescriptor; + +// Send data +- (void)sendDispatchData:(dispatch_data_t)data callback:(void(^)(NSError*))callback; +- (void)sendData:(NSData*)data callback:(void(^)(NSError*))callback; + +// Read data +- (void)readFromOffset:(off_t)offset length:(size_t)length callback:(void(^)(NSError *error, dispatch_data_t data))callback; + +// Close the channel, preventing further reads and writes, but letting currently +// queued reads and writes finish. +- (void)cancel; + +// Close the channel, preventing further reads and writes, immediately +// terminating any ongoing reads and writes. +- (void)stop; + +@end + + +@interface Lookin_PTUSBChannel (Private) + ++ (NSDictionary*)packetDictionaryWithPacketType:(NSString*)messageType payload:(NSDictionary*)payload; +- (BOOL)openOnQueue:(dispatch_queue_t)queue error:(NSError**)error onEnd:(void(^)(NSError *error))onEnd; +- (void)listenWithBroadcastHandler:(void(^)(NSDictionary *packet))broadcastHandler callback:(void(^)(NSError*))callback; +- (BOOL)errorFromPlistResponse:(NSDictionary*)packet error:(NSError**)error; +- (uint32_t)nextPacketTag; +- (void)sendPacketOfType:(USBMuxPacketType)type overProtocol:(USBMuxPacketProtocol)protocol tag:(uint32_t)tag payload:(NSData*)payload callback:(void(^)(NSError*))callback; +- (void)sendPacket:(NSDictionary*)packet tag:(uint32_t)tag callback:(void(^)(NSError *error))callback; +- (void)sendRequest:(NSDictionary*)packet callback:(void(^)(NSError *error, NSDictionary *responsePacket))callback; +- (void)scheduleReadPacketWithCallback:(void(^)(NSError *error, NSDictionary *packet, uint32_t packetTag))callback; +- (void)scheduleReadPacketWithBroadcastHandler:(void(^)(NSDictionary *packet))broadcastHandler; +- (void)setNeedsReadingPacket; +@end + + +@interface Lookin_PTUSBHub () { + Lookin_PTUSBChannel *channel_; +} +- (void)handleBroadcastPacket:(NSDictionary*)packet; +@end + + +@implementation Lookin_PTUSBHub + + ++ (Lookin_PTUSBHub*)sharedHub { + static Lookin_PTUSBHub *gSharedHub; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + gSharedHub = [Lookin_PTUSBHub new]; + [gSharedHub listenOnQueue:dispatch_get_main_queue() onStart:^(NSError *error) { + if (error) { + NSLog(@"Lookin_PTUSBHub failed to initialize: %@", error); + } + } onEnd:nil]; + }); + return gSharedHub; +} + + +- (id)init { + if (!(self = [super init])) return nil; + + return self; +} + + +- (void)listenOnQueue:(dispatch_queue_t)queue onStart:(void(^)(NSError*))onStart onEnd:(void(^)(NSError*))onEnd { + if (channel_) { + if (onStart) onStart(nil); + return; + } + channel_ = [Lookin_PTUSBChannel new]; + NSError *error = nil; + if ([channel_ openOnQueue:queue error:&error onEnd:onEnd]) { + [channel_ listenWithBroadcastHandler:^(NSDictionary *packet) { [self handleBroadcastPacket:packet]; } callback:onStart]; + } else if (onStart) { + onStart(error); + } +} + + +- (void)connectToDevice:(NSNumber*)deviceID port:(int)port onStart:(void(^)(NSError*, dispatch_io_t))onStart onEnd:(void(^)(NSError*))onEnd { + Lookin_PTUSBChannel *channel = [Lookin_PTUSBChannel new]; + NSError *error = nil; + + if (![channel openOnQueue:dispatch_get_main_queue() error:&error onEnd:onEnd]) { + onStart(error, nil); + return; + } + + port = ((port<<8) & 0xFF00) | (port>>8); // limit + + NSDictionary *packet = [Lookin_PTUSBChannel packetDictionaryWithPacketType:kPlistPacketTypeConnect + payload:[NSDictionary dictionaryWithObjectsAndKeys: + deviceID, @"DeviceID", + [NSNumber numberWithInt:port], @"PortNumber", + nil]]; + + [channel sendRequest:packet callback:^(NSError *error_, NSDictionary *responsePacket) { + NSError *error = error_; + [channel errorFromPlistResponse:responsePacket error:&error]; + onStart(error, (error ? nil : channel.dispatchChannel) ); + }]; +} + + +- (void)handleBroadcastPacket:(NSDictionary*)packet { + NSString *messageType = [packet objectForKey:@"MessageType"]; + + if ([@"Attached" isEqualToString:messageType]) { + [[NSNotificationCenter defaultCenter] postNotificationName:Lookin_PTUSBDeviceDidAttachNotification object:self userInfo:packet]; + } else if ([@"Detached" isEqualToString:messageType]) { + [[NSNotificationCenter defaultCenter] postNotificationName:Lookin_PTUSBDeviceDidDetachNotification object:self userInfo:packet]; + } else { + NSLog(@"Warning: Unhandled broadcast message: %@", packet); + } +} + + +@end + +#pragma mark - + +@implementation Lookin_PTUSBChannel + ++ (NSDictionary*)packetDictionaryWithPacketType:(NSString*)messageType payload:(NSDictionary*)payload { + NSDictionary *packet = nil; + + static NSString *bundleName = nil; + static NSString *bundleVersion = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *infoDict = [NSBundle mainBundle].infoDictionary; + if (infoDict) { + bundleName = [infoDict objectForKey:@"CFBundleName"]; + bundleVersion = [[infoDict objectForKey:@"CFBundleVersion"] description]; + } + }); + + if (bundleName) { + packet = [NSDictionary dictionaryWithObjectsAndKeys: + messageType, @"MessageType", + bundleName, @"ProgName", + bundleVersion, @"ClientVersionString", + nil]; + } else { + packet = [NSDictionary dictionaryWithObjectsAndKeys:messageType, @"MessageType", nil]; + } + + if (payload) { + NSMutableDictionary *mpacket = [NSMutableDictionary dictionaryWithDictionary:payload]; + [mpacket addEntriesFromDictionary:packet]; + packet = mpacket; + } + + return packet; +} + + +- (id)init { + if (!(self = [super init])) return nil; + + return self; +} + + +- (void)dealloc { + //NSLog(@"dealloc %@", self); + if (channel_) { +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(channel_); +#endif + channel_ = nil; + } +} + + +- (BOOL)valid { + return !!channel_; +} + + +- (dispatch_io_t)dispatchChannel { + return channel_; +} + + +- (dispatch_fd_t)fileDescriptor { + return dispatch_io_get_descriptor(channel_); +} + + +- (BOOL)openOnQueue:(dispatch_queue_t)queue error:(NSError**)error onEnd:(void(^)(NSError*))onEnd { + assert(queue != nil); + assert(channel_ == nil); + queue_ = queue; + + // Create socket + dispatch_fd_t fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + if (error) *error = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]; + return NO; + } + + // prevent SIGPIPE + int on = 1; + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); + + // Connect socket + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, "/var/run/usbmuxd"); + socklen_t socklen = sizeof(addr); + if (connect(fd, (struct sockaddr*)&addr, socklen) == -1) { + if (error) *error = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]; + return NO; + } + + channel_ = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue_, ^(int error) { + close(fd); + if (onEnd) { + onEnd(error == 0 ? nil : [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil]); + } + }); + + return YES; +} + + +- (void)listenWithBroadcastHandler:(void(^)(NSDictionary *packet))broadcastHandler callback:(void(^)(NSError*))callback { + autoReadPackets_ = YES; + [self scheduleReadPacketWithBroadcastHandler:broadcastHandler]; + + NSDictionary *packet = [Lookin_PTUSBChannel packetDictionaryWithPacketType:kPlistPacketTypeListen payload:nil]; + + [self sendRequest:packet callback:^(NSError *error_, NSDictionary *responsePacket) { + if (!callback) + return; + + NSError *error = error_; + [self errorFromPlistResponse:responsePacket error:&error]; + + callback(error); + }]; +} + + +- (BOOL)errorFromPlistResponse:(NSDictionary*)packet error:(NSError**)error { + if (!*error) { + NSNumber *n = [packet objectForKey:@"Number"]; + + if (!n) { + *error = [NSError errorWithDomain:Lookin_PTUSBHubErrorDomain code:(n ? n.integerValue : 0) userInfo:nil]; + return NO; + } + + USBMuxReplyCode replyCode = (USBMuxReplyCode)n.integerValue; + if (replyCode != 0) { + NSString *errmessage = @"Unspecified error"; + switch (replyCode) { + case USBMuxReplyCodeBadCommand: errmessage = @"illegal command"; break; + case USBMuxReplyCodeBadDevice: errmessage = @"unknown device"; break; + case USBMuxReplyCodeConnectionRefused: errmessage = @"connection refused"; break; + case USBMuxReplyCodeBadVersion: errmessage = @"invalid version"; break; + default: break; + } + *error = [NSError errorWithDomain:Lookin_PTUSBHubErrorDomain code:replyCode userInfo:[NSDictionary dictionaryWithObject:errmessage forKey:NSLocalizedDescriptionKey]]; + return NO; + } + } + return YES; +} + + +- (uint32_t)nextPacketTag { + return ++nextPacketTag_; +} + + +- (void)sendRequest:(NSDictionary*)packet callback:(void(^)(NSError*, NSDictionary*))callback { + uint32_t tag = [self nextPacketTag]; + [self sendPacket:packet tag:tag callback:^(NSError *error) { + if (error) { + callback(error, nil); + return; + } + // TODO: timeout un-triggered callbacks in responseQueue_ + if (!self->responseQueue_) self->responseQueue_ = [NSMutableDictionary new]; + [self->responseQueue_ setObject:callback forKey:[NSNumber numberWithUnsignedInt:tag]]; + }]; + + // We are awaiting a response + [self setNeedsReadingPacket]; +} + + +- (void)setNeedsReadingPacket { + if (!isReadingPackets_) { + [self scheduleReadPacketWithBroadcastHandler:nil]; + } +} + + +- (void)scheduleReadPacketWithBroadcastHandler:(void(^)(NSDictionary *packet))broadcastHandler { + assert(isReadingPackets_ == NO); + + [self scheduleReadPacketWithCallback:^(NSError *error, NSDictionary *packet, uint32_t packetTag) { + // Interpret the package we just received + if (packetTag == 0) { + // Broadcast message + //NSLog(@"Received broadcast: %@", packet); + if (broadcastHandler) broadcastHandler(packet); + } else if (self->responseQueue_) { + // Reply + NSNumber *key = [NSNumber numberWithUnsignedInt:packetTag]; + void(^requestCallback)(NSError*,NSDictionary*) = [self->responseQueue_ objectForKey:key]; + if (requestCallback) { + [self->responseQueue_ removeObjectForKey:key]; + requestCallback(error, packet); + } else { + NSLog(@"Warning: Ignoring reply packet for which there is no registered callback. Packet => %@", packet); + } + } + + // Schedule reading another incoming package + if (self->autoReadPackets_) { + [self scheduleReadPacketWithBroadcastHandler:broadcastHandler]; + } + }]; +} + + +- (void)scheduleReadPacketWithCallback:(void(^)(NSError*, NSDictionary*, uint32_t))callback { + static usbmux_packet_t ref_upacket; + isReadingPackets_ = YES; + + // Read the first `sizeof(ref_upacket.size)` bytes off the channel_ + dispatch_io_read(channel_, 0, sizeof(ref_upacket.size), queue_, ^(bool done, dispatch_data_t data, int error) { + //NSLog(@"dispatch_io_read 0,4: done=%d data=%p error=%d", done, data, error); + + if (!done) + return; + + if (error) { + self->isReadingPackets_ = NO; + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], nil, 0); + return; + } + + // Read size of incoming usbmux_packet_t + uint32_t upacket_len = 0; + char *buffer = NULL; + size_t buffer_size = 0; + PT_PRECISE_LIFETIME_UNUSED dispatch_data_t map_data = dispatch_data_create_map(data, (const void **)&buffer, &buffer_size); // objc_precise_lifetime guarantees 'map_data' isn't released before memcpy has a chance to do its thing + assert(buffer_size == sizeof(ref_upacket.size)); + assert(sizeof(upacket_len) == sizeof(ref_upacket.size)); + memcpy((void *)&(upacket_len), (const void *)buffer, buffer_size); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(map_data); +#endif + + // Allocate a new usbmux_packet_t for the expected size + uint32_t payloadLength = upacket_len - (uint32_t)sizeof(usbmux_packet_t); + usbmux_packet_t *upacket = usbmux_packet_alloc(payloadLength); + + // Read rest of the incoming usbmux_packet_t + off_t offset = sizeof(ref_upacket.size); + dispatch_io_read(self->channel_, offset, (size_t)(upacket->size - offset), self->queue_, ^(bool done, dispatch_data_t data, int error) { + //NSLog(@"dispatch_io_read X,Y: done=%d data=%p error=%d", done, data, error); + + if (!done) { + return; + } + + self->isReadingPackets_ = NO; + + if (error) { + callback([[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil], nil, 0); + usbmux_packet_free(upacket); + return; + } + + if (upacket_len > kUsbmuxPacketMaxPayloadSize) { + callback( + [[NSError alloc] initWithDomain:Lookin_PTUSBHubErrorDomain code:1 userInfo:@{ + NSLocalizedDescriptionKey:@"Received a packet that is too large"}], + nil, + 0 + ); + usbmux_packet_free(upacket); + return; + } + + // Copy read bytes onto our usbmux_packet_t + char *buffer = NULL; + size_t buffer_size = 0; + PT_PRECISE_LIFETIME_UNUSED dispatch_data_t map_data = dispatch_data_create_map(data, (const void **)&buffer, &buffer_size); + assert(buffer_size == upacket->size - offset); + memcpy(((void *)(upacket))+offset, (const void *)buffer, buffer_size); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(map_data); +#endif + + // We only support plist protocol + if (upacket->protocol != USBMuxPacketProtocolPlist) { + callback([[NSError alloc] initWithDomain:Lookin_PTUSBHubErrorDomain code:0 userInfo:[NSDictionary dictionaryWithObject:@"Unexpected package protocol" forKey:NSLocalizedDescriptionKey]], nil, upacket->tag); + usbmux_packet_free(upacket); + return; + } + + // Only one type of packet in the plist protocol + if (upacket->type != USBMuxPacketTypePlistPayload) { + callback([[NSError alloc] initWithDomain:Lookin_PTUSBHubErrorDomain code:0 userInfo:[NSDictionary dictionaryWithObject:@"Unexpected package type" forKey:NSLocalizedDescriptionKey]], nil, upacket->tag); + usbmux_packet_free(upacket); + return; + } + + // Try to decode any payload as plist + NSError *err = nil; + NSDictionary *dict = nil; + if (usbmux_packet_payload_size(upacket)) { + dict = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytesNoCopy:usbmux_packet_payload(upacket) length:usbmux_packet_payload_size(upacket) freeWhenDone:NO] options:NSPropertyListImmutable format:NULL error:&err]; + } + + // Invoke callback + callback(err, dict, upacket->tag); + usbmux_packet_free(upacket); + }); + }); +} + + +- (void)sendPacketOfType:(USBMuxPacketType)type + overProtocol:(USBMuxPacketProtocol)protocol + tag:(uint32_t)tag + payload:(NSData*)payload + callback:(void(^)(NSError*))callback +{ + assert(payload.length <= kUsbmuxPacketMaxPayloadSize); + usbmux_packet_t *upacket = usbmux_packet_create( + protocol, + type, + tag, + payload ? payload.bytes : nil, + (uint32_t)(payload ? payload.length : 0) + ); + dispatch_data_t data = dispatch_data_create((const void*)upacket, upacket->size, queue_, ^{ + // Free packet when data is freed + usbmux_packet_free(upacket); + }); + //NSData *data1 = [NSData dataWithBytesNoCopy:(void*)upacket length:upacket->size freeWhenDone:NO]; + //[data1 writeToFile:[NSString stringWithFormat:@"/Users/rsms/c-packet-%u.data", tag] atomically:NO]; + [self sendDispatchData:data callback:callback]; +} + + +- (void)sendPacket:(NSDictionary*)packet tag:(uint32_t)tag callback:(void(^)(NSError*))callback { + NSError *error = nil; + // NSPropertyListBinaryFormat_v1_0 + NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:packet format:NSPropertyListXMLFormat_v1_0 options:0 error:&error]; + if (!plistData) { + callback(error); + } else { + [self sendPacketOfType:USBMuxPacketTypePlistPayload overProtocol:USBMuxPacketProtocolPlist tag:tag payload:plistData callback:callback]; + } +} + + +- (void)sendDispatchData:(dispatch_data_t)data callback:(void(^)(NSError*))callback { + off_t offset = 0; + dispatch_io_write(channel_, offset, data, queue_, ^(bool done, dispatch_data_t data, int _errno) { + //NSLog(@"dispatch_io_write: done=%d data=%p error=%d", done, data, error); + if (!done) + return; + if (callback) { + NSError *err = nil; + if (_errno) err = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:_errno userInfo:nil]; + callback(err); + } + }); +#if PT_DISPATCH_RETAIN_RELEASE + dispatch_release(data); // Release our ref. A ref is still held by dispatch_io_write +#endif +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-getter-return-value" + +- (void)sendData:(NSData*)data callback:(void(^)(NSError*))callback { + dispatch_data_t ddata = dispatch_data_create((const void*)data.bytes, data.length, queue_, ^{ + // trick to have the block capture and retain the data + [data length]; + }); + [self sendDispatchData:ddata callback:callback]; +} + +#pragma clang diagnostic pop + +- (void)readFromOffset:(off_t)offset length:(size_t)length callback:(void(^)(NSError *error, dispatch_data_t data))callback { + dispatch_io_read(channel_, offset, length, queue_, ^(bool done, dispatch_data_t data, int _errno) { + if (!done) + return; + + NSError *error = nil; + if (_errno != 0) { + error = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:_errno userInfo:nil]; + } + + callback(error, data); + }); +} + + +- (void)cancel { + if (channel_) { + dispatch_io_close(channel_, 0); + } +} + + +- (void)stop { + if (channel_) { + dispatch_io_close(channel_, DISPATCH_IO_STOP); + } +} + +@end + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/LookinServer/Src/Main/Shared/Peertalk/Peertalk.h b/Pods/LookinServer/Src/Main/Shared/Peertalk/Peertalk.h new file mode 100644 index 00000000..82493292 --- /dev/null +++ b/Pods/LookinServer/Src/Main/Shared/Peertalk/Peertalk.h @@ -0,0 +1,28 @@ +#ifdef SHOULD_COMPILE_LOOKIN_SERVER + +// +// Peertalk.h +// Peertalk +// +// Created by Marek Cirkos on 12/04/2016. +// +// + + + +#import + +//! Project version number for Peertalk. +FOUNDATION_EXPORT double PeertalkVersionNumber; + +//! Project version string for Peertalk. +FOUNDATION_EXPORT const unsigned char PeertalkVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + +#import "Lookin_PTChannel.h" +#import "Lookin_PTProtocol.h" +#import "Lookin_PTUSBHub.h" + +#endif /* SHOULD_COMPILE_LOOKIN_SERVER */ diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index d40c4d44..9ac22ae7 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -110,4 +110,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 817a9f6635815ee132800871dcfecfd381ee2044 -COCOAPODS: 1.16.2 +COCOAPODS: 1.15.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 397277e9..ef660565 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -3,13 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ 1CD0618C486973D5588EF20D2E8C0AEA /* SwiftFormat */ = { isa = PBXAggregateTarget; - buildConfigurationList = 46EB2E00007DF0 /* Build configuration list for PBXAggregateTarget "SwiftFormat" */; + buildConfigurationList = 46EB2E00007D90 /* Build configuration list for PBXAggregateTarget "SwiftFormat" */; buildPhases = ( ); dependencies = ( @@ -19,1332 +19,1330 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 46EB2E00004870 /* CLCameraController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A80 /* CLCameraController.swift */; }; - 46EB2E00004880 /* CLCameraImagePreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A90 /* CLCameraImagePreviewController.swift */; }; - 46EB2E00004890 /* CLCameraVideoPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AA0 /* CLCameraVideoPreviewController.swift */; }; - 46EB2E000048A0 /* AVCaptureDevice+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AB0 /* AVCaptureDevice+Extension.swift */; }; - 46EB2E000048B0 /* AVCapturePhoto+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AC0 /* AVCapturePhoto+Extension.swift */; }; - 46EB2E000048C0 /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AD0 /* UIImage+Extension.swift */; }; - 46EB2E000048D0 /* CLCameraConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AE0 /* CLCameraConfig.swift */; }; - 46EB2E000048E0 /* CLCameraEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AF0 /* CLCameraEnum.swift */; }; - 46EB2E000048F0 /* CLCameraError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B00 /* CLCameraError.swift */; }; - 46EB2E00004900 /* CLCameraHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B10 /* CLCameraHelper.swift */; }; - 46EB2E00004910 /* CLCameraOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B20 /* CLCameraOrientation.swift */; }; - 46EB2E00004920 /* CLPermissionInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B30 /* CLPermissionInterface.swift */; }; - 46EB2E00004930 /* CLPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B40 /* CLPermissions.swift */; }; - 46EB2E00004940 /* CLCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B50 /* CLCameraButton.swift */; }; - 46EB2E00004950 /* CLCameraControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B60 /* CLCameraControlView.swift */; }; - 46EB2E00004960 /* CLCameraPreviewToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B70 /* CLCameraPreviewToolBar.swift */; }; - 46EB2E00004970 /* CLLoadingHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B80 /* CLLoadingHUD.swift */; }; - 46EB2E00004980 /* CLLoadingHUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B90 /* CLLoadingHUDView.swift */; }; - 46EB2E00004990 /* CLLoadingProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BA0 /* CLLoadingProgressView.swift */; }; - 46EB2E000049F0 /* CLCamera-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000049E0 /* CLCamera-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00004A30 /* CLCamera-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004A20 /* CLCamera-dummy.m */; }; - 46EB2E00004AC0 /* CLPopoverConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BB0 /* CLPopoverConfig.swift */; }; - 46EB2E00004AD0 /* CLPopoverController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BC0 /* CLPopoverController.swift */; }; - 46EB2E00004AE0 /* CLPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BD0 /* CLPopoverManager.swift */; }; - 46EB2E00004AF0 /* CLPopoverProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BE0 /* CLPopoverProtocol.swift */; }; - 46EB2E00004B00 /* CLPopoverWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BF0 /* CLPopoverWindow.swift */; }; - 46EB2E00004B60 /* CLPopoverManager-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00004B50 /* CLPopoverManager-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00004BA0 /* CLPopoverManager-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004B90 /* CLPopoverManager-dummy.m */; }; - 46EB2E00004CB0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004760 /* PrivacyInfo.xcprivacy */; }; - 46EB2E00004CE0 /* AEAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C00 /* AEAD.swift */; }; - 46EB2E00004CF0 /* AEADChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C10 /* AEADChaCha20Poly1305.swift */; }; - 46EB2E00004D00 /* AEADXChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C20 /* AEADXChaCha20Poly1305.swift */; }; - 46EB2E00004D10 /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C30 /* AES.Cryptors.swift */; }; - 46EB2E00004D20 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C40 /* AES.swift */; }; - 46EB2E00004D30 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C50 /* Array+Extension.swift */; }; - 46EB2E00004D40 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C60 /* ASN1.swift */; }; - 46EB2E00004D50 /* ASN1Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C70 /* ASN1Decoder.swift */; }; - 46EB2E00004D60 /* ASN1Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C80 /* ASN1Encoder.swift */; }; - 46EB2E00004D70 /* ASN1Scanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C90 /* ASN1Scanner.swift */; }; - 46EB2E00004D80 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CA0 /* Authenticator.swift */; }; - 46EB2E00004D90 /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CB0 /* BatchedCollection.swift */; }; - 46EB2E00004DA0 /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CC0 /* Bit.swift */; }; - 46EB2E00004DB0 /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CD0 /* BlockCipher.swift */; }; - 46EB2E00004DC0 /* BlockDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CE0 /* BlockDecryptor.swift */; }; - 46EB2E00004DD0 /* BlockEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CF0 /* BlockEncryptor.swift */; }; - 46EB2E00004DE0 /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D00 /* BlockMode.swift */; }; - 46EB2E00004DF0 /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D10 /* BlockModeOptions.swift */; }; - 46EB2E00004E00 /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D20 /* CBC.swift */; }; - 46EB2E00004E10 /* CCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D30 /* CCM.swift */; }; - 46EB2E00004E20 /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D40 /* CFB.swift */; }; - 46EB2E00004E30 /* CipherModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D50 /* CipherModeWorker.swift */; }; - 46EB2E00004E40 /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D60 /* CTR.swift */; }; - 46EB2E00004E50 /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D70 /* ECB.swift */; }; - 46EB2E00004E60 /* GCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D80 /* GCM.swift */; }; - 46EB2E00004E70 /* OCB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D90 /* OCB.swift */; }; - 46EB2E00004E80 /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DA0 /* OFB.swift */; }; - 46EB2E00004E90 /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DB0 /* PCBC.swift */; }; - 46EB2E00004EA0 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DC0 /* Blowfish.swift */; }; - 46EB2E00004EB0 /* CBCMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DD0 /* CBCMAC.swift */; }; - 46EB2E00004EC0 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DE0 /* ChaCha20.swift */; }; - 46EB2E00004ED0 /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DF0 /* Checksum.swift */; }; - 46EB2E00004EE0 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E00 /* Cipher.swift */; }; - 46EB2E00004EF0 /* CMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E10 /* CMAC.swift */; }; - 46EB2E00004F00 /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E20 /* Collection+Extension.swift */; }; - 46EB2E00004F10 /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E30 /* CompactMap.swift */; }; - 46EB2E00004F20 /* Cryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E40 /* Cryptor.swift */; }; - 46EB2E00004F30 /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E50 /* Cryptors.swift */; }; - 46EB2E00004F40 /* Addition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E60 /* Addition.swift */; }; - 46EB2E00004F50 /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E70 /* BigInt.swift */; }; - 46EB2E00004F60 /* BigUInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E80 /* BigUInt.swift */; }; - 46EB2E00004F70 /* BitwiseOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E90 /* BitwiseOps.swift */; }; - 46EB2E00004F80 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EA0 /* Codable.swift */; }; - 46EB2E00004F90 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EB0 /* Comparable.swift */; }; - 46EB2E00004FA0 /* CS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EC0 /* CS.swift */; }; - 46EB2E00004FB0 /* DataConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001ED0 /* DataConversion.swift */; }; - 46EB2E00004FC0 /* Division.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EE0 /* Division.swift */; }; - 46EB2E00004FD0 /* Exponentiation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EF0 /* Exponentiation.swift */; }; - 46EB2E00004FE0 /* FloatingPointConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F00 /* FloatingPointConversion.swift */; }; - 46EB2E00004FF0 /* GCD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F10 /* GCD.swift */; }; - 46EB2E00005000 /* Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F20 /* Hashable.swift */; }; - 46EB2E00005010 /* IntegerConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F30 /* IntegerConversion.swift */; }; - 46EB2E00005020 /* Multiplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F40 /* Multiplication.swift */; }; - 46EB2E00005030 /* PrimeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F50 /* PrimeTest.swift */; }; - 46EB2E00005040 /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F60 /* Random.swift */; }; - 46EB2E00005050 /* Shifts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F70 /* Shifts.swift */; }; - 46EB2E00005060 /* SquareRoot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F80 /* SquareRoot.swift */; }; - 46EB2E00005070 /* Strideable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F90 /* Strideable.swift */; }; - 46EB2E00005080 /* StringConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FA0 /* StringConversion.swift */; }; - 46EB2E00005090 /* Subtraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FB0 /* Subtraction.swift */; }; - 46EB2E000050A0 /* WordsAndBits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FC0 /* WordsAndBits.swift */; }; - 46EB2E000050B0 /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FD0 /* Digest.swift */; }; - 46EB2E000050C0 /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FE0 /* DigestType.swift */; }; - 46EB2E000050D0 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FF0 /* AES+Foundation.swift */; }; - 46EB2E000050E0 /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002000 /* Array+Foundation.swift */; }; - 46EB2E000050F0 /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002010 /* Blowfish+Foundation.swift */; }; - 46EB2E00005100 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002020 /* ChaCha20+Foundation.swift */; }; - 46EB2E00005110 /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002030 /* Data+Extension.swift */; }; - 46EB2E00005120 /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002040 /* HMAC+Foundation.swift */; }; - 46EB2E00005130 /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002050 /* Rabbit+Foundation.swift */; }; - 46EB2E00005140 /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002060 /* String+FoundationExtension.swift */; }; - 46EB2E00005150 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002070 /* Utils+Foundation.swift */; }; - 46EB2E00005160 /* XChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002080 /* XChaCha20+Foundation.swift */; }; - 46EB2E00005170 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002090 /* Generics.swift */; }; - 46EB2E00005180 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020A0 /* HKDF.swift */; }; - 46EB2E00005190 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020B0 /* HMAC.swift */; }; - 46EB2E000051A0 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020C0 /* Int+Extension.swift */; }; - 46EB2E000051B0 /* ISO10126Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020D0 /* ISO10126Padding.swift */; }; - 46EB2E000051C0 /* ISO78164Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020E0 /* ISO78164Padding.swift */; }; - 46EB2E000051D0 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020F0 /* MD5.swift */; }; - 46EB2E000051E0 /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002100 /* NoPadding.swift */; }; - 46EB2E000051F0 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002110 /* Operators.swift */; }; - 46EB2E00005200 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002120 /* Padding.swift */; }; - 46EB2E00005210 /* DER.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002130 /* DER.swift */; }; - 46EB2E00005220 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002140 /* PBKDF1.swift */; }; - 46EB2E00005230 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002150 /* PBKDF2.swift */; }; - 46EB2E00005240 /* PKCS1v15.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002160 /* PKCS1v15.swift */; }; - 46EB2E00005250 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002170 /* PKCS5.swift */; }; - 46EB2E00005260 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002180 /* PKCS7.swift */; }; - 46EB2E00005270 /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002190 /* PKCS7Padding.swift */; }; - 46EB2E00005280 /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021A0 /* Poly1305.swift */; }; - 46EB2E00005290 /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021B0 /* Rabbit.swift */; }; - 46EB2E000052A0 /* RSA+Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021C0 /* RSA+Cipher.swift */; }; - 46EB2E000052B0 /* RSA+Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021D0 /* RSA+Signature.swift */; }; - 46EB2E000052C0 /* RSA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021E0 /* RSA.swift */; }; - 46EB2E000052D0 /* Scrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021F0 /* Scrypt.swift */; }; - 46EB2E000052E0 /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002200 /* SecureBytes.swift */; }; - 46EB2E000052F0 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002210 /* SHA1.swift */; }; - 46EB2E00005300 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002220 /* SHA2.swift */; }; - 46EB2E00005310 /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002230 /* SHA3.swift */; }; - 46EB2E00005320 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002240 /* Signature.swift */; }; - 46EB2E00005330 /* StreamDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002250 /* StreamDecryptor.swift */; }; - 46EB2E00005340 /* StreamEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002260 /* StreamEncryptor.swift */; }; - 46EB2E00005350 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002270 /* String+Extension.swift */; }; - 46EB2E00005360 /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002280 /* UInt128.swift */; }; - 46EB2E00005370 /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002290 /* UInt16+Extension.swift */; }; - 46EB2E00005380 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022A0 /* UInt32+Extension.swift */; }; - 46EB2E00005390 /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022B0 /* UInt64+Extension.swift */; }; - 46EB2E000053A0 /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022C0 /* UInt8+Extension.swift */; }; - 46EB2E000053B0 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022D0 /* Updatable.swift */; }; - 46EB2E000053C0 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022E0 /* Utils.swift */; }; - 46EB2E000053D0 /* XChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022F0 /* XChaCha20.swift */; }; - 46EB2E000053E0 /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002300 /* ZeroPadding.swift */; }; - 46EB2E00005430 /* CryptoSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00005420 /* CryptoSwift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005470 /* CryptoSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005460 /* CryptoSwift-dummy.m */; }; - 46EB2E00005500 /* DTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000001F0 /* DTConstants.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005510 /* DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000210 /* DTError.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005520 /* DTTimePeriod.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000230 /* DTTimePeriod.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005530 /* DTTimePeriodChain.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000250 /* DTTimePeriodChain.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005540 /* DTTimePeriodCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000270 /* DTTimePeriodCollection.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005550 /* DTTimePeriodGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000290 /* DTTimePeriodGroup.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005560 /* NSDate+DateTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000002B0 /* NSDate+DateTools.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005570 /* DateTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000001D0 /* DateTools.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005580 /* DTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000001E0 /* DTConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005590 /* DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000200 /* DTError.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000055A0 /* DTTimePeriod.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000220 /* DTTimePeriod.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000055B0 /* DTTimePeriodChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000240 /* DTTimePeriodChain.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000055C0 /* DTTimePeriodCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000260 /* DTTimePeriodCollection.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000055D0 /* DTTimePeriodGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000280 /* DTTimePeriodGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000055E0 /* NSDate+DateTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002A0 /* NSDate+DateTools.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005640 /* DateTools-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00005630 /* DateTools-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005670 /* DateTools-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005660 /* DateTools-dummy.m */; }; - 46EB2E00005700 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002310 /* Constants.swift */; }; - 46EB2E00005710 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002320 /* Date+Bundle.swift */; }; - 46EB2E00005720 /* Date+Comparators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002330 /* Date+Comparators.swift */; }; - 46EB2E00005730 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002340 /* Date+Components.swift */; }; - 46EB2E00005740 /* Date+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002350 /* Date+Format.swift */; }; - 46EB2E00005750 /* Date+Inits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002360 /* Date+Inits.swift */; }; - 46EB2E00005760 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002370 /* Date+Manipulations.swift */; }; - 46EB2E00005770 /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002380 /* Date+TimeAgo.swift */; }; - 46EB2E00005780 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002390 /* Enums.swift */; }; - 46EB2E00005790 /* Integer+DateTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023A0 /* Integer+DateTools.swift */; }; - 46EB2E000057A0 /* TimeChunk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023B0 /* TimeChunk.swift */; }; - 46EB2E000057B0 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023C0 /* TimePeriod.swift */; }; - 46EB2E000057C0 /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023D0 /* TimePeriodChain.swift */; }; - 46EB2E000057D0 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023E0 /* TimePeriodCollection.swift */; }; - 46EB2E000057E0 /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023F0 /* TimePeriodGroup.swift */; }; - 46EB2E00005840 /* DateToolsSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00005830 /* DateToolsSwift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005880 /* DateToolsSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005870 /* DateToolsSwift-dummy.m */; }; - 46EB2E00005990 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004780 /* PrivacyInfo.xcprivacy */; }; - 46EB2E000059C0 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002400 /* CacheSerializer.swift */; }; - 46EB2E000059D0 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002410 /* DiskStorage.swift */; }; - 46EB2E000059E0 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002420 /* FormatIndicatedCacheSerializer.swift */; }; - 46EB2E000059F0 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002430 /* ImageCache.swift */; }; - 46EB2E00005A00 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002440 /* MemoryStorage.swift */; }; - 46EB2E00005A10 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002450 /* Storage.swift */; }; - 46EB2E00005A20 /* CPListItem+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002460 /* CPListItem+Kingfisher.swift */; }; - 46EB2E00005A30 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002470 /* ImageView+Kingfisher.swift */; }; - 46EB2E00005A40 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002480 /* NSButton+Kingfisher.swift */; }; - 46EB2E00005A50 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002490 /* NSTextAttachment+Kingfisher.swift */; }; - 46EB2E00005A60 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024A0 /* TVMonogramView+Kingfisher.swift */; }; - 46EB2E00005A70 /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024B0 /* UIButton+Kingfisher.swift */; }; - 46EB2E00005A80 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024C0 /* WKInterfaceImage+Kingfisher.swift */; }; - 46EB2E00005A90 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024D0 /* AVAssetImageDataProvider.swift */; }; - 46EB2E00005AA0 /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024E0 /* ImageDataProvider.swift */; }; - 46EB2E00005AB0 /* PHPickerResultImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024F0 /* PHPickerResultImageDataProvider.swift */; }; - 46EB2E00005AC0 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002500 /* Resource.swift */; }; - 46EB2E00005AD0 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002510 /* Source.swift */; }; - 46EB2E00005AE0 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002520 /* KF.swift */; }; - 46EB2E00005AF0 /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002530 /* KFOptionsSetter.swift */; }; - 46EB2E00005B00 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002540 /* Kingfisher.swift */; }; - 46EB2E00005B10 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002550 /* KingfisherError.swift */; }; - 46EB2E00005B20 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002560 /* KingfisherManager.swift */; }; - 46EB2E00005B30 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002570 /* KingfisherOptionsInfo.swift */; }; - 46EB2E00005B40 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002580 /* Filter.swift */; }; - 46EB2E00005B50 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002590 /* GIFAnimatedImage.swift */; }; - 46EB2E00005B60 /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025A0 /* GraphicsContext.swift */; }; - 46EB2E00005B70 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025B0 /* Image.swift */; }; - 46EB2E00005B80 /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025C0 /* ImageDrawing.swift */; }; - 46EB2E00005B90 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025D0 /* ImageFormat.swift */; }; - 46EB2E00005BA0 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025E0 /* ImageProcessor.swift */; }; - 46EB2E00005BB0 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025F0 /* ImageProgressive.swift */; }; - 46EB2E00005BC0 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002600 /* ImageTransition.swift */; }; - 46EB2E00005BD0 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002610 /* Placeholder.swift */; }; - 46EB2E00005BE0 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002620 /* AuthenticationChallengeResponsable.swift */; }; - 46EB2E00005BF0 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002630 /* ImageDataProcessor.swift */; }; - 46EB2E00005C00 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002640 /* ImageDownloader.swift */; }; - 46EB2E00005C10 /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002650 /* ImageDownloaderDelegate.swift */; }; - 46EB2E00005C20 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002660 /* ImageModifier.swift */; }; - 46EB2E00005C30 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002670 /* ImagePrefetcher.swift */; }; - 46EB2E00005C40 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002680 /* RedirectHandler.swift */; }; - 46EB2E00005C50 /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002690 /* RequestModifier.swift */; }; - 46EB2E00005C60 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026A0 /* RetryStrategy.swift */; }; - 46EB2E00005C70 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026B0 /* SessionDataTask.swift */; }; - 46EB2E00005C80 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026C0 /* SessionDelegate.swift */; }; - 46EB2E00005C90 /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026D0 /* ImageBinder.swift */; }; - 46EB2E00005CA0 /* ImageContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026E0 /* ImageContext.swift */; }; - 46EB2E00005CB0 /* KFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026F0 /* KFAnimatedImage.swift */; }; - 46EB2E00005CC0 /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002700 /* KFImage.swift */; }; - 46EB2E00005CD0 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002710 /* KFImageOptions.swift */; }; - 46EB2E00005CE0 /* KFImageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002720 /* KFImageProtocol.swift */; }; - 46EB2E00005CF0 /* KFImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002730 /* KFImageRenderer.swift */; }; - 46EB2E00005D00 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002740 /* Box.swift */; }; - 46EB2E00005D10 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002750 /* CallbackQueue.swift */; }; - 46EB2E00005D20 /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002760 /* Delegate.swift */; }; - 46EB2E00005D30 /* DisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002770 /* DisplayLink.swift */; }; - 46EB2E00005D40 /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002780 /* ExtensionHelpers.swift */; }; - 46EB2E00005D50 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002790 /* Result.swift */; }; - 46EB2E00005D60 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027A0 /* Runtime.swift */; }; - 46EB2E00005D70 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027B0 /* SizeExtensions.swift */; }; - 46EB2E00005D80 /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027C0 /* String+MD5.swift */; }; - 46EB2E00005D90 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027D0 /* AnimatedImageView.swift */; }; - 46EB2E00005DA0 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027E0 /* Indicator.swift */; }; - 46EB2E00005DF0 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00005DE0 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00005E30 /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005E20 /* Kingfisher-dummy.m */; }; - 46EB2E00005EC0 /* CALayer+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002810 /* CALayer+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005ED0 /* NSObject+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002830 /* NSObject+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005EE0 /* UIBlurEffect+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002850 /* UIBlurEffect+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005EF0 /* UIColor+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002870 /* UIColor+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F00 /* UIImage+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002890 /* UIImage+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F10 /* UIImageView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028B0 /* UIImageView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F20 /* UILabel+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028D0 /* UILabel+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F30 /* UITableView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028F0 /* UITableView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F40 /* UITextField+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002910 /* UITextField+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F50 /* UITextView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002930 /* UITextView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F60 /* UIView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002950 /* UIView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F70 /* UIViewController+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002970 /* UIViewController+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F80 /* UIVisualEffectView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002990 /* UIVisualEffectView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005F90 /* LKS_ConnectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029B0 /* LKS_ConnectionManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FA0 /* LKS_RequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029D0 /* LKS_RequestHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FB0 /* LKS_AttrModificationPatchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029F0 /* LKS_AttrModificationPatchHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FC0 /* LKS_CustomAttrModificationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A10 /* LKS_CustomAttrModificationHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FD0 /* LKS_HierarchyDetailsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A30 /* LKS_HierarchyDetailsHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FE0 /* LKS_InbuiltAttrModificationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A50 /* LKS_InbuiltAttrModificationHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00005FF0 /* LKSConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A80 /* LKSConfigManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006000 /* LKS_AttrGroupsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AA0 /* LKS_AttrGroupsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006010 /* LKS_CustomAttrGroupsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AC0 /* LKS_CustomAttrGroupsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006020 /* LKS_CustomAttrSetterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AE0 /* LKS_CustomAttrSetterManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006030 /* LKS_CustomDisplayItemsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B00 /* LKS_CustomDisplayItemsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006040 /* LKS_EventHandlerMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B20 /* LKS_EventHandlerMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006050 /* LKS_ExportManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B40 /* LKS_ExportManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006060 /* LKS_GestureTargetActionsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B60 /* LKS_GestureTargetActionsSearcher.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006070 /* LKS_Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B80 /* LKS_Helper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006080 /* LKS_HierarchyDisplayItemsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BA0 /* LKS_HierarchyDisplayItemsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006090 /* LKS_MultiplatformAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BC0 /* LKS_MultiplatformAdapter.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060A0 /* LKS_ObjectRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BE0 /* LKS_ObjectRegistry.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060B0 /* LKS_TraceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C00 /* LKS_TraceManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060C0 /* CALayer+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C30 /* CALayer+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060D0 /* Color+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C50 /* Color+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060E0 /* Image+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C70 /* Image+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000060F0 /* NSArray+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C90 /* NSArray+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006100 /* NSObject+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CB0 /* NSObject+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006110 /* NSSet+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CD0 /* NSSet+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006120 /* NSString+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CF0 /* NSString+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006130 /* LookinAppInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D10 /* LookinAppInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006140 /* LookinAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D30 /* LookinAttribute.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006150 /* LookinAttributeModification.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D50 /* LookinAttributeModification.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006160 /* LookinAttributesGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D70 /* LookinAttributesGroup.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006170 /* LookinAttributesSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D90 /* LookinAttributesSection.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006180 /* LookinAttrIdentifiers.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DB0 /* LookinAttrIdentifiers.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006190 /* LookinAutoLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DE0 /* LookinAutoLayoutConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061A0 /* LookinConnectionAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E10 /* LookinConnectionAttachment.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061B0 /* LookinConnectionResponseAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E30 /* LookinConnectionResponseAttachment.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061C0 /* LookinCustomAttrModification.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E50 /* LookinCustomAttrModification.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061D0 /* LookinCustomDisplayItemInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E70 /* LookinCustomDisplayItemInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061E0 /* LookinDashboardBlueprint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E90 /* LookinDashboardBlueprint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000061F0 /* LookinDisplayItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EC0 /* LookinDisplayItem.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006200 /* LookinDisplayItemDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EE0 /* LookinDisplayItemDetail.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006210 /* LookinEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F00 /* LookinEventHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006220 /* LookinHierarchyFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F20 /* LookinHierarchyFile.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006230 /* LookinHierarchyInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F40 /* LookinHierarchyInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006240 /* LookinObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F60 /* LookinObject.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006250 /* LookinStaticAsyncUpdateTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F80 /* LookinStaticAsyncUpdateTask.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006260 /* LookinTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FA0 /* LookinTuple.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006270 /* LookinWeakContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FC0 /* LookinWeakContainer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006280 /* Lookin_PTChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FE0 /* Lookin_PTChannel.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006290 /* Lookin_PTProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003010 /* Lookin_PTProtocol.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000062A0 /* Lookin_PTUSBHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003030 /* Lookin_PTUSBHub.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000062B0 /* LookinIvarTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003060 /* LookinIvarTrace.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000062C0 /* CALayer+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002800 /* CALayer+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000062D0 /* NSObject+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002820 /* NSObject+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000062E0 /* UIBlurEffect+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002840 /* UIBlurEffect+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000062F0 /* UIColor+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002860 /* UIColor+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006300 /* UIImage+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002880 /* UIImage+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006310 /* UIImageView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028A0 /* UIImageView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006320 /* UILabel+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028C0 /* UILabel+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006330 /* UITableView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028E0 /* UITableView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006340 /* UITextField+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002900 /* UITextField+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006350 /* UITextView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002920 /* UITextView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006360 /* UIView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002940 /* UIView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006370 /* UIViewController+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002960 /* UIViewController+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006380 /* UIVisualEffectView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002980 /* UIVisualEffectView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006390 /* LKS_ConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029A0 /* LKS_ConnectionManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063A0 /* LKS_RequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029C0 /* LKS_RequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063B0 /* LKS_AttrModificationPatchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029E0 /* LKS_AttrModificationPatchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063C0 /* LKS_CustomAttrModificationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A00 /* LKS_CustomAttrModificationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063D0 /* LKS_HierarchyDetailsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A20 /* LKS_HierarchyDetailsHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063E0 /* LKS_InbuiltAttrModificationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A40 /* LKS_InbuiltAttrModificationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000063F0 /* LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A60 /* LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006400 /* LKSConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A70 /* LKSConfigManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006410 /* LKS_AttrGroupsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A90 /* LKS_AttrGroupsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006420 /* LKS_CustomAttrGroupsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AB0 /* LKS_CustomAttrGroupsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006430 /* LKS_CustomAttrSetterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AD0 /* LKS_CustomAttrSetterManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006440 /* LKS_CustomDisplayItemsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AF0 /* LKS_CustomDisplayItemsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006450 /* LKS_EventHandlerMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B10 /* LKS_EventHandlerMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006460 /* LKS_ExportManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B30 /* LKS_ExportManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006470 /* LKS_GestureTargetActionsSearcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B50 /* LKS_GestureTargetActionsSearcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006480 /* LKS_Helper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B70 /* LKS_Helper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006490 /* LKS_HierarchyDisplayItemsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B90 /* LKS_HierarchyDisplayItemsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064A0 /* LKS_MultiplatformAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BB0 /* LKS_MultiplatformAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064B0 /* LKS_ObjectRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BD0 /* LKS_ObjectRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064C0 /* LKS_TraceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BF0 /* LKS_TraceManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064D0 /* LookinServerDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C10 /* LookinServerDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064E0 /* CALayer+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C20 /* CALayer+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000064F0 /* Color+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C40 /* Color+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006500 /* Image+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C60 /* Image+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006510 /* NSArray+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C80 /* NSArray+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006520 /* NSObject+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CA0 /* NSObject+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006530 /* NSSet+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CC0 /* NSSet+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006540 /* NSString+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CE0 /* NSString+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006550 /* LookinAppInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D00 /* LookinAppInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006560 /* LookinAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D20 /* LookinAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006570 /* LookinAttributeModification.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D40 /* LookinAttributeModification.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006580 /* LookinAttributesGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D60 /* LookinAttributesGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006590 /* LookinAttributesSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D80 /* LookinAttributesSection.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065A0 /* LookinAttrIdentifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DA0 /* LookinAttrIdentifiers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065B0 /* LookinAttrType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DC0 /* LookinAttrType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065C0 /* LookinAutoLayoutConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DD0 /* LookinAutoLayoutConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065D0 /* LookinCodingValueType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DF0 /* LookinCodingValueType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065E0 /* LookinConnectionAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E00 /* LookinConnectionAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000065F0 /* LookinConnectionResponseAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E20 /* LookinConnectionResponseAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006600 /* LookinCustomAttrModification.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E40 /* LookinCustomAttrModification.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006610 /* LookinCustomDisplayItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E60 /* LookinCustomDisplayItemInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006620 /* LookinDashboardBlueprint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E80 /* LookinDashboardBlueprint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006630 /* LookinDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EA0 /* LookinDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006640 /* LookinDisplayItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EB0 /* LookinDisplayItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006650 /* LookinDisplayItemDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002ED0 /* LookinDisplayItemDetail.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006660 /* LookinEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EF0 /* LookinEventHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006670 /* LookinHierarchyFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F10 /* LookinHierarchyFile.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006680 /* LookinHierarchyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F30 /* LookinHierarchyInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006690 /* LookinObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F50 /* LookinObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066A0 /* LookinStaticAsyncUpdateTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F70 /* LookinStaticAsyncUpdateTask.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066B0 /* LookinTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F90 /* LookinTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066C0 /* LookinWeakContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FB0 /* LookinWeakContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066D0 /* Lookin_PTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FD0 /* Lookin_PTChannel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066E0 /* Lookin_PTPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FF0 /* Lookin_PTPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000066F0 /* Lookin_PTProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003000 /* Lookin_PTProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006700 /* Lookin_PTUSBHub.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003020 /* Lookin_PTUSBHub.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006710 /* Peertalk.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003040 /* Peertalk.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006720 /* LookinIvarTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003050 /* LookinIvarTrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006780 /* LookinServer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006770 /* LookinServer-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000067B0 /* LookinServer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000067A0 /* LookinServer-dummy.m */; }; - 46EB2E000068C0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004720 /* PrivacyInfo.xcprivacy */; }; - 46EB2E000068F0 /* MJExtensionConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000002E0 /* MJExtensionConst.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006900 /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000300 /* MJFoundation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006910 /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000320 /* MJProperty.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006920 /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000340 /* MJPropertyKey.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006930 /* MJPropertyType.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000360 /* MJPropertyType.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006940 /* NSObject+MJClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000380 /* NSObject+MJClass.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006950 /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003A0 /* NSObject+MJCoding.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006960 /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003C0 /* NSObject+MJKeyValue.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006970 /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003E0 /* NSObject+MJProperty.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006980 /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000400 /* NSString+MJExtension.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006990 /* MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002C0 /* MJExtension.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069A0 /* MJExtensionConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002D0 /* MJExtensionConst.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069B0 /* MJFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002F0 /* MJFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069C0 /* MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000310 /* MJProperty.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069D0 /* MJPropertyKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000330 /* MJPropertyKey.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069E0 /* MJPropertyType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000350 /* MJPropertyType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000069F0 /* NSObject+MJClass.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000370 /* NSObject+MJClass.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006A00 /* NSObject+MJCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000390 /* NSObject+MJCoding.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006A10 /* NSObject+MJKeyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003B0 /* NSObject+MJKeyValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006A20 /* NSObject+MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003D0 /* NSObject+MJProperty.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006A30 /* NSString+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003F0 /* NSString+MJExtension.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006A80 /* MJExtension-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006A70 /* MJExtension-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006AB0 /* MJExtension-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00006AA0 /* MJExtension-dummy.m */; }; - 46EB2E00006B40 /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000420 /* MASCompositeConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006B50 /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000450 /* MASConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006B60 /* MASConstraintMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000470 /* MASConstraintMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006B70 /* MASLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000490 /* MASLayoutConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006B80 /* MASViewAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000004D0 /* MASViewAttribute.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006B90 /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000004F0 /* MASViewConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006BA0 /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000510 /* NSArray+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006BB0 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000540 /* NSLayoutConstraint+MASDebugAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006BC0 /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000560 /* View+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006BD0 /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000590 /* ViewController+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006BE0 /* MASCompositeConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000410 /* MASCompositeConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006BF0 /* MASConstraint+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000430 /* MASConstraint+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C00 /* MASConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000440 /* MASConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C10 /* MASConstraintMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000460 /* MASConstraintMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C20 /* MASLayoutConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000480 /* MASLayoutConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C30 /* Masonry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004A0 /* Masonry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C40 /* MASUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004B0 /* MASUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C50 /* MASViewAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004C0 /* MASViewAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C60 /* MASViewConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004E0 /* MASViewConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C70 /* NSArray+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000500 /* NSArray+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C80 /* NSArray+MASShorthandAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000520 /* NSArray+MASShorthandAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006C90 /* NSLayoutConstraint+MASDebugAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000530 /* NSLayoutConstraint+MASDebugAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006CA0 /* View+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000550 /* View+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006CB0 /* View+MASShorthandAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000570 /* View+MASShorthandAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006CC0 /* ViewController+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000580 /* ViewController+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006D20 /* Masonry-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006D10 /* Masonry-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00006D50 /* Masonry-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00006D40 /* Masonry-dummy.m */; }; - 46EB2E00006E60 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004740 /* PrivacyInfo.xcprivacy */; }; - 46EB2E00006E90 /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000005C0 /* NSButton+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006EA0 /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000005E0 /* NSData+ImageContentType.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006EB0 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000600 /* NSImage+Compatibility.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006EC0 /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000620 /* SDAnimatedImage.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006ED0 /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000640 /* SDAnimatedImagePlayer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006EE0 /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000660 /* SDAnimatedImageRep.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006EF0 /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000680 /* SDAnimatedImageView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F00 /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006A0 /* SDAnimatedImageView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F10 /* SDCallbackQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006C0 /* SDCallbackQueue.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F20 /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006E0 /* SDDiskCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F30 /* SDGraphicsImageRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000700 /* SDGraphicsImageRenderer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F40 /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000720 /* SDImageAPNGCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F50 /* SDImageAWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000740 /* SDImageAWebPCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F60 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000760 /* SDImageCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F70 /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000780 /* SDImageCacheConfig.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F80 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007A0 /* SDImageCacheDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006F90 /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007C0 /* SDImageCachesManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FA0 /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007E0 /* SDImageCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FB0 /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000800 /* SDImageCoderHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FC0 /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000820 /* SDImageCodersManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FD0 /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000840 /* SDImageFrame.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FE0 /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000860 /* SDImageGIFCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00006FF0 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000880 /* SDImageGraphics.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007000 /* SDImageHEICCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008A0 /* SDImageHEICCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007010 /* SDImageIOAnimatedCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008C0 /* SDImageIOAnimatedCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007020 /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008E0 /* SDImageIOCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007030 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000900 /* SDImageLoader.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007040 /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000920 /* SDImageLoadersManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007050 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000940 /* SDImageTransformer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007060 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000960 /* SDMemoryCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007070 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000980 /* SDWebImageCacheKeyFilter.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007080 /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009A0 /* SDWebImageCacheSerializer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007090 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009C0 /* SDWebImageCompat.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070A0 /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009E0 /* SDWebImageDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070B0 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A00 /* SDWebImageDownloader.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070C0 /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A20 /* SDWebImageDownloaderConfig.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070D0 /* SDWebImageDownloaderDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A40 /* SDWebImageDownloaderDecryptor.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070E0 /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A60 /* SDWebImageDownloaderOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000070F0 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A80 /* SDWebImageDownloaderRequestModifier.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007100 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AA0 /* SDWebImageDownloaderResponseModifier.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007110 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AC0 /* SDWebImageError.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007120 /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AE0 /* SDWebImageIndicator.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007130 /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B00 /* SDWebImageManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007140 /* SDWebImageOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B20 /* SDWebImageOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007150 /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B40 /* SDWebImageOptionsProcessor.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007160 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B60 /* SDWebImagePrefetcher.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007170 /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B80 /* SDWebImageTransition.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007180 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BA0 /* UIButton+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007190 /* UIImage+ExtendedCacheData.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BC0 /* UIImage+ExtendedCacheData.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071A0 /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BE0 /* UIImage+ForceDecode.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071B0 /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C00 /* UIImage+GIF.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071C0 /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C20 /* UIImage+MemoryCacheCost.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071D0 /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C40 /* UIImage+Metadata.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071E0 /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C60 /* UIImage+MultiFormat.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000071F0 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C80 /* UIImage+Transform.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007200 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CA0 /* UIImageView+HighlightedWebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007210 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CC0 /* UIImageView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007220 /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CE0 /* UIView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007230 /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D00 /* UIView+WebCacheOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007240 /* UIView+WebCacheState.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D20 /* UIView+WebCacheState.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007250 /* NSBezierPath+SDRoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D50 /* NSBezierPath+SDRoundedCorners.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007260 /* SDAssociatedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D70 /* SDAssociatedObject.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007270 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D90 /* SDAsyncBlockOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007280 /* SDDeviceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DB0 /* SDDeviceHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007290 /* SDDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DD0 /* SDDisplayLink.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072A0 /* SDFileAttributeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DF0 /* SDFileAttributeHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072B0 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E10 /* SDImageAssetManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072C0 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E30 /* SDImageCachesManagerOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072D0 /* SDImageFramePool.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E50 /* SDImageFramePool.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072E0 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E80 /* SDInternalMacros.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000072F0 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EB0 /* SDWeakProxy.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007300 /* UIColor+SDHexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EE0 /* UIColor+SDHexString.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007310 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005B0 /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007320 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005D0 /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007330 /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005F0 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007340 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000610 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007350 /* SDAnimatedImagePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000630 /* SDAnimatedImagePlayer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007360 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000650 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007370 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000670 /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007380 /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000690 /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007390 /* SDCallbackQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006B0 /* SDCallbackQueue.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073A0 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006D0 /* SDDiskCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073B0 /* SDGraphicsImageRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006F0 /* SDGraphicsImageRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073C0 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000710 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073D0 /* SDImageAWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000730 /* SDImageAWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073E0 /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000750 /* SDImageCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000073F0 /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000770 /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007400 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000790 /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007410 /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007B0 /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007420 /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007D0 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007430 /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007F0 /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007440 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000810 /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007450 /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000830 /* SDImageFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007460 /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000850 /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007470 /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000870 /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007480 /* SDImageHEICCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000890 /* SDImageHEICCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007490 /* SDImageIOAnimatedCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008B0 /* SDImageIOAnimatedCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074A0 /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008D0 /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074B0 /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008F0 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074C0 /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000910 /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074D0 /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000930 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074E0 /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000950 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000074F0 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000970 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007500 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000990 /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007510 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009B0 /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007520 /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009D0 /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007530 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009F0 /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007540 /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A10 /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007550 /* SDWebImageDownloaderDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A30 /* SDWebImageDownloaderDecryptor.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007560 /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A50 /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007570 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A70 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007580 /* SDWebImageDownloaderResponseModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A90 /* SDWebImageDownloaderResponseModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007590 /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AB0 /* SDWebImageError.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075A0 /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AD0 /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075B0 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AF0 /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075C0 /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B10 /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075D0 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B30 /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075E0 /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B50 /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000075F0 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B70 /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007600 /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B90 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007610 /* UIImage+ExtendedCacheData.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BB0 /* UIImage+ExtendedCacheData.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007620 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BD0 /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007630 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BF0 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007640 /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C10 /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007650 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C30 /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007660 /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C50 /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007670 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C70 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007680 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C90 /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007690 /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CB0 /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076A0 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CD0 /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076B0 /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CF0 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076C0 /* UIView+WebCacheState.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D10 /* UIView+WebCacheState.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076D0 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D30 /* SDWebImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076E0 /* NSBezierPath+SDRoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D40 /* NSBezierPath+SDRoundedCorners.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000076F0 /* SDAssociatedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D60 /* SDAssociatedObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007700 /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D80 /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007710 /* SDDeviceHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DA0 /* SDDeviceHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007720 /* SDDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DC0 /* SDDisplayLink.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007730 /* SDFileAttributeHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DE0 /* SDFileAttributeHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007740 /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E00 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007750 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E20 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007760 /* SDImageFramePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E40 /* SDImageFramePool.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007770 /* SDImageIOAnimatedCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E60 /* SDImageIOAnimatedCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007780 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E70 /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007790 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E90 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000077A0 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EA0 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000077B0 /* SDWebImageTransitionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EC0 /* SDWebImageTransitionInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000077C0 /* UIColor+SDHexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000ED0 /* UIColor+SDHexString.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007810 /* SDWebImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00007800 /* SDWebImage-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007840 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00007830 /* SDWebImage-dummy.m */; }; - 46EB2E000078D0 /* SDImageWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F00 /* SDImageWebPCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000078E0 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F20 /* SDWebImageWebPCoderDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000078F0 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F40 /* UIImage+WebP.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00007900 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EF0 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007910 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F10 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007920 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F30 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007930 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F50 /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007940 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F60 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007950 /* SDWebImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F70 /* SDWebImageWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000079C0 /* SDWebImageWebPCoder-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000079B0 /* SDWebImageWebPCoder-dummy.m */; }; - 46EB2E00007AD0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E000047A0 /* PrivacyInfo.xcprivacy */; }; - 46EB2E00007B00 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003070 /* Constraint.swift */; }; - 46EB2E00007B10 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003080 /* ConstraintAttributes.swift */; }; - 46EB2E00007B20 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003090 /* ConstraintConfig.swift */; }; - 46EB2E00007B30 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030A0 /* ConstraintConstantTarget.swift */; }; - 46EB2E00007B40 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030B0 /* ConstraintDescription.swift */; }; - 46EB2E00007B50 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030C0 /* ConstraintDirectionalInsets.swift */; }; - 46EB2E00007B60 /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030D0 /* ConstraintDirectionalInsetTarget.swift */; }; - 46EB2E00007B70 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030E0 /* ConstraintDSL.swift */; }; - 46EB2E00007B80 /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030F0 /* ConstraintInsets.swift */; }; - 46EB2E00007B90 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003100 /* ConstraintInsetTarget.swift */; }; - 46EB2E00007BA0 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003110 /* ConstraintItem.swift */; }; - 46EB2E00007BB0 /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003120 /* ConstraintLayoutGuide+Extensions.swift */; }; - 46EB2E00007BC0 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003130 /* ConstraintLayoutGuide.swift */; }; - 46EB2E00007BD0 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003140 /* ConstraintLayoutGuideDSL.swift */; }; - 46EB2E00007BE0 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003150 /* ConstraintLayoutSupport.swift */; }; - 46EB2E00007BF0 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003160 /* ConstraintLayoutSupportDSL.swift */; }; - 46EB2E00007C00 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003170 /* ConstraintMaker.swift */; }; - 46EB2E00007C10 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003180 /* ConstraintMakerEditable.swift */; }; - 46EB2E00007C20 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003190 /* ConstraintMakerExtendable.swift */; }; - 46EB2E00007C30 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031A0 /* ConstraintMakerFinalizable.swift */; }; - 46EB2E00007C40 /* ConstraintMakerPrioritizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031B0 /* ConstraintMakerPrioritizable.swift */; }; - 46EB2E00007C50 /* ConstraintMakerRelatable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031C0 /* ConstraintMakerRelatable+Extensions.swift */; }; - 46EB2E00007C60 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031D0 /* ConstraintMakerRelatable.swift */; }; - 46EB2E00007C70 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031E0 /* ConstraintMultiplierTarget.swift */; }; - 46EB2E00007C80 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031F0 /* ConstraintOffsetTarget.swift */; }; - 46EB2E00007C90 /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003200 /* ConstraintPriority.swift */; }; - 46EB2E00007CA0 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003210 /* ConstraintPriorityTarget.swift */; }; - 46EB2E00007CB0 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003220 /* ConstraintRelatableTarget.swift */; }; - 46EB2E00007CC0 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003230 /* ConstraintRelation.swift */; }; - 46EB2E00007CD0 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003240 /* ConstraintView+Extensions.swift */; }; - 46EB2E00007CE0 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003250 /* ConstraintView.swift */; }; - 46EB2E00007CF0 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003260 /* ConstraintViewDSL.swift */; }; - 46EB2E00007D00 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003270 /* Debugging.swift */; }; - 46EB2E00007D10 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003280 /* LayoutConstraint.swift */; }; - 46EB2E00007D20 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003290 /* LayoutConstraintItem.swift */; }; - 46EB2E00007D30 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032A0 /* Typealiases.swift */; }; - 46EB2E00007D40 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032B0 /* UILayoutSupport+Extensions.swift */; }; - 46EB2E00007D90 /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00007D80 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00007DD0 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00007DC0 /* SnapKit-dummy.m */; }; - 46EB2E00007F50 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E000047C0 /* PrivacyInfo.xcprivacy */; }; - 46EB2E00007F80 /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032C0 /* SwiftyJSON.swift */; }; - 46EB2E00007FD0 /* SwiftyJSON-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00007FC0 /* SwiftyJSON-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008010 /* SwiftyJSON-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00008000 /* SwiftyJSON-dummy.m */; }; - 46EB2E000080A0 /* NSBundle+TZImagePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032F0 /* NSBundle+TZImagePicker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000080B0 /* TZAssetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003310 /* TZAssetCell.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000080C0 /* TZAssetModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003330 /* TZAssetModel.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000080D0 /* TZAuthLimitedFooterTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003350 /* TZAuthLimitedFooterTipView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000080E0 /* TZGifPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003370 /* TZGifPhotoPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000080F0 /* TZImageCropManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003390 /* TZImageCropManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008100 /* TZImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033B0 /* TZImageManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008110 /* TZImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033D0 /* TZImagePickerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008120 /* TZImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033F0 /* TZImageRequestOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008130 /* TZPhotoPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003410 /* TZPhotoPickerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008140 /* TZPhotoPreviewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003430 /* TZPhotoPreviewCell.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008150 /* TZPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003450 /* TZPhotoPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008160 /* TZProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003470 /* TZProgressView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008170 /* TZVideoCropController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003490 /* TZVideoCropController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008180 /* TZVideoEditedPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034B0 /* TZVideoEditedPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008190 /* TZVideoPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034D0 /* TZVideoPlayerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000081A0 /* UIView+TZLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034F0 /* UIView+TZLayout.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000081B0 /* NSBundle+TZImagePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000032E0 /* NSBundle+TZImagePicker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000081C0 /* TZAssetCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003300 /* TZAssetCell.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000081D0 /* TZAssetModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003320 /* TZAssetModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000081E0 /* TZAuthLimitedFooterTipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003340 /* TZAuthLimitedFooterTipView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000081F0 /* TZGifPhotoPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003360 /* TZGifPhotoPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008200 /* TZImageCropManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003380 /* TZImageCropManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008210 /* TZImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033A0 /* TZImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008220 /* TZImagePickerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033C0 /* TZImagePickerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008230 /* TZImageRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033E0 /* TZImageRequestOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008240 /* TZPhotoPickerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003400 /* TZPhotoPickerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008250 /* TZPhotoPreviewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003420 /* TZPhotoPreviewCell.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008260 /* TZPhotoPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003440 /* TZPhotoPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008270 /* TZProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003460 /* TZProgressView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008280 /* TZVideoCropController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003480 /* TZVideoCropController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008290 /* TZVideoEditedPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034A0 /* TZVideoEditedPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000082A0 /* TZVideoPlayerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034C0 /* TZVideoPlayerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000082B0 /* UIView+TZLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034E0 /* UIView+TZLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E000082C0 /* TZLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003520 /* TZLocationManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000082D0 /* TZLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003510 /* TZLocationManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008330 /* TZImagePickerController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00008320 /* TZImagePickerController-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008360 /* TZImagePickerController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00008350 /* TZImagePickerController-dummy.m */; }; - 46EB2E000083F0 /* anim_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F90 /* anim_decode.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008400 /* demux.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FA0 /* demux.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008410 /* demux.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FB0 /* demux.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008420 /* anim_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FE0 /* anim_encode.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008430 /* muxedit.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FF0 /* muxedit.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008440 /* muxinternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001010 /* muxinternal.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008450 /* muxread.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001020 /* muxread.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008460 /* animi.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FD0 /* animi.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008470 /* muxi.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001000 /* muxi.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008480 /* mux.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001030 /* mux.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008490 /* sharpyuv.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001050 /* sharpyuv.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084A0 /* sharpyuv_cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001070 /* sharpyuv_cpu.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084B0 /* sharpyuv_csp.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001090 /* sharpyuv_csp.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084C0 /* sharpyuv_dsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010B0 /* sharpyuv_dsp.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084D0 /* sharpyuv_gamma.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010D0 /* sharpyuv_gamma.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084E0 /* sharpyuv_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010F0 /* sharpyuv_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000084F0 /* sharpyuv_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001100 /* sharpyuv_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008500 /* sharpyuv.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001060 /* sharpyuv.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008510 /* sharpyuv_cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001080 /* sharpyuv_cpu.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008520 /* sharpyuv_csp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010A0 /* sharpyuv_csp.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008530 /* sharpyuv_dsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010C0 /* sharpyuv_dsp.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008540 /* sharpyuv_gamma.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010E0 /* sharpyuv_gamma.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008550 /* bit_reader_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001180 /* bit_reader_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008560 /* bit_writer_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011A0 /* bit_writer_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008570 /* color_cache_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011C0 /* color_cache_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008580 /* filters_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011F0 /* filters_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008590 /* huffman_encode_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001210 /* huffman_encode_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085A0 /* huffman_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001230 /* huffman_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085B0 /* quant_levels_dec_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001250 /* quant_levels_dec_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085C0 /* quant_levels_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001270 /* quant_levels_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085D0 /* random_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001290 /* random_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085E0 /* rescaler_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012B0 /* rescaler_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000085F0 /* thread_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012D0 /* thread_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008600 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012F0 /* utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008610 /* alpha_processing.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001310 /* alpha_processing.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008620 /* alpha_processing_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001320 /* alpha_processing_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008630 /* alpha_processing_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001330 /* alpha_processing_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008640 /* alpha_processing_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001340 /* alpha_processing_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008650 /* alpha_processing_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001350 /* alpha_processing_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008660 /* cost.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001380 /* cost.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008670 /* cost_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001390 /* cost_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008680 /* cost_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013A0 /* cost_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008690 /* cost_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013B0 /* cost_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086A0 /* cost_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013C0 /* cost_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086B0 /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013D0 /* cpu.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086C0 /* dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013F0 /* dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086D0 /* dec_clip_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001400 /* dec_clip_tables.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086E0 /* dec_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001410 /* dec_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000086F0 /* dec_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001420 /* dec_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008700 /* dec_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001430 /* dec_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008710 /* dec_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001440 /* dec_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008720 /* dec_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001450 /* dec_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008730 /* dec_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001460 /* dec_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008740 /* enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001480 /* enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008750 /* enc_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001490 /* enc_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008760 /* enc_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014A0 /* enc_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008770 /* enc_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014B0 /* enc_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008780 /* enc_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014C0 /* enc_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008790 /* enc_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014D0 /* enc_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087A0 /* enc_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014E0 /* enc_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087B0 /* filters.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014F0 /* filters.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087C0 /* filters_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001500 /* filters_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087D0 /* filters_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001510 /* filters_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087E0 /* filters_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001520 /* filters_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000087F0 /* filters_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001530 /* filters_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008800 /* lossless.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001540 /* lossless.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008810 /* lossless_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001570 /* lossless_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008820 /* lossless_enc_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001580 /* lossless_enc_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008830 /* lossless_enc_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001590 /* lossless_enc_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008840 /* lossless_enc_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015A0 /* lossless_enc_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008850 /* lossless_enc_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015B0 /* lossless_enc_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008860 /* lossless_enc_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015C0 /* lossless_enc_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008870 /* lossless_enc_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015D0 /* lossless_enc_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008880 /* lossless_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015E0 /* lossless_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008890 /* lossless_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015F0 /* lossless_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088A0 /* lossless_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001600 /* lossless_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088B0 /* lossless_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001610 /* lossless_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088C0 /* lossless_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001620 /* lossless_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088D0 /* rescaler.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001670 /* rescaler.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088E0 /* rescaler_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001680 /* rescaler_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000088F0 /* rescaler_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001690 /* rescaler_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008900 /* rescaler_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016A0 /* rescaler_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008910 /* rescaler_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016B0 /* rescaler_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008920 /* rescaler_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016C0 /* rescaler_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008930 /* ssim.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016D0 /* ssim.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008940 /* ssim_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016E0 /* ssim_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008950 /* upsampling.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016F0 /* upsampling.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008960 /* upsampling_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001700 /* upsampling_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008970 /* upsampling_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001710 /* upsampling_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008980 /* upsampling_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001720 /* upsampling_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008990 /* upsampling_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001730 /* upsampling_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089A0 /* upsampling_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001740 /* upsampling_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089B0 /* yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001750 /* yuv.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089C0 /* yuv_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001770 /* yuv_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089D0 /* yuv_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001780 /* yuv_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089E0 /* yuv_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001790 /* yuv_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E000089F0 /* yuv_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017A0 /* yuv_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A00 /* yuv_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017B0 /* yuv_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A10 /* alpha_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017D0 /* alpha_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A20 /* buffer_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017E0 /* buffer_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A30 /* frame_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001800 /* frame_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A40 /* idec_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001810 /* idec_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A50 /* io_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001820 /* io_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A60 /* quant_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001830 /* quant_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A70 /* tree_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001840 /* tree_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A80 /* vp8l_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001870 /* vp8l_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008A90 /* vp8_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001880 /* vp8_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AA0 /* webp_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018B0 /* webp_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AB0 /* alpha_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018C0 /* alpha_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AC0 /* analysis_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018D0 /* analysis_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AD0 /* backward_references_cost_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018E0 /* backward_references_cost_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AE0 /* backward_references_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018F0 /* backward_references_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008AF0 /* config_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001910 /* config_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B00 /* cost_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001920 /* cost_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B10 /* filter_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001940 /* filter_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B20 /* frame_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001950 /* frame_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B30 /* histogram_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001960 /* histogram_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B40 /* iterator_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001980 /* iterator_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B50 /* near_lossless_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001990 /* near_lossless_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B60 /* picture_csp_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019A0 /* picture_csp_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B70 /* picture_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019B0 /* picture_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B80 /* picture_psnr_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019C0 /* picture_psnr_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008B90 /* picture_rescale_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019D0 /* picture_rescale_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BA0 /* picture_tools_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019E0 /* picture_tools_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BB0 /* predictor_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019F0 /* predictor_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BC0 /* quant_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A00 /* quant_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BD0 /* syntax_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A10 /* syntax_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BE0 /* token_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A20 /* token_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008BF0 /* tree_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A30 /* tree_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008C00 /* vp8l_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A60 /* vp8l_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008C10 /* webp_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A70 /* webp_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 46EB2E00008C20 /* decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001120 /* decode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C30 /* encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001130 /* encode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C40 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001140 /* types.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C50 /* mux_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001150 /* mux_types.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C60 /* format_constants.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001160 /* format_constants.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C70 /* bit_reader_inl_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001170 /* bit_reader_inl_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C80 /* bit_reader_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001190 /* bit_reader_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008C90 /* bit_writer_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011B0 /* bit_writer_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CA0 /* color_cache_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011D0 /* color_cache_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CB0 /* endian_inl_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011E0 /* endian_inl_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CC0 /* filters_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001200 /* filters_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CD0 /* huffman_encode_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001220 /* huffman_encode_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CE0 /* huffman_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001240 /* huffman_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008CF0 /* quant_levels_dec_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001260 /* quant_levels_dec_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D00 /* quant_levels_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001280 /* quant_levels_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D10 /* random_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012A0 /* random_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D20 /* rescaler_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012C0 /* rescaler_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D30 /* thread_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012E0 /* thread_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D40 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001300 /* utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D50 /* common_sse2.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001360 /* common_sse2.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D60 /* common_sse41.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001370 /* common_sse41.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D70 /* cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000013E0 /* cpu.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D80 /* dsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001470 /* dsp.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008D90 /* lossless.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001550 /* lossless.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DA0 /* lossless_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001560 /* lossless_common.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DB0 /* mips_macro.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001630 /* mips_macro.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DC0 /* msa_macro.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001640 /* msa_macro.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DD0 /* neon.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001650 /* neon.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DE0 /* quant.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001660 /* quant.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008DF0 /* yuv.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001760 /* yuv.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E00 /* alphai_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000017C0 /* alphai_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E10 /* common_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000017F0 /* common_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E20 /* vp8i_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001850 /* vp8i_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E30 /* vp8li_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001860 /* vp8li_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E40 /* vp8_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001890 /* vp8_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E50 /* webpi_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000018A0 /* webpi_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E60 /* backward_references_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001900 /* backward_references_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E70 /* cost_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001930 /* cost_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E80 /* histogram_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001970 /* histogram_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008E90 /* vp8i_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A40 /* vp8i_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008EA0 /* vp8li_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A50 /* vp8li_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008F00 /* libwebp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00008EF0 /* libwebp-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E00008F30 /* libwebp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00008F20 /* libwebp-dummy.m */; }; - 46EB2E00009040 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E000047E0 /* PrivacyInfo.xcprivacy */; }; - 46EB2E00009070 /* CAAnimation+TimingConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003530 /* CAAnimation+TimingConfiguration.swift */; }; - 46EB2E00009080 /* CALayer+addAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003540 /* CALayer+addAnimation.swift */; }; - 46EB2E00009090 /* CombinedShapeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003550 /* CombinedShapeAnimation.swift */; }; - 46EB2E000090A0 /* CustomPathAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003560 /* CustomPathAnimation.swift */; }; - 46EB2E000090B0 /* DropShadowAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003570 /* DropShadowAnimation.swift */; }; - 46EB2E000090C0 /* EllipseAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003580 /* EllipseAnimation.swift */; }; - 46EB2E000090D0 /* GradientAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003590 /* GradientAnimations.swift */; }; - 46EB2E000090E0 /* LayerProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035A0 /* LayerProperty.swift */; }; - 46EB2E000090F0 /* OpacityAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035B0 /* OpacityAnimation.swift */; }; - 46EB2E00009100 /* RectangleAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035C0 /* RectangleAnimation.swift */; }; - 46EB2E00009110 /* ShapeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035D0 /* ShapeAnimation.swift */; }; - 46EB2E00009120 /* StarAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035E0 /* StarAnimation.swift */; }; - 46EB2E00009130 /* StrokeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035F0 /* StrokeAnimation.swift */; }; - 46EB2E00009140 /* TransformAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003600 /* TransformAnimations.swift */; }; - 46EB2E00009150 /* VisibilityAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003610 /* VisibilityAnimation.swift */; }; - 46EB2E00009160 /* CompatibilityTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003620 /* CompatibilityTracker.swift */; }; - 46EB2E00009170 /* CoreAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003630 /* CoreAnimationLayer.swift */; }; - 46EB2E00009180 /* CALayer+fillBounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003640 /* CALayer+fillBounds.swift */; }; - 46EB2E00009190 /* KeyframeGroup+exactlyOneKeyframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003650 /* KeyframeGroup+exactlyOneKeyframe.swift */; }; - 46EB2E000091A0 /* Keyframes+combined.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003660 /* Keyframes+combined.swift */; }; - 46EB2E000091B0 /* Keyframes+timeRemapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003670 /* Keyframes+timeRemapping.swift */; }; - 46EB2E000091C0 /* AnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003680 /* AnimationLayer.swift */; }; - 46EB2E000091D0 /* BaseAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003690 /* BaseAnimationLayer.swift */; }; - 46EB2E000091E0 /* BaseCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036A0 /* BaseCompositionLayer.swift */; }; - 46EB2E000091F0 /* CALayer+setupLayerHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036B0 /* CALayer+setupLayerHierarchy.swift */; }; - 46EB2E00009200 /* GradientRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036C0 /* GradientRenderLayer.swift */; }; - 46EB2E00009210 /* ImageLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036D0 /* ImageLayer.swift */; }; - 46EB2E00009220 /* InfiniteOpaqueAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036E0 /* InfiniteOpaqueAnimationLayer.swift */; }; - 46EB2E00009230 /* LayerModel+makeAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036F0 /* LayerModel+makeAnimationLayer.swift */; }; - 46EB2E00009240 /* MaskCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003700 /* MaskCompositionLayer.swift */; }; - 46EB2E00009250 /* PreCompLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003710 /* PreCompLayer.swift */; }; - 46EB2E00009260 /* RepeaterLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003720 /* RepeaterLayer.swift */; }; - 46EB2E00009270 /* ShapeItemLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003730 /* ShapeItemLayer.swift */; }; - 46EB2E00009280 /* ShapeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003740 /* ShapeLayer.swift */; }; - 46EB2E00009290 /* SolidLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003750 /* SolidLayer.swift */; }; - 46EB2E000092A0 /* TextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003760 /* TextLayer.swift */; }; - 46EB2E000092B0 /* TransformLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003770 /* TransformLayer.swift */; }; - 46EB2E000092C0 /* ValueProviderStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003780 /* ValueProviderStore.swift */; }; - 46EB2E000092D0 /* Collection+Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003790 /* Collection+Diff.swift */; }; - 46EB2E000092E0 /* Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037A0 /* Diffable.swift */; }; - 46EB2E000092F0 /* DiffableSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037B0 /* DiffableSection.swift */; }; - 46EB2E00009300 /* IndexChangeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037C0 /* IndexChangeset.swift */; }; - 46EB2E00009310 /* SectionedChangeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037D0 /* SectionedChangeset.swift */; }; - 46EB2E00009320 /* EpoxyLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037E0 /* EpoxyLogger.swift */; }; - 46EB2E00009330 /* CallbackContextEpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037F0 /* CallbackContextEpoxyModeled.swift */; }; - 46EB2E00009340 /* EpoxyModelArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003800 /* EpoxyModelArrayBuilder.swift */; }; - 46EB2E00009350 /* EpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003810 /* EpoxyModeled.swift */; }; - 46EB2E00009360 /* EpoxyModelProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003820 /* EpoxyModelProperty.swift */; }; - 46EB2E00009370 /* EpoxyModelStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003830 /* EpoxyModelStorage.swift */; }; - 46EB2E00009380 /* AnyEpoxyModelProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003840 /* AnyEpoxyModelProperty.swift */; }; - 46EB2E00009390 /* ClassReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003850 /* ClassReference.swift */; }; - 46EB2E000093A0 /* AnimatedProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003860 /* AnimatedProviding.swift */; }; - 46EB2E000093B0 /* DataIDProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003870 /* DataIDProviding.swift */; }; - 46EB2E000093C0 /* DidDisplayProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003880 /* DidDisplayProviding.swift */; }; - 46EB2E000093D0 /* DidEndDisplayingProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003890 /* DidEndDisplayingProviding.swift */; }; - 46EB2E000093E0 /* DidSelectProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038A0 /* DidSelectProviding.swift */; }; - 46EB2E000093F0 /* ErasedContentProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038B0 /* ErasedContentProviding.swift */; }; - 46EB2E00009400 /* MakeViewProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038C0 /* MakeViewProviding.swift */; }; - 46EB2E00009410 /* SetBehaviorsProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038D0 /* SetBehaviorsProviding.swift */; }; - 46EB2E00009420 /* SetContentProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038E0 /* SetContentProviding.swift */; }; - 46EB2E00009430 /* StyleIDProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038F0 /* StyleIDProviding.swift */; }; - 46EB2E00009440 /* TraitCollectionProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003900 /* TraitCollectionProviding.swift */; }; - 46EB2E00009450 /* ViewDifferentiatorProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003910 /* ViewDifferentiatorProviding.swift */; }; - 46EB2E00009460 /* ViewProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003920 /* ViewProviding.swift */; }; - 46EB2E00009470 /* WillDisplayProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003930 /* WillDisplayProviding.swift */; }; - 46EB2E00009480 /* ViewEpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003940 /* ViewEpoxyModeled.swift */; }; - 46EB2E00009490 /* EpoxyableView+SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003950 /* EpoxyableView+SwiftUIView.swift */; }; - 46EB2E000094A0 /* EpoxySwiftUIHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003960 /* EpoxySwiftUIHostingController.swift */; }; - 46EB2E000094B0 /* EpoxySwiftUIHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003970 /* EpoxySwiftUIHostingView.swift */; }; - 46EB2E000094C0 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003980 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift */; }; - 46EB2E000094D0 /* EpoxySwiftUILayoutMargins.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003990 /* EpoxySwiftUILayoutMargins.swift */; }; - 46EB2E000094E0 /* MeasuringViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039A0 /* MeasuringViewRepresentable.swift */; }; - 46EB2E000094F0 /* SwiftUIMeasurementContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039B0 /* SwiftUIMeasurementContainer.swift */; }; - 46EB2E00009500 /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039C0 /* SwiftUIView.swift */; }; - 46EB2E00009510 /* UIView+SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039D0 /* UIView+SwiftUIView.swift */; }; - 46EB2E00009520 /* UIViewConfiguringSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039E0 /* UIViewConfiguringSwiftUIView.swift */; }; - 46EB2E00009530 /* BehaviorsConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039F0 /* BehaviorsConfigurableView.swift */; }; - 46EB2E00009540 /* ContentConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A00 /* ContentConfigurableView.swift */; }; - 46EB2E00009550 /* EpoxyableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A10 /* EpoxyableView.swift */; }; - 46EB2E00009560 /* StyledView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A20 /* StyledView.swift */; }; - 46EB2E00009570 /* ViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A30 /* ViewType.swift */; }; - 46EB2E00009580 /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A40 /* LRUCache.swift */; }; - 46EB2E00009590 /* Archive+BackingConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A50 /* Archive+BackingConfiguration.swift */; }; - 46EB2E000095A0 /* Archive+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A60 /* Archive+Helpers.swift */; }; - 46EB2E000095B0 /* Archive+MemoryFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A70 /* Archive+MemoryFile.swift */; }; - 46EB2E000095C0 /* Archive+Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A80 /* Archive+Progress.swift */; }; - 46EB2E000095D0 /* Archive+Reading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A90 /* Archive+Reading.swift */; }; - 46EB2E000095E0 /* Archive+ReadingDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AA0 /* Archive+ReadingDeprecated.swift */; }; - 46EB2E000095F0 /* Archive+Writing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AB0 /* Archive+Writing.swift */; }; - 46EB2E00009600 /* Archive+WritingDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AC0 /* Archive+WritingDeprecated.swift */; }; - 46EB2E00009610 /* Archive+ZIP64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AD0 /* Archive+ZIP64.swift */; }; - 46EB2E00009620 /* Archive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AE0 /* Archive.swift */; }; - 46EB2E00009630 /* Data+Compression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AF0 /* Data+Compression.swift */; }; - 46EB2E00009640 /* Data+CompressionDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B00 /* Data+CompressionDeprecated.swift */; }; - 46EB2E00009650 /* Data+Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B10 /* Data+Serialization.swift */; }; - 46EB2E00009660 /* Entry+Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B20 /* Entry+Serialization.swift */; }; - 46EB2E00009670 /* Entry+ZIP64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B30 /* Entry+ZIP64.swift */; }; - 46EB2E00009680 /* Entry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B40 /* Entry.swift */; }; - 46EB2E00009690 /* FileManager+ZIP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B50 /* FileManager+ZIP.swift */; }; - 46EB2E000096A0 /* URL+ZIP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B60 /* URL+ZIP.swift */; }; - 46EB2E000096B0 /* CompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B70 /* CompositionLayer.swift */; }; - 46EB2E000096C0 /* ImageCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B80 /* ImageCompositionLayer.swift */; }; - 46EB2E000096D0 /* MaskContainerLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B90 /* MaskContainerLayer.swift */; }; - 46EB2E000096E0 /* NullCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BA0 /* NullCompositionLayer.swift */; }; - 46EB2E000096F0 /* PreCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BB0 /* PreCompositionLayer.swift */; }; - 46EB2E00009700 /* ShapeCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BC0 /* ShapeCompositionLayer.swift */; }; - 46EB2E00009710 /* SolidCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BD0 /* SolidCompositionLayer.swift */; }; - 46EB2E00009720 /* TextCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BE0 /* TextCompositionLayer.swift */; }; - 46EB2E00009730 /* MainThreadAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BF0 /* MainThreadAnimationLayer.swift */; }; - 46EB2E00009740 /* CachedImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C00 /* CachedImageProvider.swift */; }; - 46EB2E00009750 /* CompositionLayersInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C10 /* CompositionLayersInitializer.swift */; }; - 46EB2E00009760 /* CoreTextRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C20 /* CoreTextRenderLayer.swift */; }; - 46EB2E00009770 /* InvertedMatteLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C30 /* InvertedMatteLayer.swift */; }; - 46EB2E00009780 /* LayerFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C40 /* LayerFontProvider.swift */; }; - 46EB2E00009790 /* LayerImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C50 /* LayerImageProvider.swift */; }; - 46EB2E000097A0 /* LayerTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C60 /* LayerTextProvider.swift */; }; - 46EB2E000097B0 /* LayerTransformNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C70 /* LayerTransformNode.swift */; }; - 46EB2E000097C0 /* ItemsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C80 /* ItemsExtension.swift */; }; - 46EB2E000097D0 /* NodeProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C90 /* NodeProperty.swift */; }; - 46EB2E000097E0 /* AnyNodeProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CA0 /* AnyNodeProperty.swift */; }; - 46EB2E000097F0 /* AnyValueContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CB0 /* AnyValueContainer.swift */; }; - 46EB2E00009800 /* KeypathSearchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CC0 /* KeypathSearchable.swift */; }; - 46EB2E00009810 /* NodePropertyMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CD0 /* NodePropertyMap.swift */; }; - 46EB2E00009820 /* ValueContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CE0 /* ValueContainer.swift */; }; - 46EB2E00009830 /* GroupInterpolator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CF0 /* GroupInterpolator.swift */; }; - 46EB2E00009840 /* SingleValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D00 /* SingleValueProvider.swift */; }; - 46EB2E00009850 /* RoundedCornersNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D10 /* RoundedCornersNode.swift */; }; - 46EB2E00009860 /* TrimPathNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D20 /* TrimPathNode.swift */; }; - 46EB2E00009870 /* GroupOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D30 /* GroupOutputNode.swift */; }; - 46EB2E00009880 /* PassThroughOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D40 /* PassThroughOutputNode.swift */; }; - 46EB2E00009890 /* PathOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D50 /* PathOutputNode.swift */; }; - 46EB2E000098A0 /* FillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D60 /* FillRenderer.swift */; }; - 46EB2E000098B0 /* GradientFillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D70 /* GradientFillRenderer.swift */; }; - 46EB2E000098C0 /* GradientStrokeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D80 /* GradientStrokeRenderer.swift */; }; - 46EB2E000098D0 /* LegacyGradientFillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D90 /* LegacyGradientFillRenderer.swift */; }; - 46EB2E000098E0 /* StrokeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DA0 /* StrokeRenderer.swift */; }; - 46EB2E000098F0 /* EllipseNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DB0 /* EllipseNode.swift */; }; - 46EB2E00009900 /* PolygonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DC0 /* PolygonNode.swift */; }; - 46EB2E00009910 /* RectNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DD0 /* RectNode.swift */; }; - 46EB2E00009920 /* ShapeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DE0 /* ShapeNode.swift */; }; - 46EB2E00009930 /* StarNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DF0 /* StarNode.swift */; }; - 46EB2E00009940 /* GroupNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E00 /* GroupNode.swift */; }; - 46EB2E00009950 /* FillNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E10 /* FillNode.swift */; }; - 46EB2E00009960 /* GradientFillNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E20 /* GradientFillNode.swift */; }; - 46EB2E00009970 /* GradientStrokeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E30 /* GradientStrokeNode.swift */; }; - 46EB2E00009980 /* StrokeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E40 /* StrokeNode.swift */; }; - 46EB2E00009990 /* TextAnimatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E50 /* TextAnimatorNode.swift */; }; - 46EB2E000099A0 /* AnimatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E60 /* AnimatorNode.swift */; }; - 46EB2E000099B0 /* PathNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E70 /* PathNode.swift */; }; - 46EB2E000099C0 /* RenderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E80 /* RenderNode.swift */; }; - 46EB2E000099D0 /* ShapeContainerLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E90 /* ShapeContainerLayer.swift */; }; - 46EB2E000099E0 /* ShapeRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EA0 /* ShapeRenderLayer.swift */; }; - 46EB2E000099F0 /* Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EB0 /* Asset.swift */; }; - 46EB2E00009A00 /* AssetLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EC0 /* AssetLibrary.swift */; }; - 46EB2E00009A10 /* ImageAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003ED0 /* ImageAsset.swift */; }; - 46EB2E00009A20 /* PrecompAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EE0 /* PrecompAsset.swift */; }; - 46EB2E00009A30 /* DictionaryInitializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EF0 /* DictionaryInitializable.swift */; }; - 46EB2E00009A40 /* DotLottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F00 /* DotLottieAnimation.swift */; }; - 46EB2E00009A50 /* DotLottieImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F10 /* DotLottieImageProvider.swift */; }; - 46EB2E00009A60 /* DotLottieManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F20 /* DotLottieManifest.swift */; }; - 46EB2E00009A70 /* DotLottieUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F30 /* DotLottieUtils.swift */; }; - 46EB2E00009A80 /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F40 /* Bundle.swift */; }; - 46EB2E00009A90 /* KeyedDecodingContainerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F50 /* KeyedDecodingContainerExtensions.swift */; }; - 46EB2E00009AA0 /* KeyframeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F60 /* KeyframeData.swift */; }; - 46EB2E00009AB0 /* KeyframeGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F70 /* KeyframeGroup.swift */; }; - 46EB2E00009AC0 /* DropShadowEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F80 /* DropShadowEffect.swift */; }; - 46EB2E00009AD0 /* ColorEffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F90 /* ColorEffectValue.swift */; }; - 46EB2E00009AE0 /* EffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FA0 /* EffectValue.swift */; }; - 46EB2E00009AF0 /* Vector1DEffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FB0 /* Vector1DEffectValue.swift */; }; - 46EB2E00009B00 /* LayerEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FC0 /* LayerEffect.swift */; }; - 46EB2E00009B10 /* ImageLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FD0 /* ImageLayerModel.swift */; }; - 46EB2E00009B20 /* LayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FE0 /* LayerModel.swift */; }; - 46EB2E00009B30 /* PreCompLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FF0 /* PreCompLayerModel.swift */; }; - 46EB2E00009B40 /* ShapeLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004000 /* ShapeLayerModel.swift */; }; - 46EB2E00009B50 /* SolidLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004010 /* SolidLayerModel.swift */; }; - 46EB2E00009B60 /* TextLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004020 /* TextLayerModel.swift */; }; - 46EB2E00009B70 /* DropShadowStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004030 /* DropShadowStyle.swift */; }; - 46EB2E00009B80 /* LayerStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004040 /* LayerStyle.swift */; }; - 46EB2E00009B90 /* DashPattern.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004050 /* DashPattern.swift */; }; - 46EB2E00009BA0 /* Marker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004060 /* Marker.swift */; }; - 46EB2E00009BB0 /* Mask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004070 /* Mask.swift */; }; - 46EB2E00009BC0 /* Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004080 /* Transform.swift */; }; - 46EB2E00009BD0 /* Ellipse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004090 /* Ellipse.swift */; }; - 46EB2E00009BE0 /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040A0 /* Fill.swift */; }; - 46EB2E00009BF0 /* GradientFill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040B0 /* GradientFill.swift */; }; - 46EB2E00009C00 /* GradientStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040C0 /* GradientStroke.swift */; }; - 46EB2E00009C10 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040D0 /* Group.swift */; }; - 46EB2E00009C20 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040E0 /* Merge.swift */; }; - 46EB2E00009C30 /* Rectangle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040F0 /* Rectangle.swift */; }; - 46EB2E00009C40 /* Repeater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004100 /* Repeater.swift */; }; - 46EB2E00009C50 /* RoundedCorners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004110 /* RoundedCorners.swift */; }; - 46EB2E00009C60 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004120 /* Shape.swift */; }; - 46EB2E00009C70 /* ShapeItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004130 /* ShapeItem.swift */; }; - 46EB2E00009C80 /* ShapeTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004140 /* ShapeTransform.swift */; }; - 46EB2E00009C90 /* Star.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004150 /* Star.swift */; }; - 46EB2E00009CA0 /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004160 /* Stroke.swift */; }; - 46EB2E00009CB0 /* Trim.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004170 /* Trim.swift */; }; - 46EB2E00009CC0 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004180 /* Font.swift */; }; - 46EB2E00009CD0 /* Glyph.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004190 /* Glyph.swift */; }; - 46EB2E00009CE0 /* TextAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041A0 /* TextAnimator.swift */; }; - 46EB2E00009CF0 /* TextDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041B0 /* TextDocument.swift */; }; - 46EB2E00009D00 /* RootAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041C0 /* RootAnimationLayer.swift */; }; - 46EB2E00009D10 /* AnimatorNodeDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041D0 /* AnimatorNodeDebugging.swift */; }; - 46EB2E00009D20 /* LayerDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041E0 /* LayerDebugging.swift */; }; - 46EB2E00009D30 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041F0 /* TestHelpers.swift */; }; - 46EB2E00009D40 /* AnimationKeypathExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004200 /* AnimationKeypathExtension.swift */; }; - 46EB2E00009D50 /* BlendMode+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004210 /* BlendMode+Filter.swift */; }; - 46EB2E00009D60 /* CGColor+RGB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004220 /* CGColor+RGB.swift */; }; - 46EB2E00009D70 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004230 /* CGFloatExtensions.swift */; }; - 46EB2E00009D80 /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004240 /* DataExtension.swift */; }; - 46EB2E00009D90 /* MathKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004250 /* MathKit.swift */; }; - 46EB2E00009DA0 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004260 /* StringExtensions.swift */; }; - 46EB2E00009DB0 /* AnimationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004270 /* AnimationContext.swift */; }; - 46EB2E00009DC0 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004280 /* AnyEquatable.swift */; }; - 46EB2E00009DD0 /* Binding+Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004290 /* Binding+Map.swift */; }; - 46EB2E00009DE0 /* View+ValueChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042A0 /* View+ValueChanged.swift */; }; - 46EB2E00009DF0 /* InterpolatableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042B0 /* InterpolatableExtensions.swift */; }; - 46EB2E00009E00 /* KeyframeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042C0 /* KeyframeExtensions.swift */; }; - 46EB2E00009E10 /* KeyframeInterpolator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042D0 /* KeyframeInterpolator.swift */; }; - 46EB2E00009E20 /* LottieAnimationSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042E0 /* LottieAnimationSource.swift */; }; - 46EB2E00009E30 /* BezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042F0 /* BezierPath.swift */; }; - 46EB2E00009E40 /* BezierPathRoundExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004300 /* BezierPathRoundExtension.swift */; }; - 46EB2E00009E50 /* CGPointExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004310 /* CGPointExtension.swift */; }; - 46EB2E00009E60 /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004320 /* ColorExtension.swift */; }; - 46EB2E00009E70 /* CompoundBezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004330 /* CompoundBezierPath.swift */; }; - 46EB2E00009E80 /* CurveVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004340 /* CurveVertex.swift */; }; - 46EB2E00009E90 /* PathElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004350 /* PathElement.swift */; }; - 46EB2E00009EA0 /* UnitBezier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004360 /* UnitBezier.swift */; }; - 46EB2E00009EB0 /* VectorsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004370 /* VectorsExtensions.swift */; }; - 46EB2E00009EC0 /* LottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004380 /* LottieAnimation.swift */; }; - 46EB2E00009ED0 /* LottieAnimationHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004390 /* LottieAnimationHelpers.swift */; }; - 46EB2E00009EE0 /* LottieAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043A0 /* LottieAnimationLayer.swift */; }; - 46EB2E00009EF0 /* LottieAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043B0 /* LottieAnimationView.swift */; }; - 46EB2E00009F00 /* LottieAnimationViewInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043C0 /* LottieAnimationViewInitializers.swift */; }; - 46EB2E00009F10 /* LottiePlaybackMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043D0 /* LottiePlaybackMode.swift */; }; - 46EB2E00009F20 /* LottieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043E0 /* LottieView.swift */; }; - 46EB2E00009F30 /* AnimationCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043F0 /* AnimationCacheProvider.swift */; }; - 46EB2E00009F40 /* DefaultAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004400 /* DefaultAnimationCache.swift */; }; - 46EB2E00009F50 /* LottieAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004410 /* LottieAnimationCache.swift */; }; - 46EB2E00009F60 /* LRUAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004420 /* LRUAnimationCache.swift */; }; - 46EB2E00009F70 /* DecodingStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004430 /* DecodingStrategy.swift */; }; - 46EB2E00009F80 /* LottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004440 /* LottieConfiguration.swift */; }; - 46EB2E00009F90 /* ReducedMotionOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004450 /* ReducedMotionOption.swift */; }; - 46EB2E00009FA0 /* RenderingEngineOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004460 /* RenderingEngineOption.swift */; }; - 46EB2E00009FB0 /* AnimatedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004470 /* AnimatedButton.swift */; }; - 46EB2E00009FC0 /* AnimatedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004480 /* AnimatedControl.swift */; }; - 46EB2E00009FD0 /* AnimatedSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004490 /* AnimatedSwitch.swift */; }; - 46EB2E00009FE0 /* LottieButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044A0 /* LottieButton.swift */; }; - 46EB2E00009FF0 /* LottieSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044B0 /* LottieSwitch.swift */; }; - 46EB2E0000A000 /* LottieViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044C0 /* LottieViewType.swift */; }; - 46EB2E0000A010 /* DotLottieCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044D0 /* DotLottieCache.swift */; }; - 46EB2E0000A020 /* DotLottieCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044E0 /* DotLottieCacheProvider.swift */; }; - 46EB2E0000A030 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044F0 /* DotLottieConfiguration.swift */; }; - 46EB2E0000A040 /* DotLottieFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004500 /* DotLottieFile.swift */; }; - 46EB2E0000A050 /* DotLottieFileHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004510 /* DotLottieFileHelpers.swift */; }; - 46EB2E0000A060 /* AnimationKeypath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004520 /* AnimationKeypath.swift */; }; - 46EB2E0000A070 /* AnyValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004530 /* AnyValueProvider.swift */; }; - 46EB2E0000A080 /* ColorValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004540 /* ColorValueProvider.swift */; }; - 46EB2E0000A090 /* FloatValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004550 /* FloatValueProvider.swift */; }; - 46EB2E0000A0A0 /* GradientValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004560 /* GradientValueProvider.swift */; }; - 46EB2E0000A0B0 /* PointValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004570 /* PointValueProvider.swift */; }; - 46EB2E0000A0C0 /* SizeValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004580 /* SizeValueProvider.swift */; }; - 46EB2E0000A0D0 /* AnimationFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004590 /* AnimationFontProvider.swift */; }; - 46EB2E0000A0E0 /* AnimationImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045A0 /* AnimationImageProvider.swift */; }; - 46EB2E0000A0F0 /* AnimationSubview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045B0 /* AnimationSubview.swift */; }; - 46EB2E0000A100 /* BundleImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045C0 /* BundleImageProvider.swift */; }; - 46EB2E0000A110 /* CompatibleAnimationKeypath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045D0 /* CompatibleAnimationKeypath.swift */; }; - 46EB2E0000A120 /* CompatibleAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045E0 /* CompatibleAnimationView.swift */; }; - 46EB2E0000A130 /* FilepathImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045F0 /* FilepathImageProvider.swift */; }; - 46EB2E0000A140 /* LottieAnimationViewBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004600 /* LottieAnimationViewBase.swift */; }; - 46EB2E0000A150 /* UIColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004610 /* UIColorExtension.swift */; }; - 46EB2E0000A160 /* Interpolatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004620 /* Interpolatable.swift */; }; - 46EB2E0000A170 /* Keyframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004630 /* Keyframe.swift */; }; - 46EB2E0000A180 /* LottieLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004640 /* LottieLogger.swift */; }; - 46EB2E0000A190 /* AnimationTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004650 /* AnimationTime.swift */; }; - 46EB2E0000A1A0 /* LottieColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004660 /* LottieColor.swift */; }; - 46EB2E0000A1B0 /* Vectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004670 /* Vectors.swift */; }; - 46EB2E0000A1C0 /* AnimationTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004680 /* AnimationTextProvider.swift */; }; - 46EB2E0000A210 /* lottie-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A200 /* lottie-ios-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E0000A250 /* lottie-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A240 /* lottie-ios-dummy.m */; }; - 46EB2E0000A350 /* Pods-CLDemo-OC-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A340 /* Pods-CLDemo-OC-dummy.m */; }; - 46EB2E0000A430 /* Pods-CLDemo-Swift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A420 /* Pods-CLDemo-Swift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 46EB2E0000A480 /* Pods-CLDemo-Swift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A470 /* Pods-CLDemo-Swift-dummy.m */; }; + 46EB2E00004830 /* CLCameraController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A80 /* CLCameraController.swift */; }; + 46EB2E00004840 /* CLCameraImagePreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A90 /* CLCameraImagePreviewController.swift */; }; + 46EB2E00004850 /* CLCameraVideoPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AA0 /* CLCameraVideoPreviewController.swift */; }; + 46EB2E00004860 /* AVCaptureDevice+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AB0 /* AVCaptureDevice+Extension.swift */; }; + 46EB2E00004870 /* AVCapturePhoto+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AC0 /* AVCapturePhoto+Extension.swift */; }; + 46EB2E00004880 /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AD0 /* UIImage+Extension.swift */; }; + 46EB2E00004890 /* CLCameraConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AE0 /* CLCameraConfig.swift */; }; + 46EB2E000048A0 /* CLCameraEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001AF0 /* CLCameraEnum.swift */; }; + 46EB2E000048B0 /* CLCameraError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B00 /* CLCameraError.swift */; }; + 46EB2E000048C0 /* CLCameraHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B10 /* CLCameraHelper.swift */; }; + 46EB2E000048D0 /* CLCameraOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B20 /* CLCameraOrientation.swift */; }; + 46EB2E000048E0 /* CLPermissionInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B30 /* CLPermissionInterface.swift */; }; + 46EB2E000048F0 /* CLPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B40 /* CLPermissions.swift */; }; + 46EB2E00004900 /* CLCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B50 /* CLCameraButton.swift */; }; + 46EB2E00004910 /* CLCameraControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B60 /* CLCameraControlView.swift */; }; + 46EB2E00004920 /* CLCameraPreviewToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B70 /* CLCameraPreviewToolBar.swift */; }; + 46EB2E00004930 /* CLLoadingHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B80 /* CLLoadingHUD.swift */; }; + 46EB2E00004940 /* CLLoadingHUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001B90 /* CLLoadingHUDView.swift */; }; + 46EB2E00004950 /* CLLoadingProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BA0 /* CLLoadingProgressView.swift */; }; + 46EB2E000049B0 /* CLCamera-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000049A0 /* CLCamera-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000049F0 /* CLCamera-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000049E0 /* CLCamera-dummy.m */; }; + 46EB2E00004A80 /* CLPopoverConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BB0 /* CLPopoverConfig.swift */; }; + 46EB2E00004A90 /* CLPopoverController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BC0 /* CLPopoverController.swift */; }; + 46EB2E00004AA0 /* CLPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BD0 /* CLPopoverManager.swift */; }; + 46EB2E00004AB0 /* CLPopoverProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BE0 /* CLPopoverProtocol.swift */; }; + 46EB2E00004AC0 /* CLPopoverWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001BF0 /* CLPopoverWindow.swift */; }; + 46EB2E00004B20 /* CLPopoverManager-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00004B10 /* CLPopoverManager-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00004B60 /* CLPopoverManager-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004B50 /* CLPopoverManager-dummy.m */; }; + 46EB2E00004C70 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004740 /* PrivacyInfo.xcprivacy */; }; + 46EB2E00004CA0 /* AEAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C00 /* AEAD.swift */; }; + 46EB2E00004CB0 /* AEADChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C10 /* AEADChaCha20Poly1305.swift */; }; + 46EB2E00004CC0 /* AEADXChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C20 /* AEADXChaCha20Poly1305.swift */; }; + 46EB2E00004CD0 /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C30 /* AES.Cryptors.swift */; }; + 46EB2E00004CE0 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C40 /* AES.swift */; }; + 46EB2E00004CF0 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C50 /* Array+Extension.swift */; }; + 46EB2E00004D00 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C60 /* ASN1.swift */; }; + 46EB2E00004D10 /* ASN1Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C70 /* ASN1Decoder.swift */; }; + 46EB2E00004D20 /* ASN1Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C80 /* ASN1Encoder.swift */; }; + 46EB2E00004D30 /* ASN1Scanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001C90 /* ASN1Scanner.swift */; }; + 46EB2E00004D40 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CA0 /* Authenticator.swift */; }; + 46EB2E00004D50 /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CB0 /* BatchedCollection.swift */; }; + 46EB2E00004D60 /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CC0 /* Bit.swift */; }; + 46EB2E00004D70 /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CD0 /* BlockCipher.swift */; }; + 46EB2E00004D80 /* BlockDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CE0 /* BlockDecryptor.swift */; }; + 46EB2E00004D90 /* BlockEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001CF0 /* BlockEncryptor.swift */; }; + 46EB2E00004DA0 /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D00 /* BlockMode.swift */; }; + 46EB2E00004DB0 /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D10 /* BlockModeOptions.swift */; }; + 46EB2E00004DC0 /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D20 /* CBC.swift */; }; + 46EB2E00004DD0 /* CCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D30 /* CCM.swift */; }; + 46EB2E00004DE0 /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D40 /* CFB.swift */; }; + 46EB2E00004DF0 /* CipherModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D50 /* CipherModeWorker.swift */; }; + 46EB2E00004E00 /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D60 /* CTR.swift */; }; + 46EB2E00004E10 /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D70 /* ECB.swift */; }; + 46EB2E00004E20 /* GCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D80 /* GCM.swift */; }; + 46EB2E00004E30 /* OCB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001D90 /* OCB.swift */; }; + 46EB2E00004E40 /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DA0 /* OFB.swift */; }; + 46EB2E00004E50 /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DB0 /* PCBC.swift */; }; + 46EB2E00004E60 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DC0 /* Blowfish.swift */; }; + 46EB2E00004E70 /* CBCMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DD0 /* CBCMAC.swift */; }; + 46EB2E00004E80 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DE0 /* ChaCha20.swift */; }; + 46EB2E00004E90 /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001DF0 /* Checksum.swift */; }; + 46EB2E00004EA0 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E00 /* Cipher.swift */; }; + 46EB2E00004EB0 /* CMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E10 /* CMAC.swift */; }; + 46EB2E00004EC0 /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E20 /* Collection+Extension.swift */; }; + 46EB2E00004ED0 /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E30 /* CompactMap.swift */; }; + 46EB2E00004EE0 /* Cryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E40 /* Cryptor.swift */; }; + 46EB2E00004EF0 /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E50 /* Cryptors.swift */; }; + 46EB2E00004F00 /* Addition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E60 /* Addition.swift */; }; + 46EB2E00004F10 /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E70 /* BigInt.swift */; }; + 46EB2E00004F20 /* BigUInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E80 /* BigUInt.swift */; }; + 46EB2E00004F30 /* BitwiseOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001E90 /* BitwiseOps.swift */; }; + 46EB2E00004F40 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EA0 /* Codable.swift */; }; + 46EB2E00004F50 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EB0 /* Comparable.swift */; }; + 46EB2E00004F60 /* CS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EC0 /* CS.swift */; }; + 46EB2E00004F70 /* DataConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001ED0 /* DataConversion.swift */; }; + 46EB2E00004F80 /* Division.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EE0 /* Division.swift */; }; + 46EB2E00004F90 /* Exponentiation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001EF0 /* Exponentiation.swift */; }; + 46EB2E00004FA0 /* FloatingPointConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F00 /* FloatingPointConversion.swift */; }; + 46EB2E00004FB0 /* GCD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F10 /* GCD.swift */; }; + 46EB2E00004FC0 /* Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F20 /* Hashable.swift */; }; + 46EB2E00004FD0 /* IntegerConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F30 /* IntegerConversion.swift */; }; + 46EB2E00004FE0 /* Multiplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F40 /* Multiplication.swift */; }; + 46EB2E00004FF0 /* PrimeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F50 /* PrimeTest.swift */; }; + 46EB2E00005000 /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F60 /* Random.swift */; }; + 46EB2E00005010 /* Shifts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F70 /* Shifts.swift */; }; + 46EB2E00005020 /* SquareRoot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F80 /* SquareRoot.swift */; }; + 46EB2E00005030 /* Strideable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001F90 /* Strideable.swift */; }; + 46EB2E00005040 /* StringConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FA0 /* StringConversion.swift */; }; + 46EB2E00005050 /* Subtraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FB0 /* Subtraction.swift */; }; + 46EB2E00005060 /* WordsAndBits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FC0 /* WordsAndBits.swift */; }; + 46EB2E00005070 /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FD0 /* Digest.swift */; }; + 46EB2E00005080 /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FE0 /* DigestType.swift */; }; + 46EB2E00005090 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001FF0 /* AES+Foundation.swift */; }; + 46EB2E000050A0 /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002000 /* Array+Foundation.swift */; }; + 46EB2E000050B0 /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002010 /* Blowfish+Foundation.swift */; }; + 46EB2E000050C0 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002020 /* ChaCha20+Foundation.swift */; }; + 46EB2E000050D0 /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002030 /* Data+Extension.swift */; }; + 46EB2E000050E0 /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002040 /* HMAC+Foundation.swift */; }; + 46EB2E000050F0 /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002050 /* Rabbit+Foundation.swift */; }; + 46EB2E00005100 /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002060 /* String+FoundationExtension.swift */; }; + 46EB2E00005110 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002070 /* Utils+Foundation.swift */; }; + 46EB2E00005120 /* XChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002080 /* XChaCha20+Foundation.swift */; }; + 46EB2E00005130 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002090 /* Generics.swift */; }; + 46EB2E00005140 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020A0 /* HKDF.swift */; }; + 46EB2E00005150 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020B0 /* HMAC.swift */; }; + 46EB2E00005160 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020C0 /* Int+Extension.swift */; }; + 46EB2E00005170 /* ISO10126Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020D0 /* ISO10126Padding.swift */; }; + 46EB2E00005180 /* ISO78164Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020E0 /* ISO78164Padding.swift */; }; + 46EB2E00005190 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000020F0 /* MD5.swift */; }; + 46EB2E000051A0 /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002100 /* NoPadding.swift */; }; + 46EB2E000051B0 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002110 /* Operators.swift */; }; + 46EB2E000051C0 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002120 /* Padding.swift */; }; + 46EB2E000051D0 /* DER.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002130 /* DER.swift */; }; + 46EB2E000051E0 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002140 /* PBKDF1.swift */; }; + 46EB2E000051F0 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002150 /* PBKDF2.swift */; }; + 46EB2E00005200 /* PKCS1v15.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002160 /* PKCS1v15.swift */; }; + 46EB2E00005210 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002170 /* PKCS5.swift */; }; + 46EB2E00005220 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002180 /* PKCS7.swift */; }; + 46EB2E00005230 /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002190 /* PKCS7Padding.swift */; }; + 46EB2E00005240 /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021A0 /* Poly1305.swift */; }; + 46EB2E00005250 /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021B0 /* Rabbit.swift */; }; + 46EB2E00005260 /* RSA+Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021C0 /* RSA+Cipher.swift */; }; + 46EB2E00005270 /* RSA+Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021D0 /* RSA+Signature.swift */; }; + 46EB2E00005280 /* RSA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021E0 /* RSA.swift */; }; + 46EB2E00005290 /* Scrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000021F0 /* Scrypt.swift */; }; + 46EB2E000052A0 /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002200 /* SecureBytes.swift */; }; + 46EB2E000052B0 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002210 /* SHA1.swift */; }; + 46EB2E000052C0 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002220 /* SHA2.swift */; }; + 46EB2E000052D0 /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002230 /* SHA3.swift */; }; + 46EB2E000052E0 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002240 /* Signature.swift */; }; + 46EB2E000052F0 /* StreamDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002250 /* StreamDecryptor.swift */; }; + 46EB2E00005300 /* StreamEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002260 /* StreamEncryptor.swift */; }; + 46EB2E00005310 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002270 /* String+Extension.swift */; }; + 46EB2E00005320 /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002280 /* UInt128.swift */; }; + 46EB2E00005330 /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002290 /* UInt16+Extension.swift */; }; + 46EB2E00005340 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022A0 /* UInt32+Extension.swift */; }; + 46EB2E00005350 /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022B0 /* UInt64+Extension.swift */; }; + 46EB2E00005360 /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022C0 /* UInt8+Extension.swift */; }; + 46EB2E00005370 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022D0 /* Updatable.swift */; }; + 46EB2E00005380 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022E0 /* Utils.swift */; }; + 46EB2E00005390 /* XChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000022F0 /* XChaCha20.swift */; }; + 46EB2E000053A0 /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002300 /* ZeroPadding.swift */; }; + 46EB2E000053F0 /* CryptoSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000053E0 /* CryptoSwift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005430 /* CryptoSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005420 /* CryptoSwift-dummy.m */; }; + 46EB2E000054C0 /* DTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000001F0 /* DTConstants.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000054D0 /* DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000210 /* DTError.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000054E0 /* DTTimePeriod.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000230 /* DTTimePeriod.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000054F0 /* DTTimePeriodChain.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000250 /* DTTimePeriodChain.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005500 /* DTTimePeriodCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000270 /* DTTimePeriodCollection.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005510 /* DTTimePeriodGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000290 /* DTTimePeriodGroup.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005520 /* NSDate+DateTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000002B0 /* NSDate+DateTools.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005530 /* DateTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000001D0 /* DateTools.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005540 /* DTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000001E0 /* DTConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005550 /* DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000200 /* DTError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005560 /* DTTimePeriod.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000220 /* DTTimePeriod.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005570 /* DTTimePeriodChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000240 /* DTTimePeriodChain.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005580 /* DTTimePeriodCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000260 /* DTTimePeriodCollection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005590 /* DTTimePeriodGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000280 /* DTTimePeriodGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000055A0 /* NSDate+DateTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002A0 /* NSDate+DateTools.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005600 /* DateTools-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000055F0 /* DateTools-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005630 /* DateTools-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005620 /* DateTools-dummy.m */; }; + 46EB2E000056C0 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002310 /* Constants.swift */; }; + 46EB2E000056D0 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002320 /* Date+Bundle.swift */; }; + 46EB2E000056E0 /* Date+Comparators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002330 /* Date+Comparators.swift */; }; + 46EB2E000056F0 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002340 /* Date+Components.swift */; }; + 46EB2E00005700 /* Date+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002350 /* Date+Format.swift */; }; + 46EB2E00005710 /* Date+Inits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002360 /* Date+Inits.swift */; }; + 46EB2E00005720 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002370 /* Date+Manipulations.swift */; }; + 46EB2E00005730 /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002380 /* Date+TimeAgo.swift */; }; + 46EB2E00005740 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002390 /* Enums.swift */; }; + 46EB2E00005750 /* Integer+DateTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023A0 /* Integer+DateTools.swift */; }; + 46EB2E00005760 /* TimeChunk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023B0 /* TimeChunk.swift */; }; + 46EB2E00005770 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023C0 /* TimePeriod.swift */; }; + 46EB2E00005780 /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023D0 /* TimePeriodChain.swift */; }; + 46EB2E00005790 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023E0 /* TimePeriodCollection.swift */; }; + 46EB2E000057A0 /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000023F0 /* TimePeriodGroup.swift */; }; + 46EB2E00005800 /* DateToolsSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000057F0 /* DateToolsSwift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005840 /* DateToolsSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005830 /* DateToolsSwift-dummy.m */; }; + 46EB2E00005950 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004760 /* PrivacyInfo.xcprivacy */; }; + 46EB2E00005980 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002400 /* CacheSerializer.swift */; }; + 46EB2E00005990 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002410 /* DiskStorage.swift */; }; + 46EB2E000059A0 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002420 /* FormatIndicatedCacheSerializer.swift */; }; + 46EB2E000059B0 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002430 /* ImageCache.swift */; }; + 46EB2E000059C0 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002440 /* MemoryStorage.swift */; }; + 46EB2E000059D0 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002450 /* Storage.swift */; }; + 46EB2E000059E0 /* CPListItem+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002460 /* CPListItem+Kingfisher.swift */; }; + 46EB2E000059F0 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002470 /* ImageView+Kingfisher.swift */; }; + 46EB2E00005A00 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002480 /* NSButton+Kingfisher.swift */; }; + 46EB2E00005A10 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002490 /* NSTextAttachment+Kingfisher.swift */; }; + 46EB2E00005A20 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024A0 /* TVMonogramView+Kingfisher.swift */; }; + 46EB2E00005A30 /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024B0 /* UIButton+Kingfisher.swift */; }; + 46EB2E00005A40 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024C0 /* WKInterfaceImage+Kingfisher.swift */; }; + 46EB2E00005A50 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024D0 /* AVAssetImageDataProvider.swift */; }; + 46EB2E00005A60 /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024E0 /* ImageDataProvider.swift */; }; + 46EB2E00005A70 /* PHPickerResultImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000024F0 /* PHPickerResultImageDataProvider.swift */; }; + 46EB2E00005A80 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002500 /* Resource.swift */; }; + 46EB2E00005A90 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002510 /* Source.swift */; }; + 46EB2E00005AA0 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002520 /* KF.swift */; }; + 46EB2E00005AB0 /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002530 /* KFOptionsSetter.swift */; }; + 46EB2E00005AC0 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002540 /* Kingfisher.swift */; }; + 46EB2E00005AD0 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002550 /* KingfisherError.swift */; }; + 46EB2E00005AE0 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002560 /* KingfisherManager.swift */; }; + 46EB2E00005AF0 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002570 /* KingfisherOptionsInfo.swift */; }; + 46EB2E00005B00 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002580 /* Filter.swift */; }; + 46EB2E00005B10 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002590 /* GIFAnimatedImage.swift */; }; + 46EB2E00005B20 /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025A0 /* GraphicsContext.swift */; }; + 46EB2E00005B30 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025B0 /* Image.swift */; }; + 46EB2E00005B40 /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025C0 /* ImageDrawing.swift */; }; + 46EB2E00005B50 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025D0 /* ImageFormat.swift */; }; + 46EB2E00005B60 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025E0 /* ImageProcessor.swift */; }; + 46EB2E00005B70 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000025F0 /* ImageProgressive.swift */; }; + 46EB2E00005B80 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002600 /* ImageTransition.swift */; }; + 46EB2E00005B90 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002610 /* Placeholder.swift */; }; + 46EB2E00005BA0 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002620 /* AuthenticationChallengeResponsable.swift */; }; + 46EB2E00005BB0 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002630 /* ImageDataProcessor.swift */; }; + 46EB2E00005BC0 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002640 /* ImageDownloader.swift */; }; + 46EB2E00005BD0 /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002650 /* ImageDownloaderDelegate.swift */; }; + 46EB2E00005BE0 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002660 /* ImageModifier.swift */; }; + 46EB2E00005BF0 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002670 /* ImagePrefetcher.swift */; }; + 46EB2E00005C00 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002680 /* RedirectHandler.swift */; }; + 46EB2E00005C10 /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002690 /* RequestModifier.swift */; }; + 46EB2E00005C20 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026A0 /* RetryStrategy.swift */; }; + 46EB2E00005C30 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026B0 /* SessionDataTask.swift */; }; + 46EB2E00005C40 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026C0 /* SessionDelegate.swift */; }; + 46EB2E00005C50 /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026D0 /* ImageBinder.swift */; }; + 46EB2E00005C60 /* ImageContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026E0 /* ImageContext.swift */; }; + 46EB2E00005C70 /* KFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000026F0 /* KFAnimatedImage.swift */; }; + 46EB2E00005C80 /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002700 /* KFImage.swift */; }; + 46EB2E00005C90 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002710 /* KFImageOptions.swift */; }; + 46EB2E00005CA0 /* KFImageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002720 /* KFImageProtocol.swift */; }; + 46EB2E00005CB0 /* KFImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002730 /* KFImageRenderer.swift */; }; + 46EB2E00005CC0 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002740 /* Box.swift */; }; + 46EB2E00005CD0 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002750 /* CallbackQueue.swift */; }; + 46EB2E00005CE0 /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002760 /* Delegate.swift */; }; + 46EB2E00005CF0 /* DisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002770 /* DisplayLink.swift */; }; + 46EB2E00005D00 /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002780 /* ExtensionHelpers.swift */; }; + 46EB2E00005D10 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002790 /* Result.swift */; }; + 46EB2E00005D20 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027A0 /* Runtime.swift */; }; + 46EB2E00005D30 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027B0 /* SizeExtensions.swift */; }; + 46EB2E00005D40 /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027C0 /* String+MD5.swift */; }; + 46EB2E00005D50 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027D0 /* AnimatedImageView.swift */; }; + 46EB2E00005D60 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000027E0 /* Indicator.swift */; }; + 46EB2E00005DB0 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00005DA0 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00005DF0 /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00005DE0 /* Kingfisher-dummy.m */; }; + 46EB2E00005E80 /* CALayer+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002810 /* CALayer+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005E90 /* NSObject+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002830 /* NSObject+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005EA0 /* UIBlurEffect+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002850 /* UIBlurEffect+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005EB0 /* UIColor+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002870 /* UIColor+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005EC0 /* UIImage+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002890 /* UIImage+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005ED0 /* UIImageView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028B0 /* UIImageView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005EE0 /* UILabel+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028D0 /* UILabel+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005EF0 /* UITableView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000028F0 /* UITableView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F00 /* UITextField+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002910 /* UITextField+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F10 /* UITextView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002930 /* UITextView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F20 /* UIView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002950 /* UIView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F30 /* UIViewController+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002970 /* UIViewController+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F40 /* UIVisualEffectView+LookinServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002990 /* UIVisualEffectView+LookinServer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F50 /* LKS_ConnectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029B0 /* LKS_ConnectionManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F60 /* LKS_RequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029D0 /* LKS_RequestHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F70 /* LKS_AttrModificationPatchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000029F0 /* LKS_AttrModificationPatchHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F80 /* LKS_CustomAttrModificationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A10 /* LKS_CustomAttrModificationHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005F90 /* LKS_HierarchyDetailsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A30 /* LKS_HierarchyDetailsHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FA0 /* LKS_InbuiltAttrModificationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A50 /* LKS_InbuiltAttrModificationHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FB0 /* LKSConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A80 /* LKSConfigManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FC0 /* LKS_AttrGroupsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AA0 /* LKS_AttrGroupsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FD0 /* LKS_CustomAttrGroupsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AC0 /* LKS_CustomAttrGroupsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FE0 /* LKS_CustomAttrSetterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AE0 /* LKS_CustomAttrSetterManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00005FF0 /* LKS_CustomDisplayItemsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B00 /* LKS_CustomDisplayItemsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006000 /* LKS_EventHandlerMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B20 /* LKS_EventHandlerMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006010 /* LKS_ExportManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B40 /* LKS_ExportManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006020 /* LKS_GestureTargetActionsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B60 /* LKS_GestureTargetActionsSearcher.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006030 /* LKS_Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B80 /* LKS_Helper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006040 /* LKS_HierarchyDisplayItemsMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BA0 /* LKS_HierarchyDisplayItemsMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006050 /* LKS_MultiplatformAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BC0 /* LKS_MultiplatformAdapter.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006060 /* LKS_ObjectRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BE0 /* LKS_ObjectRegistry.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006070 /* LKS_TraceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C00 /* LKS_TraceManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006080 /* CALayer+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C30 /* CALayer+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006090 /* Color+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C50 /* Color+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060A0 /* Image+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C70 /* Image+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060B0 /* NSArray+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C90 /* NSArray+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060C0 /* NSObject+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CB0 /* NSObject+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060D0 /* NSSet+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CD0 /* NSSet+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060E0 /* NSString+Lookin.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CF0 /* NSString+Lookin.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000060F0 /* LookinAppInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D10 /* LookinAppInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006100 /* LookinAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D30 /* LookinAttribute.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006110 /* LookinAttributeModification.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D50 /* LookinAttributeModification.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006120 /* LookinAttributesGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D70 /* LookinAttributesGroup.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006130 /* LookinAttributesSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D90 /* LookinAttributesSection.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006140 /* LookinAttrIdentifiers.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DB0 /* LookinAttrIdentifiers.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006150 /* LookinAutoLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DE0 /* LookinAutoLayoutConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006160 /* LookinConnectionAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E10 /* LookinConnectionAttachment.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006170 /* LookinConnectionResponseAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E30 /* LookinConnectionResponseAttachment.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006180 /* LookinCustomAttrModification.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E50 /* LookinCustomAttrModification.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006190 /* LookinCustomDisplayItemInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E70 /* LookinCustomDisplayItemInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061A0 /* LookinDashboardBlueprint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E90 /* LookinDashboardBlueprint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061B0 /* LookinDisplayItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EC0 /* LookinDisplayItem.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061C0 /* LookinDisplayItemDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EE0 /* LookinDisplayItemDetail.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061D0 /* LookinEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F00 /* LookinEventHandler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061E0 /* LookinHierarchyFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F20 /* LookinHierarchyFile.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000061F0 /* LookinHierarchyInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F40 /* LookinHierarchyInfo.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006200 /* LookinObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F60 /* LookinObject.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006210 /* LookinStaticAsyncUpdateTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F80 /* LookinStaticAsyncUpdateTask.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006220 /* LookinTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FA0 /* LookinTuple.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006230 /* LookinWeakContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FC0 /* LookinWeakContainer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006240 /* Lookin_PTChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FE0 /* Lookin_PTChannel.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006250 /* Lookin_PTProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003010 /* Lookin_PTProtocol.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006260 /* Lookin_PTUSBHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003030 /* Lookin_PTUSBHub.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006270 /* LookinIvarTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003060 /* LookinIvarTrace.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006280 /* CALayer+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002800 /* CALayer+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006290 /* NSObject+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002820 /* NSObject+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062A0 /* UIBlurEffect+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002840 /* UIBlurEffect+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062B0 /* UIColor+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002860 /* UIColor+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062C0 /* UIImage+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002880 /* UIImage+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062D0 /* UIImageView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028A0 /* UIImageView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062E0 /* UILabel+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028C0 /* UILabel+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000062F0 /* UITableView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000028E0 /* UITableView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006300 /* UITextField+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002900 /* UITextField+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006310 /* UITextView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002920 /* UITextView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006320 /* UIView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002940 /* UIView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006330 /* UIViewController+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002960 /* UIViewController+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006340 /* UIVisualEffectView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002980 /* UIVisualEffectView+LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006350 /* LKS_ConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029A0 /* LKS_ConnectionManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006360 /* LKS_RequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029C0 /* LKS_RequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006370 /* LKS_AttrModificationPatchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000029E0 /* LKS_AttrModificationPatchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006380 /* LKS_CustomAttrModificationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A00 /* LKS_CustomAttrModificationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006390 /* LKS_HierarchyDetailsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A20 /* LKS_HierarchyDetailsHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063A0 /* LKS_InbuiltAttrModificationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A40 /* LKS_InbuiltAttrModificationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063B0 /* LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A60 /* LookinServer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063C0 /* LKSConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A70 /* LKSConfigManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063D0 /* LKS_AttrGroupsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002A90 /* LKS_AttrGroupsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063E0 /* LKS_CustomAttrGroupsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AB0 /* LKS_CustomAttrGroupsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000063F0 /* LKS_CustomAttrSetterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AD0 /* LKS_CustomAttrSetterManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006400 /* LKS_CustomDisplayItemsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002AF0 /* LKS_CustomDisplayItemsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006410 /* LKS_EventHandlerMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B10 /* LKS_EventHandlerMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006420 /* LKS_ExportManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B30 /* LKS_ExportManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006430 /* LKS_GestureTargetActionsSearcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B50 /* LKS_GestureTargetActionsSearcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006440 /* LKS_Helper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B70 /* LKS_Helper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006450 /* LKS_HierarchyDisplayItemsMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002B90 /* LKS_HierarchyDisplayItemsMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006460 /* LKS_MultiplatformAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BB0 /* LKS_MultiplatformAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006470 /* LKS_ObjectRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BD0 /* LKS_ObjectRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006480 /* LKS_TraceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002BF0 /* LKS_TraceManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006490 /* LookinServerDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C10 /* LookinServerDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064A0 /* CALayer+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C20 /* CALayer+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064B0 /* Color+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C40 /* Color+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064C0 /* Image+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C60 /* Image+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064D0 /* NSArray+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002C80 /* NSArray+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064E0 /* NSObject+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CA0 /* NSObject+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000064F0 /* NSSet+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CC0 /* NSSet+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006500 /* NSString+Lookin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002CE0 /* NSString+Lookin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006510 /* LookinAppInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D00 /* LookinAppInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006520 /* LookinAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D20 /* LookinAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006530 /* LookinAttributeModification.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D40 /* LookinAttributeModification.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006540 /* LookinAttributesGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D60 /* LookinAttributesGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006550 /* LookinAttributesSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002D80 /* LookinAttributesSection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006560 /* LookinAttrIdentifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DA0 /* LookinAttrIdentifiers.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006570 /* LookinAttrType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DC0 /* LookinAttrType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006580 /* LookinAutoLayoutConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DD0 /* LookinAutoLayoutConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006590 /* LookinCodingValueType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002DF0 /* LookinCodingValueType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065A0 /* LookinConnectionAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E00 /* LookinConnectionAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065B0 /* LookinConnectionResponseAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E20 /* LookinConnectionResponseAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065C0 /* LookinCustomAttrModification.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E40 /* LookinCustomAttrModification.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065D0 /* LookinCustomDisplayItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E60 /* LookinCustomDisplayItemInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065E0 /* LookinDashboardBlueprint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002E80 /* LookinDashboardBlueprint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000065F0 /* LookinDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EA0 /* LookinDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006600 /* LookinDisplayItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EB0 /* LookinDisplayItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006610 /* LookinDisplayItemDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002ED0 /* LookinDisplayItemDetail.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006620 /* LookinEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002EF0 /* LookinEventHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006630 /* LookinHierarchyFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F10 /* LookinHierarchyFile.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006640 /* LookinHierarchyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F30 /* LookinHierarchyInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006650 /* LookinObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F50 /* LookinObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006660 /* LookinStaticAsyncUpdateTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F70 /* LookinStaticAsyncUpdateTask.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006670 /* LookinTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002F90 /* LookinTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006680 /* LookinWeakContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FB0 /* LookinWeakContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006690 /* Lookin_PTChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FD0 /* Lookin_PTChannel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000066A0 /* Lookin_PTPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00002FF0 /* Lookin_PTPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000066B0 /* Lookin_PTProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003000 /* Lookin_PTProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000066C0 /* Lookin_PTUSBHub.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003020 /* Lookin_PTUSBHub.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000066D0 /* Peertalk.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003040 /* Peertalk.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000066E0 /* LookinIvarTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003050 /* LookinIvarTrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006740 /* LookinServer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006730 /* LookinServer-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006770 /* LookinServer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00006760 /* LookinServer-dummy.m */; }; + 46EB2E000068A0 /* MJExtensionConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000002E0 /* MJExtensionConst.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000068B0 /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000300 /* MJFoundation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000068C0 /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000320 /* MJProperty.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000068D0 /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000340 /* MJPropertyKey.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000068E0 /* MJPropertyType.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000360 /* MJPropertyType.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000068F0 /* NSObject+MJClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000380 /* NSObject+MJClass.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006900 /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003A0 /* NSObject+MJCoding.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006910 /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003C0 /* NSObject+MJKeyValue.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006920 /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000003E0 /* NSObject+MJProperty.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006930 /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000400 /* NSString+MJExtension.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006940 /* MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002C0 /* MJExtension.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006950 /* MJExtensionConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002D0 /* MJExtensionConst.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006960 /* MJFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000002F0 /* MJFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006970 /* MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000310 /* MJProperty.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006980 /* MJPropertyKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000330 /* MJPropertyKey.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006990 /* MJPropertyType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000350 /* MJPropertyType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000069A0 /* NSObject+MJClass.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000370 /* NSObject+MJClass.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000069B0 /* NSObject+MJCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000390 /* NSObject+MJCoding.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000069C0 /* NSObject+MJKeyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003B0 /* NSObject+MJKeyValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000069D0 /* NSObject+MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003D0 /* NSObject+MJProperty.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000069E0 /* NSString+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000003F0 /* NSString+MJExtension.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006A30 /* MJExtension-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006A20 /* MJExtension-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006A60 /* MJExtension-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00006A50 /* MJExtension-dummy.m */; }; + 46EB2E00006AF0 /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000420 /* MASCompositeConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B00 /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000450 /* MASConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B10 /* MASConstraintMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000470 /* MASConstraintMaker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B20 /* MASLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000490 /* MASLayoutConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B30 /* MASViewAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000004D0 /* MASViewAttribute.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B40 /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000004F0 /* MASViewConstraint.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B50 /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000510 /* NSArray+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B60 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000540 /* NSLayoutConstraint+MASDebugAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B70 /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000560 /* View+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B80 /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000590 /* ViewController+MASAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006B90 /* MASCompositeConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000410 /* MASCompositeConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BA0 /* MASConstraint+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000430 /* MASConstraint+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BB0 /* MASConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000440 /* MASConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BC0 /* MASConstraintMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000460 /* MASConstraintMaker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BD0 /* MASLayoutConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000480 /* MASLayoutConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BE0 /* Masonry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004A0 /* Masonry.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006BF0 /* MASUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004B0 /* MASUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C00 /* MASViewAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004C0 /* MASViewAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C10 /* MASViewConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000004E0 /* MASViewConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C20 /* NSArray+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000500 /* NSArray+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C30 /* NSArray+MASShorthandAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000520 /* NSArray+MASShorthandAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C40 /* NSLayoutConstraint+MASDebugAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000530 /* NSLayoutConstraint+MASDebugAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C50 /* View+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000550 /* View+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C60 /* View+MASShorthandAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000570 /* View+MASShorthandAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006C70 /* ViewController+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000580 /* ViewController+MASAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006CD0 /* Masonry-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00006CC0 /* Masonry-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00006D00 /* Masonry-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00006CF0 /* Masonry-dummy.m */; }; + 46EB2E00006E10 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004720 /* PrivacyInfo.xcprivacy */; }; + 46EB2E00006E40 /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000005C0 /* NSButton+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006E50 /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000005E0 /* NSData+ImageContentType.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006E60 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000600 /* NSImage+Compatibility.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006E70 /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000620 /* SDAnimatedImage.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006E80 /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000640 /* SDAnimatedImagePlayer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006E90 /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000660 /* SDAnimatedImageRep.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006EA0 /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000680 /* SDAnimatedImageView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006EB0 /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006A0 /* SDAnimatedImageView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006EC0 /* SDCallbackQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006C0 /* SDCallbackQueue.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006ED0 /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000006E0 /* SDDiskCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006EE0 /* SDGraphicsImageRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000700 /* SDGraphicsImageRenderer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006EF0 /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000720 /* SDImageAPNGCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F00 /* SDImageAWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000740 /* SDImageAWebPCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F10 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000760 /* SDImageCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F20 /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000780 /* SDImageCacheConfig.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F30 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007A0 /* SDImageCacheDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F40 /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007C0 /* SDImageCachesManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F50 /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000007E0 /* SDImageCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F60 /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000800 /* SDImageCoderHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F70 /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000820 /* SDImageCodersManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F80 /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000840 /* SDImageFrame.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006F90 /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000860 /* SDImageGIFCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FA0 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000880 /* SDImageGraphics.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FB0 /* SDImageHEICCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008A0 /* SDImageHEICCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FC0 /* SDImageIOAnimatedCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008C0 /* SDImageIOAnimatedCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FD0 /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000008E0 /* SDImageIOCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FE0 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000900 /* SDImageLoader.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00006FF0 /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000920 /* SDImageLoadersManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007000 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000940 /* SDImageTransformer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007010 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000960 /* SDMemoryCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007020 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000980 /* SDWebImageCacheKeyFilter.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007030 /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009A0 /* SDWebImageCacheSerializer.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007040 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009C0 /* SDWebImageCompat.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007050 /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000009E0 /* SDWebImageDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007060 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A00 /* SDWebImageDownloader.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007070 /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A20 /* SDWebImageDownloaderConfig.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007080 /* SDWebImageDownloaderDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A40 /* SDWebImageDownloaderDecryptor.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007090 /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A60 /* SDWebImageDownloaderOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070A0 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A80 /* SDWebImageDownloaderRequestModifier.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070B0 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AA0 /* SDWebImageDownloaderResponseModifier.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070C0 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AC0 /* SDWebImageError.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070D0 /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AE0 /* SDWebImageIndicator.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070E0 /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B00 /* SDWebImageManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000070F0 /* SDWebImageOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B20 /* SDWebImageOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007100 /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B40 /* SDWebImageOptionsProcessor.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007110 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B60 /* SDWebImagePrefetcher.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007120 /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B80 /* SDWebImageTransition.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007130 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BA0 /* UIButton+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007140 /* UIImage+ExtendedCacheData.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BC0 /* UIImage+ExtendedCacheData.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007150 /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BE0 /* UIImage+ForceDecode.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007160 /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C00 /* UIImage+GIF.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007170 /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C20 /* UIImage+MemoryCacheCost.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007180 /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C40 /* UIImage+Metadata.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007190 /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C60 /* UIImage+MultiFormat.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071A0 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C80 /* UIImage+Transform.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071B0 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CA0 /* UIImageView+HighlightedWebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071C0 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CC0 /* UIImageView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071D0 /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CE0 /* UIView+WebCache.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071E0 /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D00 /* UIView+WebCacheOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000071F0 /* UIView+WebCacheState.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D20 /* UIView+WebCacheState.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007200 /* NSBezierPath+SDRoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D50 /* NSBezierPath+SDRoundedCorners.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007210 /* SDAssociatedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D70 /* SDAssociatedObject.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007220 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D90 /* SDAsyncBlockOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007230 /* SDDeviceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DB0 /* SDDeviceHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007240 /* SDDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DD0 /* SDDisplayLink.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007250 /* SDFileAttributeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DF0 /* SDFileAttributeHelper.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007260 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E10 /* SDImageAssetManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007270 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E30 /* SDImageCachesManagerOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007280 /* SDImageFramePool.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E50 /* SDImageFramePool.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007290 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E80 /* SDInternalMacros.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000072A0 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EB0 /* SDWeakProxy.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000072B0 /* UIColor+SDHexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EE0 /* UIColor+SDHexString.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000072C0 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005B0 /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000072D0 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005D0 /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000072E0 /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000005F0 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000072F0 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000610 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007300 /* SDAnimatedImagePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000630 /* SDAnimatedImagePlayer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007310 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000650 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007320 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000670 /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007330 /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000690 /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007340 /* SDCallbackQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006B0 /* SDCallbackQueue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007350 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006D0 /* SDDiskCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007360 /* SDGraphicsImageRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000006F0 /* SDGraphicsImageRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007370 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000710 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007380 /* SDImageAWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000730 /* SDImageAWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007390 /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000750 /* SDImageCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073A0 /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000770 /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073B0 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000790 /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073C0 /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007B0 /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073D0 /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007D0 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073E0 /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000007F0 /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000073F0 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000810 /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007400 /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000830 /* SDImageFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007410 /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000850 /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007420 /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000870 /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007430 /* SDImageHEICCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000890 /* SDImageHEICCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007440 /* SDImageIOAnimatedCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008B0 /* SDImageIOAnimatedCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007450 /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008D0 /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007460 /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000008F0 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007470 /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000910 /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007480 /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000930 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007490 /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000950 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074A0 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000970 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074B0 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000990 /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074C0 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009B0 /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074D0 /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009D0 /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074E0 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000009F0 /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000074F0 /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A10 /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007500 /* SDWebImageDownloaderDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A30 /* SDWebImageDownloaderDecryptor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007510 /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A50 /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007520 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A70 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007530 /* SDWebImageDownloaderResponseModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000A90 /* SDWebImageDownloaderResponseModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007540 /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AB0 /* SDWebImageError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007550 /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AD0 /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007560 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000AF0 /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007570 /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B10 /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007580 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B30 /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007590 /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B50 /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075A0 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B70 /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075B0 /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000B90 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075C0 /* UIImage+ExtendedCacheData.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BB0 /* UIImage+ExtendedCacheData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075D0 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BD0 /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075E0 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000BF0 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000075F0 /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C10 /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007600 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C30 /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007610 /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C50 /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007620 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C70 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007630 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000C90 /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007640 /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CB0 /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007650 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CD0 /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007660 /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000CF0 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007670 /* UIView+WebCacheState.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D10 /* UIView+WebCacheState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007680 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D30 /* SDWebImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007690 /* NSBezierPath+SDRoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D40 /* NSBezierPath+SDRoundedCorners.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076A0 /* SDAssociatedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D60 /* SDAssociatedObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076B0 /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000D80 /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076C0 /* SDDeviceHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DA0 /* SDDeviceHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076D0 /* SDDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DC0 /* SDDisplayLink.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076E0 /* SDFileAttributeHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000DE0 /* SDFileAttributeHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000076F0 /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E00 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007700 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E20 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007710 /* SDImageFramePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E40 /* SDImageFramePool.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007720 /* SDImageIOAnimatedCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E60 /* SDImageIOAnimatedCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007730 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E70 /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007740 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000E90 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007750 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EA0 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007760 /* SDWebImageTransitionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EC0 /* SDWebImageTransitionInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007770 /* UIColor+SDHexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000ED0 /* UIColor+SDHexString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000077C0 /* SDWebImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000077B0 /* SDWebImage-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000077F0 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000077E0 /* SDWebImage-dummy.m */; }; + 46EB2E00007880 /* SDImageWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F00 /* SDImageWebPCoder.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00007890 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F20 /* SDWebImageWebPCoderDefine.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000078A0 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F40 /* UIImage+WebP.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000078B0 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000EF0 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000078C0 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F10 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000078D0 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F30 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000078E0 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F50 /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000078F0 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F60 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007900 /* SDWebImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F70 /* SDWebImageWebPCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007970 /* SDWebImageWebPCoder-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00007960 /* SDWebImageWebPCoder-dummy.m */; }; + 46EB2E00007AA0 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003070 /* Constraint.swift */; }; + 46EB2E00007AB0 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003080 /* ConstraintAttributes.swift */; }; + 46EB2E00007AC0 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003090 /* ConstraintConfig.swift */; }; + 46EB2E00007AD0 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030A0 /* ConstraintConstantTarget.swift */; }; + 46EB2E00007AE0 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030B0 /* ConstraintDescription.swift */; }; + 46EB2E00007AF0 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030C0 /* ConstraintDirectionalInsets.swift */; }; + 46EB2E00007B00 /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030D0 /* ConstraintDirectionalInsetTarget.swift */; }; + 46EB2E00007B10 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030E0 /* ConstraintDSL.swift */; }; + 46EB2E00007B20 /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000030F0 /* ConstraintInsets.swift */; }; + 46EB2E00007B30 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003100 /* ConstraintInsetTarget.swift */; }; + 46EB2E00007B40 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003110 /* ConstraintItem.swift */; }; + 46EB2E00007B50 /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003120 /* ConstraintLayoutGuide+Extensions.swift */; }; + 46EB2E00007B60 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003130 /* ConstraintLayoutGuide.swift */; }; + 46EB2E00007B70 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003140 /* ConstraintLayoutGuideDSL.swift */; }; + 46EB2E00007B80 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003150 /* ConstraintLayoutSupport.swift */; }; + 46EB2E00007B90 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003160 /* ConstraintLayoutSupportDSL.swift */; }; + 46EB2E00007BA0 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003170 /* ConstraintMaker.swift */; }; + 46EB2E00007BB0 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003180 /* ConstraintMakerEditable.swift */; }; + 46EB2E00007BC0 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003190 /* ConstraintMakerExtendable.swift */; }; + 46EB2E00007BD0 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031A0 /* ConstraintMakerFinalizable.swift */; }; + 46EB2E00007BE0 /* ConstraintMakerPrioritizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031B0 /* ConstraintMakerPrioritizable.swift */; }; + 46EB2E00007BF0 /* ConstraintMakerRelatable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031C0 /* ConstraintMakerRelatable+Extensions.swift */; }; + 46EB2E00007C00 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031D0 /* ConstraintMakerRelatable.swift */; }; + 46EB2E00007C10 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031E0 /* ConstraintMultiplierTarget.swift */; }; + 46EB2E00007C20 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000031F0 /* ConstraintOffsetTarget.swift */; }; + 46EB2E00007C30 /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003200 /* ConstraintPriority.swift */; }; + 46EB2E00007C40 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003210 /* ConstraintPriorityTarget.swift */; }; + 46EB2E00007C50 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003220 /* ConstraintRelatableTarget.swift */; }; + 46EB2E00007C60 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003230 /* ConstraintRelation.swift */; }; + 46EB2E00007C70 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003240 /* ConstraintView+Extensions.swift */; }; + 46EB2E00007C80 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003250 /* ConstraintView.swift */; }; + 46EB2E00007C90 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003260 /* ConstraintViewDSL.swift */; }; + 46EB2E00007CA0 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003270 /* Debugging.swift */; }; + 46EB2E00007CB0 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003280 /* LayoutConstraint.swift */; }; + 46EB2E00007CC0 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003290 /* LayoutConstraintItem.swift */; }; + 46EB2E00007CD0 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032A0 /* Typealiases.swift */; }; + 46EB2E00007CE0 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032B0 /* UILayoutSupport+Extensions.swift */; }; + 46EB2E00007D30 /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00007D20 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007D70 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00007D60 /* SnapKit-dummy.m */; }; + 46EB2E00007EF0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004780 /* PrivacyInfo.xcprivacy */; }; + 46EB2E00007F20 /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032C0 /* SwiftyJSON.swift */; }; + 46EB2E00007F70 /* SwiftyJSON-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00007F60 /* SwiftyJSON-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00007FB0 /* SwiftyJSON-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00007FA0 /* SwiftyJSON-dummy.m */; }; + 46EB2E00008040 /* NSBundle+TZImagePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000032F0 /* NSBundle+TZImagePicker.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008050 /* TZAssetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003310 /* TZAssetCell.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008060 /* TZAssetModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003330 /* TZAssetModel.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008070 /* TZAuthLimitedFooterTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003350 /* TZAuthLimitedFooterTipView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008080 /* TZGifPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003370 /* TZGifPhotoPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008090 /* TZImageCropManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003390 /* TZImageCropManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080A0 /* TZImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033B0 /* TZImageManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080B0 /* TZImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033D0 /* TZImagePickerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080C0 /* TZImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000033F0 /* TZImageRequestOperation.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080D0 /* TZPhotoPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003410 /* TZPhotoPickerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080E0 /* TZPhotoPreviewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003430 /* TZPhotoPreviewCell.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000080F0 /* TZPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003450 /* TZPhotoPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008100 /* TZProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003470 /* TZProgressView.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008110 /* TZVideoCropController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003490 /* TZVideoCropController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008120 /* TZVideoEditedPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034B0 /* TZVideoEditedPreviewController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008130 /* TZVideoPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034D0 /* TZVideoPlayerController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008140 /* UIView+TZLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000034F0 /* UIView+TZLayout.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008150 /* NSBundle+TZImagePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000032E0 /* NSBundle+TZImagePicker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008160 /* TZAssetCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003300 /* TZAssetCell.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008170 /* TZAssetModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003320 /* TZAssetModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008180 /* TZAuthLimitedFooterTipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003340 /* TZAuthLimitedFooterTipView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008190 /* TZGifPhotoPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003360 /* TZGifPhotoPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081A0 /* TZImageCropManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003380 /* TZImageCropManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081B0 /* TZImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033A0 /* TZImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081C0 /* TZImagePickerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033C0 /* TZImagePickerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081D0 /* TZImageRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000033E0 /* TZImageRequestOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081E0 /* TZPhotoPickerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003400 /* TZPhotoPickerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000081F0 /* TZPhotoPreviewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003420 /* TZPhotoPreviewCell.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008200 /* TZPhotoPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003440 /* TZPhotoPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008210 /* TZProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003460 /* TZProgressView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008220 /* TZVideoCropController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003480 /* TZVideoCropController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008230 /* TZVideoEditedPreviewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034A0 /* TZVideoEditedPreviewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008240 /* TZVideoPlayerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034C0 /* TZVideoPlayerController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008250 /* UIView+TZLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000034E0 /* UIView+TZLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008260 /* TZLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003520 /* TZLocationManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008270 /* TZLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00003510 /* TZLocationManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000082D0 /* TZImagePickerController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000082C0 /* TZImagePickerController-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008300 /* TZImagePickerController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000082F0 /* TZImagePickerController-dummy.m */; }; + 46EB2E00008390 /* anim_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000F90 /* anim_decode.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000083A0 /* demux.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FA0 /* demux.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000083B0 /* demux.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FB0 /* demux.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000083C0 /* anim_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FE0 /* anim_encode.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000083D0 /* muxedit.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FF0 /* muxedit.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000083E0 /* muxinternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001010 /* muxinternal.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000083F0 /* muxread.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001020 /* muxread.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008400 /* animi.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00000FD0 /* animi.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008410 /* muxi.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001000 /* muxi.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008420 /* mux.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001030 /* mux.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008430 /* sharpyuv.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001050 /* sharpyuv.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008440 /* sharpyuv_cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001070 /* sharpyuv_cpu.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008450 /* sharpyuv_csp.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001090 /* sharpyuv_csp.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008460 /* sharpyuv_dsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010B0 /* sharpyuv_dsp.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008470 /* sharpyuv_gamma.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010D0 /* sharpyuv_gamma.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008480 /* sharpyuv_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000010F0 /* sharpyuv_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008490 /* sharpyuv_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001100 /* sharpyuv_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000084A0 /* sharpyuv.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001060 /* sharpyuv.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000084B0 /* sharpyuv_cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001080 /* sharpyuv_cpu.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000084C0 /* sharpyuv_csp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010A0 /* sharpyuv_csp.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000084D0 /* sharpyuv_dsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010C0 /* sharpyuv_dsp.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000084E0 /* sharpyuv_gamma.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000010E0 /* sharpyuv_gamma.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E000084F0 /* bit_reader_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001180 /* bit_reader_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008500 /* bit_writer_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011A0 /* bit_writer_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008510 /* color_cache_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011C0 /* color_cache_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008520 /* filters_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000011F0 /* filters_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008530 /* huffman_encode_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001210 /* huffman_encode_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008540 /* huffman_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001230 /* huffman_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008550 /* quant_levels_dec_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001250 /* quant_levels_dec_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008560 /* quant_levels_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001270 /* quant_levels_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008570 /* random_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001290 /* random_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008580 /* rescaler_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012B0 /* rescaler_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008590 /* thread_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012D0 /* thread_utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085A0 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000012F0 /* utils.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085B0 /* alpha_processing.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001310 /* alpha_processing.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085C0 /* alpha_processing_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001320 /* alpha_processing_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085D0 /* alpha_processing_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001330 /* alpha_processing_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085E0 /* alpha_processing_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001340 /* alpha_processing_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000085F0 /* alpha_processing_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001350 /* alpha_processing_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008600 /* cost.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001380 /* cost.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008610 /* cost_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001390 /* cost_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008620 /* cost_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013A0 /* cost_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008630 /* cost_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013B0 /* cost_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008640 /* cost_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013C0 /* cost_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008650 /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013D0 /* cpu.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008660 /* dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000013F0 /* dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008670 /* dec_clip_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001400 /* dec_clip_tables.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008680 /* dec_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001410 /* dec_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008690 /* dec_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001420 /* dec_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086A0 /* dec_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001430 /* dec_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086B0 /* dec_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001440 /* dec_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086C0 /* dec_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001450 /* dec_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086D0 /* dec_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001460 /* dec_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086E0 /* enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001480 /* enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000086F0 /* enc_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001490 /* enc_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008700 /* enc_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014A0 /* enc_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008710 /* enc_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014B0 /* enc_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008720 /* enc_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014C0 /* enc_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008730 /* enc_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014D0 /* enc_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008740 /* enc_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014E0 /* enc_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008750 /* filters.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000014F0 /* filters.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008760 /* filters_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001500 /* filters_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008770 /* filters_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001510 /* filters_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008780 /* filters_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001520 /* filters_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008790 /* filters_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001530 /* filters_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087A0 /* lossless.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001540 /* lossless.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087B0 /* lossless_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001570 /* lossless_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087C0 /* lossless_enc_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001580 /* lossless_enc_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087D0 /* lossless_enc_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001590 /* lossless_enc_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087E0 /* lossless_enc_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015A0 /* lossless_enc_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000087F0 /* lossless_enc_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015B0 /* lossless_enc_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008800 /* lossless_enc_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015C0 /* lossless_enc_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008810 /* lossless_enc_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015D0 /* lossless_enc_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008820 /* lossless_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015E0 /* lossless_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008830 /* lossless_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000015F0 /* lossless_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008840 /* lossless_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001600 /* lossless_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008850 /* lossless_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001610 /* lossless_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008860 /* lossless_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001620 /* lossless_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008870 /* rescaler.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001670 /* rescaler.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008880 /* rescaler_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001680 /* rescaler_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008890 /* rescaler_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001690 /* rescaler_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088A0 /* rescaler_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016A0 /* rescaler_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088B0 /* rescaler_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016B0 /* rescaler_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088C0 /* rescaler_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016C0 /* rescaler_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088D0 /* ssim.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016D0 /* ssim.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088E0 /* ssim_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016E0 /* ssim_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000088F0 /* upsampling.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000016F0 /* upsampling.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008900 /* upsampling_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001700 /* upsampling_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008910 /* upsampling_msa.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001710 /* upsampling_msa.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008920 /* upsampling_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001720 /* upsampling_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008930 /* upsampling_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001730 /* upsampling_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008940 /* upsampling_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001740 /* upsampling_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008950 /* yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001750 /* yuv.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008960 /* yuv_mips32.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001770 /* yuv_mips32.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008970 /* yuv_mips_dsp_r2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001780 /* yuv_mips_dsp_r2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008980 /* yuv_neon.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001790 /* yuv_neon.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008990 /* yuv_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017A0 /* yuv_sse2.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089A0 /* yuv_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017B0 /* yuv_sse41.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089B0 /* alpha_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017D0 /* alpha_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089C0 /* buffer_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000017E0 /* buffer_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089D0 /* frame_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001800 /* frame_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089E0 /* idec_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001810 /* idec_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E000089F0 /* io_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001820 /* io_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A00 /* quant_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001830 /* quant_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A10 /* tree_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001840 /* tree_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A20 /* vp8l_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001870 /* vp8l_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A30 /* vp8_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001880 /* vp8_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A40 /* webp_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018B0 /* webp_dec.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A50 /* alpha_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018C0 /* alpha_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A60 /* analysis_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018D0 /* analysis_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A70 /* backward_references_cost_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018E0 /* backward_references_cost_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A80 /* backward_references_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000018F0 /* backward_references_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008A90 /* config_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001910 /* config_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AA0 /* cost_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001920 /* cost_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AB0 /* filter_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001940 /* filter_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AC0 /* frame_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001950 /* frame_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AD0 /* histogram_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001960 /* histogram_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AE0 /* iterator_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001980 /* iterator_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008AF0 /* near_lossless_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001990 /* near_lossless_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B00 /* picture_csp_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019A0 /* picture_csp_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B10 /* picture_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019B0 /* picture_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B20 /* picture_psnr_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019C0 /* picture_psnr_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B30 /* picture_rescale_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019D0 /* picture_rescale_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B40 /* picture_tools_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019E0 /* picture_tools_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B50 /* predictor_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000019F0 /* predictor_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B60 /* quant_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A00 /* quant_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B70 /* syntax_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A10 /* syntax_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B80 /* token_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A20 /* token_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008B90 /* tree_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A30 /* tree_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008BA0 /* vp8l_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A60 /* vp8l_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008BB0 /* webp_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A70 /* webp_enc.c */; settings = {COMPILER_FLAGS = "-D_THREAD_SAFE -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 46EB2E00008BC0 /* decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001120 /* decode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008BD0 /* encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001130 /* encode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008BE0 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001140 /* types.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008BF0 /* mux_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001150 /* mux_types.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C00 /* format_constants.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001160 /* format_constants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C10 /* bit_reader_inl_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001170 /* bit_reader_inl_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C20 /* bit_reader_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001190 /* bit_reader_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C30 /* bit_writer_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011B0 /* bit_writer_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C40 /* color_cache_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011D0 /* color_cache_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C50 /* endian_inl_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000011E0 /* endian_inl_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C60 /* filters_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001200 /* filters_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C70 /* huffman_encode_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001220 /* huffman_encode_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C80 /* huffman_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001240 /* huffman_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008C90 /* quant_levels_dec_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001260 /* quant_levels_dec_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CA0 /* quant_levels_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001280 /* quant_levels_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CB0 /* random_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012A0 /* random_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CC0 /* rescaler_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012C0 /* rescaler_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CD0 /* thread_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000012E0 /* thread_utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CE0 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001300 /* utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008CF0 /* common_sse2.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001360 /* common_sse2.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D00 /* common_sse41.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001370 /* common_sse41.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D10 /* cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000013E0 /* cpu.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D20 /* dsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001470 /* dsp.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D30 /* lossless.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001550 /* lossless.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D40 /* lossless_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001560 /* lossless_common.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D50 /* mips_macro.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001630 /* mips_macro.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D60 /* msa_macro.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001640 /* msa_macro.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D70 /* neon.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001650 /* neon.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D80 /* quant.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001660 /* quant.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008D90 /* yuv.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001760 /* yuv.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DA0 /* alphai_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000017C0 /* alphai_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DB0 /* common_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000017F0 /* common_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DC0 /* vp8i_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001850 /* vp8i_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DD0 /* vp8li_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001860 /* vp8li_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DE0 /* vp8_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001890 /* vp8_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008DF0 /* webpi_dec.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E000018A0 /* webpi_dec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008E00 /* backward_references_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001900 /* backward_references_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008E10 /* cost_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001930 /* cost_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008E20 /* histogram_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001970 /* histogram_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008E30 /* vp8i_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A40 /* vp8i_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008E40 /* vp8li_enc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00001A50 /* vp8li_enc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008EA0 /* libwebp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E00008E90 /* libwebp-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E00008ED0 /* libwebp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00008EC0 /* libwebp-dummy.m */; }; + 46EB2E00008FE0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 46EB2E000047A0 /* PrivacyInfo.xcprivacy */; }; + 46EB2E00009010 /* CAAnimation+TimingConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003530 /* CAAnimation+TimingConfiguration.swift */; }; + 46EB2E00009020 /* CALayer+addAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003540 /* CALayer+addAnimation.swift */; }; + 46EB2E00009030 /* CombinedShapeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003550 /* CombinedShapeAnimation.swift */; }; + 46EB2E00009040 /* CustomPathAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003560 /* CustomPathAnimation.swift */; }; + 46EB2E00009050 /* DropShadowAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003570 /* DropShadowAnimation.swift */; }; + 46EB2E00009060 /* EllipseAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003580 /* EllipseAnimation.swift */; }; + 46EB2E00009070 /* GradientAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003590 /* GradientAnimations.swift */; }; + 46EB2E00009080 /* LayerProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035A0 /* LayerProperty.swift */; }; + 46EB2E00009090 /* OpacityAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035B0 /* OpacityAnimation.swift */; }; + 46EB2E000090A0 /* RectangleAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035C0 /* RectangleAnimation.swift */; }; + 46EB2E000090B0 /* ShapeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035D0 /* ShapeAnimation.swift */; }; + 46EB2E000090C0 /* StarAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035E0 /* StarAnimation.swift */; }; + 46EB2E000090D0 /* StrokeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000035F0 /* StrokeAnimation.swift */; }; + 46EB2E000090E0 /* TransformAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003600 /* TransformAnimations.swift */; }; + 46EB2E000090F0 /* VisibilityAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003610 /* VisibilityAnimation.swift */; }; + 46EB2E00009100 /* CompatibilityTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003620 /* CompatibilityTracker.swift */; }; + 46EB2E00009110 /* CoreAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003630 /* CoreAnimationLayer.swift */; }; + 46EB2E00009120 /* CALayer+fillBounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003640 /* CALayer+fillBounds.swift */; }; + 46EB2E00009130 /* KeyframeGroup+exactlyOneKeyframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003650 /* KeyframeGroup+exactlyOneKeyframe.swift */; }; + 46EB2E00009140 /* Keyframes+combined.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003660 /* Keyframes+combined.swift */; }; + 46EB2E00009150 /* Keyframes+timeRemapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003670 /* Keyframes+timeRemapping.swift */; }; + 46EB2E00009160 /* AnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003680 /* AnimationLayer.swift */; }; + 46EB2E00009170 /* BaseAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003690 /* BaseAnimationLayer.swift */; }; + 46EB2E00009180 /* BaseCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036A0 /* BaseCompositionLayer.swift */; }; + 46EB2E00009190 /* CALayer+setupLayerHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036B0 /* CALayer+setupLayerHierarchy.swift */; }; + 46EB2E000091A0 /* GradientRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036C0 /* GradientRenderLayer.swift */; }; + 46EB2E000091B0 /* ImageLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036D0 /* ImageLayer.swift */; }; + 46EB2E000091C0 /* InfiniteOpaqueAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036E0 /* InfiniteOpaqueAnimationLayer.swift */; }; + 46EB2E000091D0 /* LayerModel+makeAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000036F0 /* LayerModel+makeAnimationLayer.swift */; }; + 46EB2E000091E0 /* MaskCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003700 /* MaskCompositionLayer.swift */; }; + 46EB2E000091F0 /* PreCompLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003710 /* PreCompLayer.swift */; }; + 46EB2E00009200 /* RepeaterLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003720 /* RepeaterLayer.swift */; }; + 46EB2E00009210 /* ShapeItemLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003730 /* ShapeItemLayer.swift */; }; + 46EB2E00009220 /* ShapeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003740 /* ShapeLayer.swift */; }; + 46EB2E00009230 /* SolidLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003750 /* SolidLayer.swift */; }; + 46EB2E00009240 /* TextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003760 /* TextLayer.swift */; }; + 46EB2E00009250 /* TransformLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003770 /* TransformLayer.swift */; }; + 46EB2E00009260 /* ValueProviderStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003780 /* ValueProviderStore.swift */; }; + 46EB2E00009270 /* Collection+Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003790 /* Collection+Diff.swift */; }; + 46EB2E00009280 /* Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037A0 /* Diffable.swift */; }; + 46EB2E00009290 /* DiffableSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037B0 /* DiffableSection.swift */; }; + 46EB2E000092A0 /* IndexChangeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037C0 /* IndexChangeset.swift */; }; + 46EB2E000092B0 /* SectionedChangeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037D0 /* SectionedChangeset.swift */; }; + 46EB2E000092C0 /* EpoxyLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037E0 /* EpoxyLogger.swift */; }; + 46EB2E000092D0 /* CallbackContextEpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000037F0 /* CallbackContextEpoxyModeled.swift */; }; + 46EB2E000092E0 /* EpoxyModelArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003800 /* EpoxyModelArrayBuilder.swift */; }; + 46EB2E000092F0 /* EpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003810 /* EpoxyModeled.swift */; }; + 46EB2E00009300 /* EpoxyModelProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003820 /* EpoxyModelProperty.swift */; }; + 46EB2E00009310 /* EpoxyModelStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003830 /* EpoxyModelStorage.swift */; }; + 46EB2E00009320 /* AnyEpoxyModelProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003840 /* AnyEpoxyModelProperty.swift */; }; + 46EB2E00009330 /* ClassReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003850 /* ClassReference.swift */; }; + 46EB2E00009340 /* AnimatedProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003860 /* AnimatedProviding.swift */; }; + 46EB2E00009350 /* DataIDProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003870 /* DataIDProviding.swift */; }; + 46EB2E00009360 /* DidDisplayProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003880 /* DidDisplayProviding.swift */; }; + 46EB2E00009370 /* DidEndDisplayingProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003890 /* DidEndDisplayingProviding.swift */; }; + 46EB2E00009380 /* DidSelectProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038A0 /* DidSelectProviding.swift */; }; + 46EB2E00009390 /* ErasedContentProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038B0 /* ErasedContentProviding.swift */; }; + 46EB2E000093A0 /* MakeViewProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038C0 /* MakeViewProviding.swift */; }; + 46EB2E000093B0 /* SetBehaviorsProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038D0 /* SetBehaviorsProviding.swift */; }; + 46EB2E000093C0 /* SetContentProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038E0 /* SetContentProviding.swift */; }; + 46EB2E000093D0 /* StyleIDProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000038F0 /* StyleIDProviding.swift */; }; + 46EB2E000093E0 /* TraitCollectionProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003900 /* TraitCollectionProviding.swift */; }; + 46EB2E000093F0 /* ViewDifferentiatorProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003910 /* ViewDifferentiatorProviding.swift */; }; + 46EB2E00009400 /* ViewProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003920 /* ViewProviding.swift */; }; + 46EB2E00009410 /* WillDisplayProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003930 /* WillDisplayProviding.swift */; }; + 46EB2E00009420 /* ViewEpoxyModeled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003940 /* ViewEpoxyModeled.swift */; }; + 46EB2E00009430 /* EpoxyableView+SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003950 /* EpoxyableView+SwiftUIView.swift */; }; + 46EB2E00009440 /* EpoxySwiftUIHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003960 /* EpoxySwiftUIHostingController.swift */; }; + 46EB2E00009450 /* EpoxySwiftUIHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003970 /* EpoxySwiftUIHostingView.swift */; }; + 46EB2E00009460 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003980 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift */; }; + 46EB2E00009470 /* EpoxySwiftUILayoutMargins.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003990 /* EpoxySwiftUILayoutMargins.swift */; }; + 46EB2E00009480 /* MeasuringViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039A0 /* MeasuringViewRepresentable.swift */; }; + 46EB2E00009490 /* SwiftUIMeasurementContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039B0 /* SwiftUIMeasurementContainer.swift */; }; + 46EB2E000094A0 /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039C0 /* SwiftUIView.swift */; }; + 46EB2E000094B0 /* UIView+SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039D0 /* UIView+SwiftUIView.swift */; }; + 46EB2E000094C0 /* UIViewConfiguringSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039E0 /* UIViewConfiguringSwiftUIView.swift */; }; + 46EB2E000094D0 /* BehaviorsConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000039F0 /* BehaviorsConfigurableView.swift */; }; + 46EB2E000094E0 /* ContentConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A00 /* ContentConfigurableView.swift */; }; + 46EB2E000094F0 /* EpoxyableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A10 /* EpoxyableView.swift */; }; + 46EB2E00009500 /* StyledView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A20 /* StyledView.swift */; }; + 46EB2E00009510 /* ViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A30 /* ViewType.swift */; }; + 46EB2E00009520 /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A40 /* LRUCache.swift */; }; + 46EB2E00009530 /* Archive+BackingConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A50 /* Archive+BackingConfiguration.swift */; }; + 46EB2E00009540 /* Archive+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A60 /* Archive+Helpers.swift */; }; + 46EB2E00009550 /* Archive+MemoryFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A70 /* Archive+MemoryFile.swift */; }; + 46EB2E00009560 /* Archive+Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A80 /* Archive+Progress.swift */; }; + 46EB2E00009570 /* Archive+Reading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003A90 /* Archive+Reading.swift */; }; + 46EB2E00009580 /* Archive+ReadingDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AA0 /* Archive+ReadingDeprecated.swift */; }; + 46EB2E00009590 /* Archive+Writing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AB0 /* Archive+Writing.swift */; }; + 46EB2E000095A0 /* Archive+WritingDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AC0 /* Archive+WritingDeprecated.swift */; }; + 46EB2E000095B0 /* Archive+ZIP64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AD0 /* Archive+ZIP64.swift */; }; + 46EB2E000095C0 /* Archive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AE0 /* Archive.swift */; }; + 46EB2E000095D0 /* Data+Compression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003AF0 /* Data+Compression.swift */; }; + 46EB2E000095E0 /* Data+CompressionDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B00 /* Data+CompressionDeprecated.swift */; }; + 46EB2E000095F0 /* Data+Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B10 /* Data+Serialization.swift */; }; + 46EB2E00009600 /* Entry+Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B20 /* Entry+Serialization.swift */; }; + 46EB2E00009610 /* Entry+ZIP64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B30 /* Entry+ZIP64.swift */; }; + 46EB2E00009620 /* Entry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B40 /* Entry.swift */; }; + 46EB2E00009630 /* FileManager+ZIP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B50 /* FileManager+ZIP.swift */; }; + 46EB2E00009640 /* URL+ZIP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B60 /* URL+ZIP.swift */; }; + 46EB2E00009650 /* CompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B70 /* CompositionLayer.swift */; }; + 46EB2E00009660 /* ImageCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B80 /* ImageCompositionLayer.swift */; }; + 46EB2E00009670 /* MaskContainerLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003B90 /* MaskContainerLayer.swift */; }; + 46EB2E00009680 /* NullCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BA0 /* NullCompositionLayer.swift */; }; + 46EB2E00009690 /* PreCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BB0 /* PreCompositionLayer.swift */; }; + 46EB2E000096A0 /* ShapeCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BC0 /* ShapeCompositionLayer.swift */; }; + 46EB2E000096B0 /* SolidCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BD0 /* SolidCompositionLayer.swift */; }; + 46EB2E000096C0 /* TextCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BE0 /* TextCompositionLayer.swift */; }; + 46EB2E000096D0 /* MainThreadAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003BF0 /* MainThreadAnimationLayer.swift */; }; + 46EB2E000096E0 /* CachedImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C00 /* CachedImageProvider.swift */; }; + 46EB2E000096F0 /* CompositionLayersInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C10 /* CompositionLayersInitializer.swift */; }; + 46EB2E00009700 /* CoreTextRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C20 /* CoreTextRenderLayer.swift */; }; + 46EB2E00009710 /* InvertedMatteLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C30 /* InvertedMatteLayer.swift */; }; + 46EB2E00009720 /* LayerFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C40 /* LayerFontProvider.swift */; }; + 46EB2E00009730 /* LayerImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C50 /* LayerImageProvider.swift */; }; + 46EB2E00009740 /* LayerTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C60 /* LayerTextProvider.swift */; }; + 46EB2E00009750 /* LayerTransformNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C70 /* LayerTransformNode.swift */; }; + 46EB2E00009760 /* ItemsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C80 /* ItemsExtension.swift */; }; + 46EB2E00009770 /* NodeProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003C90 /* NodeProperty.swift */; }; + 46EB2E00009780 /* AnyNodeProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CA0 /* AnyNodeProperty.swift */; }; + 46EB2E00009790 /* AnyValueContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CB0 /* AnyValueContainer.swift */; }; + 46EB2E000097A0 /* KeypathSearchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CC0 /* KeypathSearchable.swift */; }; + 46EB2E000097B0 /* NodePropertyMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CD0 /* NodePropertyMap.swift */; }; + 46EB2E000097C0 /* ValueContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CE0 /* ValueContainer.swift */; }; + 46EB2E000097D0 /* GroupInterpolator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003CF0 /* GroupInterpolator.swift */; }; + 46EB2E000097E0 /* SingleValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D00 /* SingleValueProvider.swift */; }; + 46EB2E000097F0 /* RoundedCornersNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D10 /* RoundedCornersNode.swift */; }; + 46EB2E00009800 /* TrimPathNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D20 /* TrimPathNode.swift */; }; + 46EB2E00009810 /* GroupOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D30 /* GroupOutputNode.swift */; }; + 46EB2E00009820 /* PassThroughOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D40 /* PassThroughOutputNode.swift */; }; + 46EB2E00009830 /* PathOutputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D50 /* PathOutputNode.swift */; }; + 46EB2E00009840 /* FillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D60 /* FillRenderer.swift */; }; + 46EB2E00009850 /* GradientFillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D70 /* GradientFillRenderer.swift */; }; + 46EB2E00009860 /* GradientStrokeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D80 /* GradientStrokeRenderer.swift */; }; + 46EB2E00009870 /* LegacyGradientFillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003D90 /* LegacyGradientFillRenderer.swift */; }; + 46EB2E00009880 /* StrokeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DA0 /* StrokeRenderer.swift */; }; + 46EB2E00009890 /* EllipseNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DB0 /* EllipseNode.swift */; }; + 46EB2E000098A0 /* PolygonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DC0 /* PolygonNode.swift */; }; + 46EB2E000098B0 /* RectNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DD0 /* RectNode.swift */; }; + 46EB2E000098C0 /* ShapeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DE0 /* ShapeNode.swift */; }; + 46EB2E000098D0 /* StarNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003DF0 /* StarNode.swift */; }; + 46EB2E000098E0 /* GroupNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E00 /* GroupNode.swift */; }; + 46EB2E000098F0 /* FillNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E10 /* FillNode.swift */; }; + 46EB2E00009900 /* GradientFillNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E20 /* GradientFillNode.swift */; }; + 46EB2E00009910 /* GradientStrokeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E30 /* GradientStrokeNode.swift */; }; + 46EB2E00009920 /* StrokeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E40 /* StrokeNode.swift */; }; + 46EB2E00009930 /* TextAnimatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E50 /* TextAnimatorNode.swift */; }; + 46EB2E00009940 /* AnimatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E60 /* AnimatorNode.swift */; }; + 46EB2E00009950 /* PathNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E70 /* PathNode.swift */; }; + 46EB2E00009960 /* RenderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E80 /* RenderNode.swift */; }; + 46EB2E00009970 /* ShapeContainerLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003E90 /* ShapeContainerLayer.swift */; }; + 46EB2E00009980 /* ShapeRenderLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EA0 /* ShapeRenderLayer.swift */; }; + 46EB2E00009990 /* Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EB0 /* Asset.swift */; }; + 46EB2E000099A0 /* AssetLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EC0 /* AssetLibrary.swift */; }; + 46EB2E000099B0 /* ImageAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003ED0 /* ImageAsset.swift */; }; + 46EB2E000099C0 /* PrecompAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EE0 /* PrecompAsset.swift */; }; + 46EB2E000099D0 /* DictionaryInitializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003EF0 /* DictionaryInitializable.swift */; }; + 46EB2E000099E0 /* DotLottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F00 /* DotLottieAnimation.swift */; }; + 46EB2E000099F0 /* DotLottieImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F10 /* DotLottieImageProvider.swift */; }; + 46EB2E00009A00 /* DotLottieManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F20 /* DotLottieManifest.swift */; }; + 46EB2E00009A10 /* DotLottieUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F30 /* DotLottieUtils.swift */; }; + 46EB2E00009A20 /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F40 /* Bundle.swift */; }; + 46EB2E00009A30 /* KeyedDecodingContainerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F50 /* KeyedDecodingContainerExtensions.swift */; }; + 46EB2E00009A40 /* KeyframeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F60 /* KeyframeData.swift */; }; + 46EB2E00009A50 /* KeyframeGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F70 /* KeyframeGroup.swift */; }; + 46EB2E00009A60 /* DropShadowEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F80 /* DropShadowEffect.swift */; }; + 46EB2E00009A70 /* ColorEffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003F90 /* ColorEffectValue.swift */; }; + 46EB2E00009A80 /* EffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FA0 /* EffectValue.swift */; }; + 46EB2E00009A90 /* Vector1DEffectValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FB0 /* Vector1DEffectValue.swift */; }; + 46EB2E00009AA0 /* LayerEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FC0 /* LayerEffect.swift */; }; + 46EB2E00009AB0 /* ImageLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FD0 /* ImageLayerModel.swift */; }; + 46EB2E00009AC0 /* LayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FE0 /* LayerModel.swift */; }; + 46EB2E00009AD0 /* PreCompLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00003FF0 /* PreCompLayerModel.swift */; }; + 46EB2E00009AE0 /* ShapeLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004000 /* ShapeLayerModel.swift */; }; + 46EB2E00009AF0 /* SolidLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004010 /* SolidLayerModel.swift */; }; + 46EB2E00009B00 /* TextLayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004020 /* TextLayerModel.swift */; }; + 46EB2E00009B10 /* DropShadowStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004030 /* DropShadowStyle.swift */; }; + 46EB2E00009B20 /* LayerStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004040 /* LayerStyle.swift */; }; + 46EB2E00009B30 /* DashPattern.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004050 /* DashPattern.swift */; }; + 46EB2E00009B40 /* Marker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004060 /* Marker.swift */; }; + 46EB2E00009B50 /* Mask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004070 /* Mask.swift */; }; + 46EB2E00009B60 /* Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004080 /* Transform.swift */; }; + 46EB2E00009B70 /* Ellipse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004090 /* Ellipse.swift */; }; + 46EB2E00009B80 /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040A0 /* Fill.swift */; }; + 46EB2E00009B90 /* GradientFill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040B0 /* GradientFill.swift */; }; + 46EB2E00009BA0 /* GradientStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040C0 /* GradientStroke.swift */; }; + 46EB2E00009BB0 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040D0 /* Group.swift */; }; + 46EB2E00009BC0 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040E0 /* Merge.swift */; }; + 46EB2E00009BD0 /* Rectangle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000040F0 /* Rectangle.swift */; }; + 46EB2E00009BE0 /* Repeater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004100 /* Repeater.swift */; }; + 46EB2E00009BF0 /* RoundedCorners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004110 /* RoundedCorners.swift */; }; + 46EB2E00009C00 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004120 /* Shape.swift */; }; + 46EB2E00009C10 /* ShapeItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004130 /* ShapeItem.swift */; }; + 46EB2E00009C20 /* ShapeTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004140 /* ShapeTransform.swift */; }; + 46EB2E00009C30 /* Star.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004150 /* Star.swift */; }; + 46EB2E00009C40 /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004160 /* Stroke.swift */; }; + 46EB2E00009C50 /* Trim.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004170 /* Trim.swift */; }; + 46EB2E00009C60 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004180 /* Font.swift */; }; + 46EB2E00009C70 /* Glyph.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004190 /* Glyph.swift */; }; + 46EB2E00009C80 /* TextAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041A0 /* TextAnimator.swift */; }; + 46EB2E00009C90 /* TextDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041B0 /* TextDocument.swift */; }; + 46EB2E00009CA0 /* RootAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041C0 /* RootAnimationLayer.swift */; }; + 46EB2E00009CB0 /* AnimatorNodeDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041D0 /* AnimatorNodeDebugging.swift */; }; + 46EB2E00009CC0 /* LayerDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041E0 /* LayerDebugging.swift */; }; + 46EB2E00009CD0 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000041F0 /* TestHelpers.swift */; }; + 46EB2E00009CE0 /* AnimationKeypathExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004200 /* AnimationKeypathExtension.swift */; }; + 46EB2E00009CF0 /* BlendMode+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004210 /* BlendMode+Filter.swift */; }; + 46EB2E00009D00 /* CGColor+RGB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004220 /* CGColor+RGB.swift */; }; + 46EB2E00009D10 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004230 /* CGFloatExtensions.swift */; }; + 46EB2E00009D20 /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004240 /* DataExtension.swift */; }; + 46EB2E00009D30 /* MathKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004250 /* MathKit.swift */; }; + 46EB2E00009D40 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004260 /* StringExtensions.swift */; }; + 46EB2E00009D50 /* AnimationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004270 /* AnimationContext.swift */; }; + 46EB2E00009D60 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004280 /* AnyEquatable.swift */; }; + 46EB2E00009D70 /* Binding+Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004290 /* Binding+Map.swift */; }; + 46EB2E00009D80 /* View+ValueChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042A0 /* View+ValueChanged.swift */; }; + 46EB2E00009D90 /* InterpolatableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042B0 /* InterpolatableExtensions.swift */; }; + 46EB2E00009DA0 /* KeyframeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042C0 /* KeyframeExtensions.swift */; }; + 46EB2E00009DB0 /* KeyframeInterpolator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042D0 /* KeyframeInterpolator.swift */; }; + 46EB2E00009DC0 /* LottieAnimationSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042E0 /* LottieAnimationSource.swift */; }; + 46EB2E00009DD0 /* BezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000042F0 /* BezierPath.swift */; }; + 46EB2E00009DE0 /* BezierPathRoundExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004300 /* BezierPathRoundExtension.swift */; }; + 46EB2E00009DF0 /* CGPointExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004310 /* CGPointExtension.swift */; }; + 46EB2E00009E00 /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004320 /* ColorExtension.swift */; }; + 46EB2E00009E10 /* CompoundBezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004330 /* CompoundBezierPath.swift */; }; + 46EB2E00009E20 /* CurveVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004340 /* CurveVertex.swift */; }; + 46EB2E00009E30 /* PathElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004350 /* PathElement.swift */; }; + 46EB2E00009E40 /* UnitBezier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004360 /* UnitBezier.swift */; }; + 46EB2E00009E50 /* VectorsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004370 /* VectorsExtensions.swift */; }; + 46EB2E00009E60 /* LottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004380 /* LottieAnimation.swift */; }; + 46EB2E00009E70 /* LottieAnimationHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004390 /* LottieAnimationHelpers.swift */; }; + 46EB2E00009E80 /* LottieAnimationLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043A0 /* LottieAnimationLayer.swift */; }; + 46EB2E00009E90 /* LottieAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043B0 /* LottieAnimationView.swift */; }; + 46EB2E00009EA0 /* LottieAnimationViewInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043C0 /* LottieAnimationViewInitializers.swift */; }; + 46EB2E00009EB0 /* LottiePlaybackMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043D0 /* LottiePlaybackMode.swift */; }; + 46EB2E00009EC0 /* LottieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043E0 /* LottieView.swift */; }; + 46EB2E00009ED0 /* AnimationCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000043F0 /* AnimationCacheProvider.swift */; }; + 46EB2E00009EE0 /* DefaultAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004400 /* DefaultAnimationCache.swift */; }; + 46EB2E00009EF0 /* LottieAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004410 /* LottieAnimationCache.swift */; }; + 46EB2E00009F00 /* LRUAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004420 /* LRUAnimationCache.swift */; }; + 46EB2E00009F10 /* DecodingStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004430 /* DecodingStrategy.swift */; }; + 46EB2E00009F20 /* LottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004440 /* LottieConfiguration.swift */; }; + 46EB2E00009F30 /* ReducedMotionOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004450 /* ReducedMotionOption.swift */; }; + 46EB2E00009F40 /* RenderingEngineOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004460 /* RenderingEngineOption.swift */; }; + 46EB2E00009F50 /* AnimatedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004470 /* AnimatedButton.swift */; }; + 46EB2E00009F60 /* AnimatedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004480 /* AnimatedControl.swift */; }; + 46EB2E00009F70 /* AnimatedSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004490 /* AnimatedSwitch.swift */; }; + 46EB2E00009F80 /* LottieButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044A0 /* LottieButton.swift */; }; + 46EB2E00009F90 /* LottieSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044B0 /* LottieSwitch.swift */; }; + 46EB2E00009FA0 /* LottieViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044C0 /* LottieViewType.swift */; }; + 46EB2E00009FB0 /* DotLottieCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044D0 /* DotLottieCache.swift */; }; + 46EB2E00009FC0 /* DotLottieCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044E0 /* DotLottieCacheProvider.swift */; }; + 46EB2E00009FD0 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000044F0 /* DotLottieConfiguration.swift */; }; + 46EB2E00009FE0 /* DotLottieFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004500 /* DotLottieFile.swift */; }; + 46EB2E00009FF0 /* DotLottieFileHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004510 /* DotLottieFileHelpers.swift */; }; + 46EB2E0000A000 /* AnimationKeypath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004520 /* AnimationKeypath.swift */; }; + 46EB2E0000A010 /* AnyValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004530 /* AnyValueProvider.swift */; }; + 46EB2E0000A020 /* ColorValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004540 /* ColorValueProvider.swift */; }; + 46EB2E0000A030 /* FloatValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004550 /* FloatValueProvider.swift */; }; + 46EB2E0000A040 /* GradientValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004560 /* GradientValueProvider.swift */; }; + 46EB2E0000A050 /* PointValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004570 /* PointValueProvider.swift */; }; + 46EB2E0000A060 /* SizeValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004580 /* SizeValueProvider.swift */; }; + 46EB2E0000A070 /* AnimationFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004590 /* AnimationFontProvider.swift */; }; + 46EB2E0000A080 /* AnimationImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045A0 /* AnimationImageProvider.swift */; }; + 46EB2E0000A090 /* AnimationSubview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045B0 /* AnimationSubview.swift */; }; + 46EB2E0000A0A0 /* BundleImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045C0 /* BundleImageProvider.swift */; }; + 46EB2E0000A0B0 /* CompatibleAnimationKeypath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045D0 /* CompatibleAnimationKeypath.swift */; }; + 46EB2E0000A0C0 /* CompatibleAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045E0 /* CompatibleAnimationView.swift */; }; + 46EB2E0000A0D0 /* FilepathImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E000045F0 /* FilepathImageProvider.swift */; }; + 46EB2E0000A0E0 /* LottieAnimationViewBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004600 /* LottieAnimationViewBase.swift */; }; + 46EB2E0000A0F0 /* UIColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004610 /* UIColorExtension.swift */; }; + 46EB2E0000A100 /* Interpolatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004620 /* Interpolatable.swift */; }; + 46EB2E0000A110 /* Keyframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004630 /* Keyframe.swift */; }; + 46EB2E0000A120 /* LottieLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004640 /* LottieLogger.swift */; }; + 46EB2E0000A130 /* AnimationTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004650 /* AnimationTime.swift */; }; + 46EB2E0000A140 /* LottieColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004660 /* LottieColor.swift */; }; + 46EB2E0000A150 /* Vectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004670 /* Vectors.swift */; }; + 46EB2E0000A160 /* AnimationTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E00004680 /* AnimationTextProvider.swift */; }; + 46EB2E0000A1B0 /* lottie-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A1A0 /* lottie-ios-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E0000A1F0 /* lottie-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A1E0 /* lottie-ios-dummy.m */; }; + 46EB2E0000A2F0 /* Pods-CLDemo-OC-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A2E0 /* Pods-CLDemo-OC-dummy.m */; }; + 46EB2E0000A3D0 /* Pods-CLDemo-Swift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A3C0 /* Pods-CLDemo-Swift-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EB2E0000A420 /* Pods-CLDemo-Swift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46EB2E0000A410 /* Pods-CLDemo-Swift-dummy.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 46EB2E0000A490 /* PBXContainerItemProxy */ = { + 46EB2E0000A430 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 2B1A4F9261E8F421732B6CB1319CCC3E; remoteInfo = DateTools; }; - 46EB2E0000A4B0 /* PBXContainerItemProxy */ = { + 46EB2E0000A450 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85; remoteInfo = MJExtension; }; - 46EB2E0000A4D0 /* PBXContainerItemProxy */ = { + 46EB2E0000A470 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 55AF53E6C77A10ED4985E04D74A8878E; remoteInfo = Masonry; }; - 46EB2E0000A4F0 /* PBXContainerItemProxy */ = { + 46EB2E0000A490 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; remoteInfo = SDWebImage; }; - 46EB2E0000A510 /* PBXContainerItemProxy */ = { + 46EB2E0000A4B0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 1953860EA9853AA2BC8022B242F08512; remoteInfo = SDWebImageWebPCoder; }; - 46EB2E0000A530 /* PBXContainerItemProxy */ = { + 46EB2E0000A4D0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 47D2E85A78C25869BB13521D8561A638; remoteInfo = libwebp; }; - 46EB2E0000A550 /* PBXContainerItemProxy */ = { + 46EB2E0000A4F0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; remoteInfo = SDWebImage; }; - 46EB2E0000A570 /* PBXContainerItemProxy */ = { + 46EB2E0000A510 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 7B01858F4318778678571D6E58E2D832; remoteInfo = CLCamera; }; - 46EB2E0000A590 /* PBXContainerItemProxy */ = { + 46EB2E0000A530 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 2808B98A5B29AEEB5B7418EEA8B1B92C; remoteInfo = CLPopoverManager; }; - 46EB2E0000A5B0 /* PBXContainerItemProxy */ = { + 46EB2E0000A550 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 99313990C1D76A6D1D017868B6975CC8; remoteInfo = CryptoSwift; }; - 46EB2E0000A5D0 /* PBXContainerItemProxy */ = { + 46EB2E0000A570 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = CCB5EA80CC733D89D54DAEB30E93351D; remoteInfo = DateToolsSwift; }; - 46EB2E0000A5F0 /* PBXContainerItemProxy */ = { + 46EB2E0000A590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; remoteInfo = Kingfisher; }; - 46EB2E0000A610 /* PBXContainerItemProxy */ = { + 46EB2E0000A5B0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 638FEAAFC575BB76BC6AC055CDDA3506; remoteInfo = LookinServer; }; - 46EB2E0000A630 /* PBXContainerItemProxy */ = { + 46EB2E0000A5D0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; remoteInfo = SnapKit; }; - 46EB2E0000A650 /* PBXContainerItemProxy */ = { + 46EB2E0000A5F0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 1CD0618C486973D5588EF20D2E8C0AEA; remoteInfo = SwiftFormat; }; - 46EB2E0000A670 /* PBXContainerItemProxy */ = { + 46EB2E0000A610 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = D118A6A04828FD3CDA8640CD2B6796D2; remoteInfo = SwiftyJSON; }; - 46EB2E0000A690 /* PBXContainerItemProxy */ = { + 46EB2E0000A630 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = A96BBB982D62BB807B5BD10774BE2D07; remoteInfo = TZImagePickerController; }; - 46EB2E0000A6B0 /* PBXContainerItemProxy */ = { + 46EB2E0000A650 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 0B967D7F8561D42493EE289EC8D450D1; remoteInfo = "lottie-ios"; }; - 46EB2E0000A6D0 /* PBXContainerItemProxy */ = { + 46EB2E0000A670 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; remoteInfo = SnapKit; }; - 46EB2E0000A6F0 /* PBXContainerItemProxy */ = { + 46EB2E0000A690 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = EBC10B6451F5FE5244D138B5176C2A02; remoteInfo = "CryptoSwift-CryptoSwift"; }; - 46EB2E0000A710 /* PBXContainerItemProxy */ = { + 46EB2E0000A6B0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 9828BBC09E9FB1238624113D7456E59E; remoteInfo = "Kingfisher-Kingfisher"; }; - 46EB2E0000A730 /* PBXContainerItemProxy */ = { + 46EB2E0000A6D0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = B32AF3F43989CBA171BB1FB3957A4509; remoteInfo = "MJExtension-MJExtension"; }; - 46EB2E0000A750 /* PBXContainerItemProxy */ = { + 46EB2E0000A6F0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 94CFBA7D633ECA58DF85C327B035E6A3; remoteInfo = "SDWebImage-SDWebImage"; }; - 46EB2E0000A770 /* PBXContainerItemProxy */ = { + 46EB2E0000A710 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; remoteInfo = SDWebImage; }; - 46EB2E0000A790 /* PBXContainerItemProxy */ = { + 46EB2E0000A730 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 47D2E85A78C25869BB13521D8561A638; remoteInfo = libwebp; }; - 46EB2E0000A7B0 /* PBXContainerItemProxy */ = { + 46EB2E0000A750 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 8A8DB685241263AFDF5E6B20FE67B93A; remoteInfo = "SnapKit-SnapKit_Privacy"; }; - 46EB2E0000A7D0 /* PBXContainerItemProxy */ = { + 46EB2E0000A770 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; remoteGlobalIDString = 677650A76A720691B88A6959EFED6418; remoteInfo = "SwiftyJSON-SwiftyJSON"; }; - 46EB2E0000A7F0 /* PBXContainerItemProxy */ = { + 46EB2E0000A790 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 46EB2E00000000 /* Project object */; proxyType = 1; @@ -2458,131 +2456,129 @@ 46EB2E000046C0 /* CLCamera.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = CLCamera.bundle; path = Camera/Resource/CLCamera.bundle; sourceTree = ""; }; 46EB2E000046E0 /* DateTools.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = DateTools.bundle; path = DateToolsSwift/DateTools/DateTools.bundle; sourceTree = ""; }; 46EB2E00004700 /* TZImagePickerController.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = TZImagePickerController.bundle; path = TZImagePickerController/TZImagePickerController/TZImagePickerController.bundle; sourceTree = ""; }; - 46EB2E00004720 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = MJExtension/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E00004740 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = WebImage/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E00004760 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/CryptoSwift/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E00004780 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 46EB2E00004720 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = WebImage/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 46EB2E00004740 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/CryptoSwift/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 46EB2E00004760 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 46EB2E00004780 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Source/SwiftyJSON/PrivacyInfo.xcprivacy; sourceTree = ""; }; 46EB2E000047A0 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E000047C0 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Source/SwiftyJSON/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E000047E0 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 46EB2E000049B0 /* CLCamera.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLCamera.debug.xcconfig; sourceTree = ""; }; - 46EB2E000049C0 /* CLCamera.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLCamera.release.xcconfig; sourceTree = ""; }; - 46EB2E000049D0 /* CLCamera.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CLCamera.modulemap; sourceTree = ""; }; - 46EB2E000049E0 /* CLCamera-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLCamera-umbrella.h"; sourceTree = ""; }; - 46EB2E00004A10 /* CLCamera-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLCamera-prefix.pch"; sourceTree = ""; }; - 46EB2E00004A20 /* CLCamera-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CLCamera-dummy.m"; sourceTree = ""; }; - 46EB2E00004B20 /* CLPopoverManager.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLPopoverManager.debug.xcconfig; sourceTree = ""; }; - 46EB2E00004B30 /* CLPopoverManager.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLPopoverManager.release.xcconfig; sourceTree = ""; }; - 46EB2E00004B40 /* CLPopoverManager.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CLPopoverManager.modulemap; sourceTree = ""; }; - 46EB2E00004B50 /* CLPopoverManager-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLPopoverManager-umbrella.h"; sourceTree = ""; }; - 46EB2E00004B80 /* CLPopoverManager-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLPopoverManager-prefix.pch"; sourceTree = ""; }; - 46EB2E00004B90 /* CLPopoverManager-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CLPopoverManager-dummy.m"; sourceTree = ""; }; - 46EB2E00004CD0 /* ResourceBundle-CryptoSwift-CryptoSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-CryptoSwift-CryptoSwift-Info.plist"; sourceTree = ""; }; - 46EB2E000053F0 /* CryptoSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.debug.xcconfig; sourceTree = ""; }; - 46EB2E00005400 /* CryptoSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.release.xcconfig; sourceTree = ""; }; - 46EB2E00005410 /* CryptoSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CryptoSwift.modulemap; sourceTree = ""; }; - 46EB2E00005420 /* CryptoSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-umbrella.h"; sourceTree = ""; }; - 46EB2E00005450 /* CryptoSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-prefix.pch"; sourceTree = ""; }; - 46EB2E00005460 /* CryptoSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CryptoSwift-dummy.m"; sourceTree = ""; }; - 46EB2E00005600 /* DateTools.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateTools.debug.xcconfig; sourceTree = ""; }; - 46EB2E00005610 /* DateTools.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateTools.release.xcconfig; sourceTree = ""; }; - 46EB2E00005620 /* DateTools.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = DateTools.modulemap; sourceTree = ""; }; - 46EB2E00005630 /* DateTools-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateTools-umbrella.h"; sourceTree = ""; }; - 46EB2E00005650 /* DateTools-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateTools-prefix.pch"; sourceTree = ""; }; - 46EB2E00005660 /* DateTools-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DateTools-dummy.m"; sourceTree = ""; }; - 46EB2E00005800 /* DateToolsSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateToolsSwift.debug.xcconfig; sourceTree = ""; }; - 46EB2E00005810 /* DateToolsSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateToolsSwift.release.xcconfig; sourceTree = ""; }; - 46EB2E00005820 /* DateToolsSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = DateToolsSwift.modulemap; sourceTree = ""; }; - 46EB2E00005830 /* DateToolsSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateToolsSwift-umbrella.h"; sourceTree = ""; }; - 46EB2E00005860 /* DateToolsSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateToolsSwift-prefix.pch"; sourceTree = ""; }; - 46EB2E00005870 /* DateToolsSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DateToolsSwift-dummy.m"; sourceTree = ""; }; - 46EB2E000059B0 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Kingfisher-Kingfisher-Info.plist"; sourceTree = ""; }; - 46EB2E00005DB0 /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; - 46EB2E00005DC0 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; - 46EB2E00005DD0 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; - 46EB2E00005DE0 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; - 46EB2E00005E10 /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; - 46EB2E00005E20 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; - 46EB2E00006740 /* LookinServer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = LookinServer.debug.xcconfig; sourceTree = ""; }; - 46EB2E00006750 /* LookinServer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = LookinServer.release.xcconfig; sourceTree = ""; }; - 46EB2E00006760 /* LookinServer.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = LookinServer.modulemap; sourceTree = ""; }; - 46EB2E00006770 /* LookinServer-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LookinServer-umbrella.h"; sourceTree = ""; }; - 46EB2E00006790 /* LookinServer-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LookinServer-prefix.pch"; sourceTree = ""; }; - 46EB2E000067A0 /* LookinServer-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "LookinServer-dummy.m"; sourceTree = ""; }; - 46EB2E000068E0 /* ResourceBundle-MJExtension-MJExtension-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MJExtension-MJExtension-Info.plist"; sourceTree = ""; }; - 46EB2E00006A40 /* MJExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.debug.xcconfig; sourceTree = ""; }; - 46EB2E00006A50 /* MJExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.release.xcconfig; sourceTree = ""; }; - 46EB2E00006A60 /* MJExtension.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MJExtension.modulemap; sourceTree = ""; }; - 46EB2E00006A70 /* MJExtension-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-umbrella.h"; sourceTree = ""; }; - 46EB2E00006A90 /* MJExtension-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-prefix.pch"; sourceTree = ""; }; - 46EB2E00006AA0 /* MJExtension-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MJExtension-dummy.m"; sourceTree = ""; }; - 46EB2E00006CE0 /* Masonry.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Masonry.debug.xcconfig; sourceTree = ""; }; - 46EB2E00006CF0 /* Masonry.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Masonry.release.xcconfig; sourceTree = ""; }; - 46EB2E00006D00 /* Masonry.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Masonry.modulemap; sourceTree = ""; }; - 46EB2E00006D10 /* Masonry-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Masonry-umbrella.h"; sourceTree = ""; }; - 46EB2E00006D30 /* Masonry-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Masonry-prefix.pch"; sourceTree = ""; }; - 46EB2E00006D40 /* Masonry-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Masonry-dummy.m"; sourceTree = ""; }; - 46EB2E00006E80 /* ResourceBundle-SDWebImage-SDWebImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SDWebImage-SDWebImage-Info.plist"; sourceTree = ""; }; - 46EB2E000077D0 /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = ""; }; - 46EB2E000077E0 /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = ""; }; - 46EB2E000077F0 /* SDWebImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImage.modulemap; sourceTree = ""; }; - 46EB2E00007800 /* SDWebImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-umbrella.h"; sourceTree = ""; }; - 46EB2E00007820 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-prefix.pch"; sourceTree = ""; }; - 46EB2E00007830 /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImage-dummy.m"; sourceTree = ""; }; - 46EB2E00007970 /* SDWebImageWebPCoder.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImageWebPCoder.debug.xcconfig; sourceTree = ""; }; - 46EB2E00007980 /* SDWebImageWebPCoder.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImageWebPCoder.release.xcconfig; sourceTree = ""; }; - 46EB2E00007990 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImageWebPCoder.modulemap; sourceTree = ""; }; - 46EB2E000079A0 /* SDWebImageWebPCoder-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImageWebPCoder-prefix.pch"; sourceTree = ""; }; - 46EB2E000079B0 /* SDWebImageWebPCoder-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImageWebPCoder-dummy.m"; sourceTree = ""; }; - 46EB2E00007AF0 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; sourceTree = ""; }; - 46EB2E00007D50 /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; - 46EB2E00007D60 /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; - 46EB2E00007D70 /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; - 46EB2E00007D80 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; - 46EB2E00007DB0 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; - 46EB2E00007DC0 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; - 46EB2E00007E30 /* SwiftFormat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftFormat.debug.xcconfig; sourceTree = ""; }; - 46EB2E00007E40 /* SwiftFormat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftFormat.release.xcconfig; sourceTree = ""; }; - 46EB2E00007F70 /* ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist"; sourceTree = ""; }; - 46EB2E00007F90 /* SwiftyJSON.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.debug.xcconfig; sourceTree = ""; }; - 46EB2E00007FA0 /* SwiftyJSON.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.release.xcconfig; sourceTree = ""; }; - 46EB2E00007FB0 /* SwiftyJSON.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftyJSON.modulemap; sourceTree = ""; }; - 46EB2E00007FC0 /* SwiftyJSON-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-umbrella.h"; sourceTree = ""; }; - 46EB2E00007FF0 /* SwiftyJSON-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-prefix.pch"; sourceTree = ""; }; - 46EB2E00008000 /* SwiftyJSON-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftyJSON-dummy.m"; sourceTree = ""; }; - 46EB2E000082F0 /* TZImagePickerController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TZImagePickerController.debug.xcconfig; sourceTree = ""; }; - 46EB2E00008300 /* TZImagePickerController.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TZImagePickerController.release.xcconfig; sourceTree = ""; }; - 46EB2E00008310 /* TZImagePickerController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = TZImagePickerController.modulemap; sourceTree = ""; }; - 46EB2E00008320 /* TZImagePickerController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TZImagePickerController-umbrella.h"; sourceTree = ""; }; - 46EB2E00008340 /* TZImagePickerController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TZImagePickerController-prefix.pch"; sourceTree = ""; }; - 46EB2E00008350 /* TZImagePickerController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "TZImagePickerController-dummy.m"; sourceTree = ""; }; - 46EB2E00008EC0 /* libwebp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = libwebp.debug.xcconfig; sourceTree = ""; }; - 46EB2E00008ED0 /* libwebp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = libwebp.release.xcconfig; sourceTree = ""; }; - 46EB2E00008EE0 /* libwebp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = libwebp.modulemap; sourceTree = ""; }; - 46EB2E00008EF0 /* libwebp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "libwebp-umbrella.h"; sourceTree = ""; }; - 46EB2E00008F10 /* libwebp-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "libwebp-prefix.pch"; sourceTree = ""; }; - 46EB2E00008F20 /* libwebp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "libwebp-dummy.m"; sourceTree = ""; }; - 46EB2E00009060 /* ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist"; sourceTree = ""; }; - 46EB2E0000A1D0 /* lottie-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.debug.xcconfig"; sourceTree = ""; }; - 46EB2E0000A1E0 /* lottie-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.release.xcconfig"; sourceTree = ""; }; - 46EB2E0000A1F0 /* lottie-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "lottie-ios.modulemap"; sourceTree = ""; }; - 46EB2E0000A200 /* lottie-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-umbrella.h"; sourceTree = ""; }; - 46EB2E0000A230 /* lottie-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-prefix.pch"; sourceTree = ""; }; - 46EB2E0000A240 /* lottie-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "lottie-ios-dummy.m"; sourceTree = ""; }; - 46EB2E0000A2F0 /* Pods-CLDemo-OC.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-OC.release.xcconfig"; sourceTree = ""; }; - 46EB2E0000A300 /* Pods-CLDemo-OC.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-OC.debug.xcconfig"; sourceTree = ""; }; - 46EB2E0000A310 /* Pods-CLDemo-OC-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CLDemo-OC-resources.sh"; sourceTree = ""; }; - 46EB2E0000A320 /* Pods-CLDemo-OC-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CLDemo-OC-acknowledgements.plist"; sourceTree = ""; }; - 46EB2E0000A330 /* Pods-CLDemo-OC-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CLDemo-OC-acknowledgements.markdown"; sourceTree = ""; }; - 46EB2E0000A340 /* Pods-CLDemo-OC-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CLDemo-OC-dummy.m"; sourceTree = ""; }; - 46EB2E0000A3F0 /* Pods-CLDemo-Swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-Swift.release.xcconfig"; sourceTree = ""; }; - 46EB2E0000A400 /* Pods-CLDemo-Swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-Swift.debug.xcconfig"; sourceTree = ""; }; - 46EB2E0000A410 /* Pods-CLDemo-Swift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CLDemo-Swift.modulemap"; sourceTree = ""; }; - 46EB2E0000A420 /* Pods-CLDemo-Swift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CLDemo-Swift-umbrella.h"; sourceTree = ""; }; - 46EB2E0000A440 /* Pods-CLDemo-Swift-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CLDemo-Swift-resources.sh"; sourceTree = ""; }; - 46EB2E0000A450 /* Pods-CLDemo-Swift-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CLDemo-Swift-acknowledgements.plist"; sourceTree = ""; }; - 46EB2E0000A460 /* Pods-CLDemo-Swift-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CLDemo-Swift-acknowledgements.markdown"; sourceTree = ""; }; - 46EB2E0000A470 /* Pods-CLDemo-Swift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CLDemo-Swift-dummy.m"; sourceTree = ""; }; + 46EB2E00004970 /* CLCamera.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLCamera.debug.xcconfig; sourceTree = ""; }; + 46EB2E00004980 /* CLCamera.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLCamera.release.xcconfig; sourceTree = ""; }; + 46EB2E00004990 /* CLCamera.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CLCamera.modulemap; sourceTree = ""; }; + 46EB2E000049A0 /* CLCamera-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLCamera-umbrella.h"; sourceTree = ""; }; + 46EB2E000049D0 /* CLCamera-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLCamera-prefix.pch"; sourceTree = ""; }; + 46EB2E000049E0 /* CLCamera-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CLCamera-dummy.m"; sourceTree = ""; }; + 46EB2E00004AE0 /* CLPopoverManager.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLPopoverManager.debug.xcconfig; sourceTree = ""; }; + 46EB2E00004AF0 /* CLPopoverManager.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CLPopoverManager.release.xcconfig; sourceTree = ""; }; + 46EB2E00004B00 /* CLPopoverManager.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CLPopoverManager.modulemap; sourceTree = ""; }; + 46EB2E00004B10 /* CLPopoverManager-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLPopoverManager-umbrella.h"; sourceTree = ""; }; + 46EB2E00004B40 /* CLPopoverManager-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CLPopoverManager-prefix.pch"; sourceTree = ""; }; + 46EB2E00004B50 /* CLPopoverManager-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CLPopoverManager-dummy.m"; sourceTree = ""; }; + 46EB2E00004C90 /* ResourceBundle-CryptoSwift-CryptoSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-CryptoSwift-CryptoSwift-Info.plist"; sourceTree = ""; }; + 46EB2E000053B0 /* CryptoSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.debug.xcconfig; sourceTree = ""; }; + 46EB2E000053C0 /* CryptoSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.release.xcconfig; sourceTree = ""; }; + 46EB2E000053D0 /* CryptoSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CryptoSwift.modulemap; sourceTree = ""; }; + 46EB2E000053E0 /* CryptoSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-umbrella.h"; sourceTree = ""; }; + 46EB2E00005410 /* CryptoSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-prefix.pch"; sourceTree = ""; }; + 46EB2E00005420 /* CryptoSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CryptoSwift-dummy.m"; sourceTree = ""; }; + 46EB2E000055C0 /* DateTools.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateTools.debug.xcconfig; sourceTree = ""; }; + 46EB2E000055D0 /* DateTools.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateTools.release.xcconfig; sourceTree = ""; }; + 46EB2E000055E0 /* DateTools.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = DateTools.modulemap; sourceTree = ""; }; + 46EB2E000055F0 /* DateTools-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateTools-umbrella.h"; sourceTree = ""; }; + 46EB2E00005610 /* DateTools-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateTools-prefix.pch"; sourceTree = ""; }; + 46EB2E00005620 /* DateTools-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DateTools-dummy.m"; sourceTree = ""; }; + 46EB2E000057C0 /* DateToolsSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateToolsSwift.debug.xcconfig; sourceTree = ""; }; + 46EB2E000057D0 /* DateToolsSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DateToolsSwift.release.xcconfig; sourceTree = ""; }; + 46EB2E000057E0 /* DateToolsSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = DateToolsSwift.modulemap; sourceTree = ""; }; + 46EB2E000057F0 /* DateToolsSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateToolsSwift-umbrella.h"; sourceTree = ""; }; + 46EB2E00005820 /* DateToolsSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DateToolsSwift-prefix.pch"; sourceTree = ""; }; + 46EB2E00005830 /* DateToolsSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DateToolsSwift-dummy.m"; sourceTree = ""; }; + 46EB2E00005970 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Kingfisher-Kingfisher-Info.plist"; sourceTree = ""; }; + 46EB2E00005D70 /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; + 46EB2E00005D80 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; + 46EB2E00005D90 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; + 46EB2E00005DA0 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; + 46EB2E00005DD0 /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; + 46EB2E00005DE0 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; + 46EB2E00006700 /* LookinServer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = LookinServer.debug.xcconfig; sourceTree = ""; }; + 46EB2E00006710 /* LookinServer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = LookinServer.release.xcconfig; sourceTree = ""; }; + 46EB2E00006720 /* LookinServer.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = LookinServer.modulemap; sourceTree = ""; }; + 46EB2E00006730 /* LookinServer-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LookinServer-umbrella.h"; sourceTree = ""; }; + 46EB2E00006750 /* LookinServer-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LookinServer-prefix.pch"; sourceTree = ""; }; + 46EB2E00006760 /* LookinServer-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "LookinServer-dummy.m"; sourceTree = ""; }; + 46EB2E00006890 /* ResourceBundle-MJExtension-MJExtension-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MJExtension-MJExtension-Info.plist"; sourceTree = ""; }; + 46EB2E000069F0 /* MJExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.debug.xcconfig; sourceTree = ""; }; + 46EB2E00006A00 /* MJExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.release.xcconfig; sourceTree = ""; }; + 46EB2E00006A10 /* MJExtension.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MJExtension.modulemap; sourceTree = ""; }; + 46EB2E00006A20 /* MJExtension-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-umbrella.h"; sourceTree = ""; }; + 46EB2E00006A40 /* MJExtension-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-prefix.pch"; sourceTree = ""; }; + 46EB2E00006A50 /* MJExtension-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MJExtension-dummy.m"; sourceTree = ""; }; + 46EB2E00006C90 /* Masonry.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Masonry.debug.xcconfig; sourceTree = ""; }; + 46EB2E00006CA0 /* Masonry.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Masonry.release.xcconfig; sourceTree = ""; }; + 46EB2E00006CB0 /* Masonry.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Masonry.modulemap; sourceTree = ""; }; + 46EB2E00006CC0 /* Masonry-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Masonry-umbrella.h"; sourceTree = ""; }; + 46EB2E00006CE0 /* Masonry-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Masonry-prefix.pch"; sourceTree = ""; }; + 46EB2E00006CF0 /* Masonry-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Masonry-dummy.m"; sourceTree = ""; }; + 46EB2E00006E30 /* ResourceBundle-SDWebImage-SDWebImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SDWebImage-SDWebImage-Info.plist"; sourceTree = ""; }; + 46EB2E00007780 /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = ""; }; + 46EB2E00007790 /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = ""; }; + 46EB2E000077A0 /* SDWebImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImage.modulemap; sourceTree = ""; }; + 46EB2E000077B0 /* SDWebImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-umbrella.h"; sourceTree = ""; }; + 46EB2E000077D0 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-prefix.pch"; sourceTree = ""; }; + 46EB2E000077E0 /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImage-dummy.m"; sourceTree = ""; }; + 46EB2E00007920 /* SDWebImageWebPCoder.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImageWebPCoder.debug.xcconfig; sourceTree = ""; }; + 46EB2E00007930 /* SDWebImageWebPCoder.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImageWebPCoder.release.xcconfig; sourceTree = ""; }; + 46EB2E00007940 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImageWebPCoder.modulemap; sourceTree = ""; }; + 46EB2E00007950 /* SDWebImageWebPCoder-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImageWebPCoder-prefix.pch"; sourceTree = ""; }; + 46EB2E00007960 /* SDWebImageWebPCoder-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImageWebPCoder-dummy.m"; sourceTree = ""; }; + 46EB2E00007A90 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; sourceTree = ""; }; + 46EB2E00007CF0 /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; + 46EB2E00007D00 /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; + 46EB2E00007D10 /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; + 46EB2E00007D20 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; + 46EB2E00007D50 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 46EB2E00007D60 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; + 46EB2E00007DD0 /* SwiftFormat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftFormat.debug.xcconfig; sourceTree = ""; }; + 46EB2E00007DE0 /* SwiftFormat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftFormat.release.xcconfig; sourceTree = ""; }; + 46EB2E00007F10 /* ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist"; sourceTree = ""; }; + 46EB2E00007F30 /* SwiftyJSON.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.debug.xcconfig; sourceTree = ""; }; + 46EB2E00007F40 /* SwiftyJSON.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.release.xcconfig; sourceTree = ""; }; + 46EB2E00007F50 /* SwiftyJSON.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftyJSON.modulemap; sourceTree = ""; }; + 46EB2E00007F60 /* SwiftyJSON-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-umbrella.h"; sourceTree = ""; }; + 46EB2E00007F90 /* SwiftyJSON-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-prefix.pch"; sourceTree = ""; }; + 46EB2E00007FA0 /* SwiftyJSON-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftyJSON-dummy.m"; sourceTree = ""; }; + 46EB2E00008290 /* TZImagePickerController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TZImagePickerController.debug.xcconfig; sourceTree = ""; }; + 46EB2E000082A0 /* TZImagePickerController.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TZImagePickerController.release.xcconfig; sourceTree = ""; }; + 46EB2E000082B0 /* TZImagePickerController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = TZImagePickerController.modulemap; sourceTree = ""; }; + 46EB2E000082C0 /* TZImagePickerController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TZImagePickerController-umbrella.h"; sourceTree = ""; }; + 46EB2E000082E0 /* TZImagePickerController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TZImagePickerController-prefix.pch"; sourceTree = ""; }; + 46EB2E000082F0 /* TZImagePickerController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "TZImagePickerController-dummy.m"; sourceTree = ""; }; + 46EB2E00008E60 /* libwebp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = libwebp.debug.xcconfig; sourceTree = ""; }; + 46EB2E00008E70 /* libwebp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = libwebp.release.xcconfig; sourceTree = ""; }; + 46EB2E00008E80 /* libwebp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = libwebp.modulemap; sourceTree = ""; }; + 46EB2E00008E90 /* libwebp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "libwebp-umbrella.h"; sourceTree = ""; }; + 46EB2E00008EB0 /* libwebp-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "libwebp-prefix.pch"; sourceTree = ""; }; + 46EB2E00008EC0 /* libwebp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "libwebp-dummy.m"; sourceTree = ""; }; + 46EB2E00009000 /* ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist"; sourceTree = ""; }; + 46EB2E0000A170 /* lottie-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.debug.xcconfig"; sourceTree = ""; }; + 46EB2E0000A180 /* lottie-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.release.xcconfig"; sourceTree = ""; }; + 46EB2E0000A190 /* lottie-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "lottie-ios.modulemap"; sourceTree = ""; }; + 46EB2E0000A1A0 /* lottie-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-umbrella.h"; sourceTree = ""; }; + 46EB2E0000A1D0 /* lottie-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-prefix.pch"; sourceTree = ""; }; + 46EB2E0000A1E0 /* lottie-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "lottie-ios-dummy.m"; sourceTree = ""; }; + 46EB2E0000A290 /* Pods-CLDemo-OC.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-OC.release.xcconfig"; sourceTree = ""; }; + 46EB2E0000A2A0 /* Pods-CLDemo-OC.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-OC.debug.xcconfig"; sourceTree = ""; }; + 46EB2E0000A2B0 /* Pods-CLDemo-OC-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CLDemo-OC-resources.sh"; sourceTree = ""; }; + 46EB2E0000A2C0 /* Pods-CLDemo-OC-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CLDemo-OC-acknowledgements.plist"; sourceTree = ""; }; + 46EB2E0000A2D0 /* Pods-CLDemo-OC-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CLDemo-OC-acknowledgements.markdown"; sourceTree = ""; }; + 46EB2E0000A2E0 /* Pods-CLDemo-OC-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CLDemo-OC-dummy.m"; sourceTree = ""; }; + 46EB2E0000A390 /* Pods-CLDemo-Swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-Swift.release.xcconfig"; sourceTree = ""; }; + 46EB2E0000A3A0 /* Pods-CLDemo-Swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CLDemo-Swift.debug.xcconfig"; sourceTree = ""; }; + 46EB2E0000A3B0 /* Pods-CLDemo-Swift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CLDemo-Swift.modulemap"; sourceTree = ""; }; + 46EB2E0000A3C0 /* Pods-CLDemo-Swift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CLDemo-Swift-umbrella.h"; sourceTree = ""; }; + 46EB2E0000A3E0 /* Pods-CLDemo-Swift-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CLDemo-Swift-resources.sh"; sourceTree = ""; }; + 46EB2E0000A3F0 /* Pods-CLDemo-Swift-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CLDemo-Swift-acknowledgements.plist"; sourceTree = ""; }; + 46EB2E0000A400 /* Pods-CLDemo-Swift-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CLDemo-Swift-acknowledgements.markdown"; sourceTree = ""; }; + 46EB2E0000A410 /* Pods-CLDemo-Swift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CLDemo-Swift-dummy.m"; sourceTree = ""; }; 4AF171581392AD234F23BE913F0C22FE /* DateTools */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = DateTools; path = libDateTools.a; sourceTree = BUILT_PRODUCTS_DIR; }; 51BA97E8B5085EFFB47BC9C0B785CEA7 /* lottie-ios */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "lottie-ios"; path = "liblottie-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5E4674603A5D5B9215FFA0F8E69F8B71 /* libwebp */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libwebp; path = liblibwebp.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2604,175 +2600,175 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 46EB2E00004860 /* Frameworks */ = { + 46EB2E00004820 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004AB0 /* Frameworks */ = { + 46EB2E00004A70 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004C20 /* Frameworks */ = { + 46EB2E00004BE0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004C90 /* Frameworks */ = { + 46EB2E00004C50 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000054F0 /* Frameworks */ = { + 46EB2E000054B0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000056F0 /* Frameworks */ = { + 46EB2E000056B0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005900 /* Frameworks */ = { + 46EB2E000058C0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005970 /* Frameworks */ = { + 46EB2E00005930 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005EB0 /* Frameworks */ = { + 46EB2E00005E70 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006830 /* Frameworks */ = { + 46EB2E000067F0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000068A0 /* Frameworks */ = { + 46EB2E00006860 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006B30 /* Frameworks */ = { + 46EB2E00006AE0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006DD0 /* Frameworks */ = { + 46EB2E00006D80 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006E40 /* Frameworks */ = { + 46EB2E00006DF0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000078C0 /* Frameworks */ = { + 46EB2E00007870 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007A40 /* Frameworks */ = { + 46EB2E000079F0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007AB0 /* Frameworks */ = { + 46EB2E00007A60 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007EC0 /* Frameworks */ = { + 46EB2E00007E60 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007F30 /* Frameworks */ = { + 46EB2E00007ED0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008090 /* Frameworks */ = { + 46EB2E00008030 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000083E0 /* Frameworks */ = { + 46EB2E00008380 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008FB0 /* Frameworks */ = { + 46EB2E00008F50 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00009020 /* Frameworks */ = { + 46EB2E00008FC0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A2D0 /* Frameworks */ = { + 46EB2E0000A270 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A3D0 /* Frameworks */ = { + 46EB2E0000A370 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -2835,8 +2831,8 @@ 46EB2E00000070 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 46EB2E0000A2E0 /* Pods-CLDemo-OC */, - 46EB2E0000A3E0 /* Pods-CLDemo-Swift */, + 46EB2E0000A280 /* Pods-CLDemo-OC */, + 46EB2E0000A380 /* Pods-CLDemo-Swift */, ); name = "Targets Support Files"; sourceTree = ""; @@ -2884,7 +2880,7 @@ 46EB2E000002A0 /* NSDate+DateTools.h */, 46EB2E000002B0 /* NSDate+DateTools.m */, 46EB2E00004690 /* Resources */, - 46EB2E000055F0 /* Support Files */, + 46EB2E000055B0 /* Support Files */, ); name = DateTools; path = DateTools; @@ -2914,8 +2910,7 @@ 46EB2E000003E0 /* NSObject+MJProperty.m */, 46EB2E000003F0 /* NSString+MJExtension.h */, 46EB2E00000400 /* NSString+MJExtension.m */, - 46EB2E00004710 /* Resources */, - 46EB2E000068D0 /* Support Files */, + 46EB2E00006880 /* Support Files */, ); name = MJExtension; path = MJExtension; @@ -2949,7 +2944,7 @@ 46EB2E00000570 /* View+MASShorthandAdditions.h */, 46EB2E00000580 /* ViewController+MASAdditions.h */, 46EB2E00000590 /* ViewController+MASAdditions.m */, - 46EB2E00006CD0 /* Support Files */, + 46EB2E00006C80 /* Support Files */, ); name = Masonry; path = Masonry; @@ -2959,7 +2954,7 @@ isa = PBXGroup; children = ( 46EB2E000005A0 /* Core */, - 46EB2E00006E70 /* Support Files */, + 46EB2E00006E20 /* Support Files */, ); name = SDWebImage; path = SDWebImage; @@ -2977,7 +2972,7 @@ 46EB2E00000F20 /* SDWebImageWebPCoderDefine.m */, 46EB2E00000F30 /* UIImage+WebP.h */, 46EB2E00000F40 /* UIImage+WebP.m */, - 46EB2E00007960 /* Support Files */, + 46EB2E00007910 /* Support Files */, ); name = SDWebImageWebPCoder; path = SDWebImageWebPCoder; @@ -2989,7 +2984,7 @@ 46EB2E00000F80 /* demux */, 46EB2E00000FC0 /* mux */, 46EB2E00001040 /* sharpyuv */, - 46EB2E00008EB0 /* Support Files */, + 46EB2E00008E50 /* Support Files */, 46EB2E00001110 /* webp */, ); name = libwebp; @@ -3019,7 +3014,7 @@ 46EB2E00001B40 /* CLPermissions.swift */, 46EB2E00001AD0 /* UIImage+Extension.swift */, 46EB2E000046B0 /* Resources */, - 46EB2E000049A0 /* Support Files */, + 46EB2E00004960 /* Support Files */, ); name = CLCamera; path = CLCamera; @@ -3033,7 +3028,7 @@ 46EB2E00001BD0 /* CLPopoverManager.swift */, 46EB2E00001BE0 /* CLPopoverProtocol.swift */, 46EB2E00001BF0 /* CLPopoverWindow.swift */, - 46EB2E00004B10 /* Support Files */, + 46EB2E00004AD0 /* Support Files */, ); name = CLPopoverManager; path = CLPopoverManager; @@ -3155,8 +3150,8 @@ 46EB2E000022F0 /* XChaCha20.swift */, 46EB2E00002080 /* XChaCha20+Foundation.swift */, 46EB2E00002300 /* ZeroPadding.swift */, - 46EB2E00004750 /* Resources */, - 46EB2E00004CC0 /* Support Files */, + 46EB2E00004730 /* Resources */, + 46EB2E00004C80 /* Support Files */, ); name = CryptoSwift; path = CryptoSwift; @@ -3181,7 +3176,7 @@ 46EB2E000023E0 /* TimePeriodCollection.swift */, 46EB2E000023F0 /* TimePeriodGroup.swift */, 46EB2E000046D0 /* Resources */, - 46EB2E000057F0 /* Support Files */, + 46EB2E000057B0 /* Support Files */, ); name = DateToolsSwift; path = DateToolsSwift; @@ -3253,8 +3248,8 @@ 46EB2E000024A0 /* TVMonogramView+Kingfisher.swift */, 46EB2E000024B0 /* UIButton+Kingfisher.swift */, 46EB2E000024C0 /* WKInterfaceImage+Kingfisher.swift */, - 46EB2E00004770 /* Resources */, - 46EB2E000059A0 /* Support Files */, + 46EB2E00004750 /* Resources */, + 46EB2E00005960 /* Support Files */, ); name = Kingfisher; path = Kingfisher; @@ -3264,7 +3259,7 @@ isa = PBXGroup; children = ( 46EB2E000027F0 /* Core */, - 46EB2E00006730 /* Support Files */, + 46EB2E000066F0 /* Support Files */, ); name = LookinServer; path = LookinServer; @@ -3310,8 +3305,7 @@ 46EB2E00003290 /* LayoutConstraintItem.swift */, 46EB2E000032A0 /* Typealiases.swift */, 46EB2E000032B0 /* UILayoutSupport+Extensions.swift */, - 46EB2E00004790 /* Resources */, - 46EB2E00007AE0 /* Support Files */, + 46EB2E00007A80 /* Support Files */, ); name = SnapKit; path = SnapKit; @@ -3320,7 +3314,7 @@ 46EB2E00000180 /* SwiftFormat */ = { isa = PBXGroup; children = ( - 46EB2E00007E20 /* Support Files */, + 46EB2E00007DC0 /* Support Files */, ); name = SwiftFormat; path = SwiftFormat; @@ -3330,8 +3324,8 @@ isa = PBXGroup; children = ( 46EB2E000032C0 /* SwiftyJSON.swift */, - 46EB2E000047B0 /* Resources */, - 46EB2E00007F60 /* Support Files */, + 46EB2E00004770 /* Resources */, + 46EB2E00007F00 /* Support Files */, ); name = SwiftyJSON; path = SwiftyJSON; @@ -3342,7 +3336,7 @@ children = ( 46EB2E000032D0 /* Basic */, 46EB2E00003500 /* Location */, - 46EB2E000082E0 /* Support Files */, + 46EB2E00008280 /* Support Files */, ); name = TZImagePickerController; path = TZImagePickerController; @@ -3629,8 +3623,8 @@ 46EB2E00003A30 /* ViewType.swift */, 46EB2E00003610 /* VisibilityAnimation.swift */, 46EB2E00003930 /* WillDisplayProviding.swift */, - 46EB2E000047D0 /* Resources */, - 46EB2E00009050 /* Support Files */, + 46EB2E00004790 /* Resources */, + 46EB2E00008FF0 /* Support Files */, ); name = "lottie-ios"; path = "lottie-ios"; @@ -3787,7 +3781,7 @@ 46EB2E00000D00 /* UIView+WebCacheOperation.m */, 46EB2E00000D10 /* UIView+WebCacheState.h */, 46EB2E00000D20 /* UIView+WebCacheState.m */, - 46EB2E00004730 /* Resources */, + 46EB2E00004710 /* Resources */, ); name = Core; sourceTree = ""; @@ -4257,287 +4251,271 @@ name = Resources; sourceTree = ""; }; - 46EB2E000047B0 /* Resources */ = { + 46EB2E00004960 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E000047C0 /* PrivacyInfo.xcprivacy */, - ); - name = Resources; - sourceTree = ""; - }; - 46EB2E000047D0 /* Resources */ = { - isa = PBXGroup; - children = ( - 46EB2E000047E0 /* PrivacyInfo.xcprivacy */, - ); - name = Resources; - sourceTree = ""; - }; - 46EB2E000049A0 /* Support Files */ = { - isa = PBXGroup; - children = ( - 46EB2E000049D0 /* CLCamera.modulemap */, - 46EB2E00004A20 /* CLCamera-dummy.m */, - 46EB2E00004A10 /* CLCamera-prefix.pch */, - 46EB2E000049E0 /* CLCamera-umbrella.h */, - 46EB2E000049B0 /* CLCamera.debug.xcconfig */, - 46EB2E000049C0 /* CLCamera.release.xcconfig */, + 46EB2E00004990 /* CLCamera.modulemap */, + 46EB2E000049E0 /* CLCamera-dummy.m */, + 46EB2E000049D0 /* CLCamera-prefix.pch */, + 46EB2E000049A0 /* CLCamera-umbrella.h */, + 46EB2E00004970 /* CLCamera.debug.xcconfig */, + 46EB2E00004980 /* CLCamera.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/CLCamera"; sourceTree = ""; }; - 46EB2E00004B10 /* Support Files */ = { + 46EB2E00004AD0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00004B40 /* CLPopoverManager.modulemap */, - 46EB2E00004B90 /* CLPopoverManager-dummy.m */, - 46EB2E00004B80 /* CLPopoverManager-prefix.pch */, - 46EB2E00004B50 /* CLPopoverManager-umbrella.h */, - 46EB2E00004B20 /* CLPopoverManager.debug.xcconfig */, - 46EB2E00004B30 /* CLPopoverManager.release.xcconfig */, + 46EB2E00004B00 /* CLPopoverManager.modulemap */, + 46EB2E00004B50 /* CLPopoverManager-dummy.m */, + 46EB2E00004B40 /* CLPopoverManager-prefix.pch */, + 46EB2E00004B10 /* CLPopoverManager-umbrella.h */, + 46EB2E00004AE0 /* CLPopoverManager.debug.xcconfig */, + 46EB2E00004AF0 /* CLPopoverManager.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/CLPopoverManager"; sourceTree = ""; }; - 46EB2E00004CC0 /* Support Files */ = { + 46EB2E00004C80 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00005410 /* CryptoSwift.modulemap */, - 46EB2E00005460 /* CryptoSwift-dummy.m */, - 46EB2E00005450 /* CryptoSwift-prefix.pch */, - 46EB2E00005420 /* CryptoSwift-umbrella.h */, - 46EB2E000053F0 /* CryptoSwift.debug.xcconfig */, - 46EB2E00005400 /* CryptoSwift.release.xcconfig */, - 46EB2E00004CD0 /* ResourceBundle-CryptoSwift-CryptoSwift-Info.plist */, + 46EB2E000053D0 /* CryptoSwift.modulemap */, + 46EB2E00005420 /* CryptoSwift-dummy.m */, + 46EB2E00005410 /* CryptoSwift-prefix.pch */, + 46EB2E000053E0 /* CryptoSwift-umbrella.h */, + 46EB2E000053B0 /* CryptoSwift.debug.xcconfig */, + 46EB2E000053C0 /* CryptoSwift.release.xcconfig */, + 46EB2E00004C90 /* ResourceBundle-CryptoSwift-CryptoSwift-Info.plist */, ); name = "Support Files"; path = "../Target Support Files/CryptoSwift"; sourceTree = ""; }; - 46EB2E000055F0 /* Support Files */ = { + 46EB2E000055B0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00005620 /* DateTools.modulemap */, - 46EB2E00005660 /* DateTools-dummy.m */, - 46EB2E00005650 /* DateTools-prefix.pch */, - 46EB2E00005630 /* DateTools-umbrella.h */, - 46EB2E00005600 /* DateTools.debug.xcconfig */, - 46EB2E00005610 /* DateTools.release.xcconfig */, + 46EB2E000055E0 /* DateTools.modulemap */, + 46EB2E00005620 /* DateTools-dummy.m */, + 46EB2E00005610 /* DateTools-prefix.pch */, + 46EB2E000055F0 /* DateTools-umbrella.h */, + 46EB2E000055C0 /* DateTools.debug.xcconfig */, + 46EB2E000055D0 /* DateTools.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/DateTools"; sourceTree = ""; }; - 46EB2E000057F0 /* Support Files */ = { + 46EB2E000057B0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00005820 /* DateToolsSwift.modulemap */, - 46EB2E00005870 /* DateToolsSwift-dummy.m */, - 46EB2E00005860 /* DateToolsSwift-prefix.pch */, - 46EB2E00005830 /* DateToolsSwift-umbrella.h */, - 46EB2E00005800 /* DateToolsSwift.debug.xcconfig */, - 46EB2E00005810 /* DateToolsSwift.release.xcconfig */, + 46EB2E000057E0 /* DateToolsSwift.modulemap */, + 46EB2E00005830 /* DateToolsSwift-dummy.m */, + 46EB2E00005820 /* DateToolsSwift-prefix.pch */, + 46EB2E000057F0 /* DateToolsSwift-umbrella.h */, + 46EB2E000057C0 /* DateToolsSwift.debug.xcconfig */, + 46EB2E000057D0 /* DateToolsSwift.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/DateToolsSwift"; sourceTree = ""; }; - 46EB2E000059A0 /* Support Files */ = { + 46EB2E00005960 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00005DD0 /* Kingfisher.modulemap */, - 46EB2E00005E20 /* Kingfisher-dummy.m */, - 46EB2E00005E10 /* Kingfisher-prefix.pch */, - 46EB2E00005DE0 /* Kingfisher-umbrella.h */, - 46EB2E00005DB0 /* Kingfisher.debug.xcconfig */, - 46EB2E00005DC0 /* Kingfisher.release.xcconfig */, - 46EB2E000059B0 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */, + 46EB2E00005D90 /* Kingfisher.modulemap */, + 46EB2E00005DE0 /* Kingfisher-dummy.m */, + 46EB2E00005DD0 /* Kingfisher-prefix.pch */, + 46EB2E00005DA0 /* Kingfisher-umbrella.h */, + 46EB2E00005D70 /* Kingfisher.debug.xcconfig */, + 46EB2E00005D80 /* Kingfisher.release.xcconfig */, + 46EB2E00005970 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */, ); name = "Support Files"; path = "../Target Support Files/Kingfisher"; sourceTree = ""; }; - 46EB2E00006730 /* Support Files */ = { + 46EB2E000066F0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00006760 /* LookinServer.modulemap */, - 46EB2E000067A0 /* LookinServer-dummy.m */, - 46EB2E00006790 /* LookinServer-prefix.pch */, - 46EB2E00006770 /* LookinServer-umbrella.h */, - 46EB2E00006740 /* LookinServer.debug.xcconfig */, - 46EB2E00006750 /* LookinServer.release.xcconfig */, + 46EB2E00006720 /* LookinServer.modulemap */, + 46EB2E00006760 /* LookinServer-dummy.m */, + 46EB2E00006750 /* LookinServer-prefix.pch */, + 46EB2E00006730 /* LookinServer-umbrella.h */, + 46EB2E00006700 /* LookinServer.debug.xcconfig */, + 46EB2E00006710 /* LookinServer.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/LookinServer"; sourceTree = ""; }; - 46EB2E000068D0 /* Support Files */ = { + 46EB2E00006880 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00006A60 /* MJExtension.modulemap */, - 46EB2E00006AA0 /* MJExtension-dummy.m */, - 46EB2E00006A90 /* MJExtension-prefix.pch */, - 46EB2E00006A70 /* MJExtension-umbrella.h */, - 46EB2E00006A40 /* MJExtension.debug.xcconfig */, - 46EB2E00006A50 /* MJExtension.release.xcconfig */, - 46EB2E000068E0 /* ResourceBundle-MJExtension-MJExtension-Info.plist */, + 46EB2E00006A10 /* MJExtension.modulemap */, + 46EB2E00006A50 /* MJExtension-dummy.m */, + 46EB2E00006A40 /* MJExtension-prefix.pch */, + 46EB2E00006A20 /* MJExtension-umbrella.h */, + 46EB2E000069F0 /* MJExtension.debug.xcconfig */, + 46EB2E00006A00 /* MJExtension.release.xcconfig */, + 46EB2E00006890 /* ResourceBundle-MJExtension-MJExtension-Info.plist */, ); name = "Support Files"; path = "../Target Support Files/MJExtension"; sourceTree = ""; }; - 46EB2E00006CD0 /* Support Files */ = { + 46EB2E00006C80 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00006D00 /* Masonry.modulemap */, - 46EB2E00006D40 /* Masonry-dummy.m */, - 46EB2E00006D30 /* Masonry-prefix.pch */, - 46EB2E00006D10 /* Masonry-umbrella.h */, - 46EB2E00006CE0 /* Masonry.debug.xcconfig */, - 46EB2E00006CF0 /* Masonry.release.xcconfig */, + 46EB2E00006CB0 /* Masonry.modulemap */, + 46EB2E00006CF0 /* Masonry-dummy.m */, + 46EB2E00006CE0 /* Masonry-prefix.pch */, + 46EB2E00006CC0 /* Masonry-umbrella.h */, + 46EB2E00006C90 /* Masonry.debug.xcconfig */, + 46EB2E00006CA0 /* Masonry.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/Masonry"; sourceTree = ""; }; - 46EB2E00006E70 /* Support Files */ = { + 46EB2E00006E20 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00006E80 /* ResourceBundle-SDWebImage-SDWebImage-Info.plist */, - 46EB2E000077F0 /* SDWebImage.modulemap */, - 46EB2E00007830 /* SDWebImage-dummy.m */, - 46EB2E00007820 /* SDWebImage-prefix.pch */, - 46EB2E00007800 /* SDWebImage-umbrella.h */, - 46EB2E000077D0 /* SDWebImage.debug.xcconfig */, - 46EB2E000077E0 /* SDWebImage.release.xcconfig */, + 46EB2E00006E30 /* ResourceBundle-SDWebImage-SDWebImage-Info.plist */, + 46EB2E000077A0 /* SDWebImage.modulemap */, + 46EB2E000077E0 /* SDWebImage-dummy.m */, + 46EB2E000077D0 /* SDWebImage-prefix.pch */, + 46EB2E000077B0 /* SDWebImage-umbrella.h */, + 46EB2E00007780 /* SDWebImage.debug.xcconfig */, + 46EB2E00007790 /* SDWebImage.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SDWebImage"; sourceTree = ""; }; - 46EB2E00007960 /* Support Files */ = { + 46EB2E00007910 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00007990 /* SDWebImageWebPCoder.modulemap */, - 46EB2E000079B0 /* SDWebImageWebPCoder-dummy.m */, - 46EB2E000079A0 /* SDWebImageWebPCoder-prefix.pch */, - 46EB2E00007970 /* SDWebImageWebPCoder.debug.xcconfig */, - 46EB2E00007980 /* SDWebImageWebPCoder.release.xcconfig */, + 46EB2E00007940 /* SDWebImageWebPCoder.modulemap */, + 46EB2E00007960 /* SDWebImageWebPCoder-dummy.m */, + 46EB2E00007950 /* SDWebImageWebPCoder-prefix.pch */, + 46EB2E00007920 /* SDWebImageWebPCoder.debug.xcconfig */, + 46EB2E00007930 /* SDWebImageWebPCoder.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SDWebImageWebPCoder"; sourceTree = ""; }; - 46EB2E00007AE0 /* Support Files */ = { + 46EB2E00007A80 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00007AF0 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */, - 46EB2E00007D70 /* SnapKit.modulemap */, - 46EB2E00007DC0 /* SnapKit-dummy.m */, - 46EB2E00007DB0 /* SnapKit-prefix.pch */, - 46EB2E00007D80 /* SnapKit-umbrella.h */, - 46EB2E00007D50 /* SnapKit.debug.xcconfig */, - 46EB2E00007D60 /* SnapKit.release.xcconfig */, + 46EB2E00007A90 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */, + 46EB2E00007D10 /* SnapKit.modulemap */, + 46EB2E00007D60 /* SnapKit-dummy.m */, + 46EB2E00007D50 /* SnapKit-prefix.pch */, + 46EB2E00007D20 /* SnapKit-umbrella.h */, + 46EB2E00007CF0 /* SnapKit.debug.xcconfig */, + 46EB2E00007D00 /* SnapKit.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SnapKit"; sourceTree = ""; }; - 46EB2E00007E20 /* Support Files */ = { + 46EB2E00007DC0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00007E30 /* SwiftFormat.debug.xcconfig */, - 46EB2E00007E40 /* SwiftFormat.release.xcconfig */, + 46EB2E00007DD0 /* SwiftFormat.debug.xcconfig */, + 46EB2E00007DE0 /* SwiftFormat.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SwiftFormat"; sourceTree = ""; }; - 46EB2E00007F60 /* Support Files */ = { + 46EB2E00007F00 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00007F70 /* ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist */, - 46EB2E00007FB0 /* SwiftyJSON.modulemap */, - 46EB2E00008000 /* SwiftyJSON-dummy.m */, - 46EB2E00007FF0 /* SwiftyJSON-prefix.pch */, - 46EB2E00007FC0 /* SwiftyJSON-umbrella.h */, - 46EB2E00007F90 /* SwiftyJSON.debug.xcconfig */, - 46EB2E00007FA0 /* SwiftyJSON.release.xcconfig */, + 46EB2E00007F10 /* ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist */, + 46EB2E00007F50 /* SwiftyJSON.modulemap */, + 46EB2E00007FA0 /* SwiftyJSON-dummy.m */, + 46EB2E00007F90 /* SwiftyJSON-prefix.pch */, + 46EB2E00007F60 /* SwiftyJSON-umbrella.h */, + 46EB2E00007F30 /* SwiftyJSON.debug.xcconfig */, + 46EB2E00007F40 /* SwiftyJSON.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SwiftyJSON"; sourceTree = ""; }; - 46EB2E000082E0 /* Support Files */ = { + 46EB2E00008280 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00008310 /* TZImagePickerController.modulemap */, - 46EB2E00008350 /* TZImagePickerController-dummy.m */, - 46EB2E00008340 /* TZImagePickerController-prefix.pch */, - 46EB2E00008320 /* TZImagePickerController-umbrella.h */, - 46EB2E000082F0 /* TZImagePickerController.debug.xcconfig */, - 46EB2E00008300 /* TZImagePickerController.release.xcconfig */, + 46EB2E000082B0 /* TZImagePickerController.modulemap */, + 46EB2E000082F0 /* TZImagePickerController-dummy.m */, + 46EB2E000082E0 /* TZImagePickerController-prefix.pch */, + 46EB2E000082C0 /* TZImagePickerController-umbrella.h */, + 46EB2E00008290 /* TZImagePickerController.debug.xcconfig */, + 46EB2E000082A0 /* TZImagePickerController.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/TZImagePickerController"; sourceTree = ""; }; - 46EB2E00008EB0 /* Support Files */ = { + 46EB2E00008E50 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E00008EE0 /* libwebp.modulemap */, - 46EB2E00008F20 /* libwebp-dummy.m */, - 46EB2E00008F10 /* libwebp-prefix.pch */, - 46EB2E00008EF0 /* libwebp-umbrella.h */, - 46EB2E00008EC0 /* libwebp.debug.xcconfig */, - 46EB2E00008ED0 /* libwebp.release.xcconfig */, + 46EB2E00008E80 /* libwebp.modulemap */, + 46EB2E00008EC0 /* libwebp-dummy.m */, + 46EB2E00008EB0 /* libwebp-prefix.pch */, + 46EB2E00008E90 /* libwebp-umbrella.h */, + 46EB2E00008E60 /* libwebp.debug.xcconfig */, + 46EB2E00008E70 /* libwebp.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/libwebp"; sourceTree = ""; }; - 46EB2E00009050 /* Support Files */ = { + 46EB2E00008FF0 /* Support Files */ = { isa = PBXGroup; children = ( - 46EB2E0000A1F0 /* lottie-ios.modulemap */, - 46EB2E0000A240 /* lottie-ios-dummy.m */, - 46EB2E0000A230 /* lottie-ios-prefix.pch */, - 46EB2E0000A200 /* lottie-ios-umbrella.h */, - 46EB2E0000A1D0 /* lottie-ios.debug.xcconfig */, - 46EB2E0000A1E0 /* lottie-ios.release.xcconfig */, - 46EB2E00009060 /* ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist */, + 46EB2E0000A190 /* lottie-ios.modulemap */, + 46EB2E0000A1E0 /* lottie-ios-dummy.m */, + 46EB2E0000A1D0 /* lottie-ios-prefix.pch */, + 46EB2E0000A1A0 /* lottie-ios-umbrella.h */, + 46EB2E0000A170 /* lottie-ios.debug.xcconfig */, + 46EB2E0000A180 /* lottie-ios.release.xcconfig */, + 46EB2E00009000 /* ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist */, ); name = "Support Files"; path = "../Target Support Files/lottie-ios"; sourceTree = ""; }; - 46EB2E0000A2E0 /* Pods-CLDemo-OC */ = { + 46EB2E0000A280 /* Pods-CLDemo-OC */ = { isa = PBXGroup; children = ( - 46EB2E0000A330 /* Pods-CLDemo-OC-acknowledgements.markdown */, - 46EB2E0000A320 /* Pods-CLDemo-OC-acknowledgements.plist */, - 46EB2E0000A340 /* Pods-CLDemo-OC-dummy.m */, - 46EB2E0000A310 /* Pods-CLDemo-OC-resources.sh */, - 46EB2E0000A300 /* Pods-CLDemo-OC.debug.xcconfig */, - 46EB2E0000A2F0 /* Pods-CLDemo-OC.release.xcconfig */, + 46EB2E0000A2D0 /* Pods-CLDemo-OC-acknowledgements.markdown */, + 46EB2E0000A2C0 /* Pods-CLDemo-OC-acknowledgements.plist */, + 46EB2E0000A2E0 /* Pods-CLDemo-OC-dummy.m */, + 46EB2E0000A2B0 /* Pods-CLDemo-OC-resources.sh */, + 46EB2E0000A2A0 /* Pods-CLDemo-OC.debug.xcconfig */, + 46EB2E0000A290 /* Pods-CLDemo-OC.release.xcconfig */, ); name = "Pods-CLDemo-OC"; path = "Target Support Files/Pods-CLDemo-OC"; sourceTree = ""; }; - 46EB2E0000A3E0 /* Pods-CLDemo-Swift */ = { + 46EB2E0000A380 /* Pods-CLDemo-Swift */ = { isa = PBXGroup; children = ( - 46EB2E0000A410 /* Pods-CLDemo-Swift.modulemap */, - 46EB2E0000A460 /* Pods-CLDemo-Swift-acknowledgements.markdown */, - 46EB2E0000A450 /* Pods-CLDemo-Swift-acknowledgements.plist */, - 46EB2E0000A470 /* Pods-CLDemo-Swift-dummy.m */, - 46EB2E0000A440 /* Pods-CLDemo-Swift-resources.sh */, - 46EB2E0000A420 /* Pods-CLDemo-Swift-umbrella.h */, - 46EB2E0000A400 /* Pods-CLDemo-Swift.debug.xcconfig */, - 46EB2E0000A3F0 /* Pods-CLDemo-Swift.release.xcconfig */, + 46EB2E0000A3B0 /* Pods-CLDemo-Swift.modulemap */, + 46EB2E0000A400 /* Pods-CLDemo-Swift-acknowledgements.markdown */, + 46EB2E0000A3F0 /* Pods-CLDemo-Swift-acknowledgements.plist */, + 46EB2E0000A410 /* Pods-CLDemo-Swift-dummy.m */, + 46EB2E0000A3E0 /* Pods-CLDemo-Swift-resources.sh */, + 46EB2E0000A3C0 /* Pods-CLDemo-Swift-umbrella.h */, + 46EB2E0000A3A0 /* Pods-CLDemo-Swift.debug.xcconfig */, + 46EB2E0000A390 /* Pods-CLDemo-Swift.release.xcconfig */, ); name = "Pods-CLDemo-Swift"; path = "Target Support Files/Pods-CLDemo-Swift"; @@ -4546,400 +4524,400 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 46EB2E00004840 /* Headers */ = { + 46EB2E00004800 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000049F0 /* CLCamera-umbrella.h in Headers */, + 46EB2E000049B0 /* CLCamera-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004A90 /* Headers */ = { + 46EB2E00004A50 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00004B60 /* CLPopoverManager-umbrella.h in Headers */, + 46EB2E00004B20 /* CLPopoverManager-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004C00 /* Headers */ = { + 46EB2E00004BC0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005430 /* CryptoSwift-umbrella.h in Headers */, + 46EB2E000053F0 /* CryptoSwift-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000054D0 /* Headers */ = { + 46EB2E00005490 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005570 /* DateTools.h in Headers */, - 46EB2E00005640 /* DateTools-umbrella.h in Headers */, - 46EB2E00005580 /* DTConstants.h in Headers */, - 46EB2E00005590 /* DTError.h in Headers */, - 46EB2E000055A0 /* DTTimePeriod.h in Headers */, - 46EB2E000055B0 /* DTTimePeriodChain.h in Headers */, - 46EB2E000055C0 /* DTTimePeriodCollection.h in Headers */, - 46EB2E000055D0 /* DTTimePeriodGroup.h in Headers */, - 46EB2E000055E0 /* NSDate+DateTools.h in Headers */, + 46EB2E00005530 /* DateTools.h in Headers */, + 46EB2E00005600 /* DateTools-umbrella.h in Headers */, + 46EB2E00005540 /* DTConstants.h in Headers */, + 46EB2E00005550 /* DTError.h in Headers */, + 46EB2E00005560 /* DTTimePeriod.h in Headers */, + 46EB2E00005570 /* DTTimePeriodChain.h in Headers */, + 46EB2E00005580 /* DTTimePeriodCollection.h in Headers */, + 46EB2E00005590 /* DTTimePeriodGroup.h in Headers */, + 46EB2E000055A0 /* NSDate+DateTools.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000056D0 /* Headers */ = { + 46EB2E00005690 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005840 /* DateToolsSwift-umbrella.h in Headers */, + 46EB2E00005800 /* DateToolsSwift-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000058E0 /* Headers */ = { + 46EB2E000058A0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005DF0 /* Kingfisher-umbrella.h in Headers */, + 46EB2E00005DB0 /* Kingfisher-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005E90 /* Headers */ = { + 46EB2E00005E50 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000064E0 /* CALayer+Lookin.h in Headers */, - 46EB2E000062C0 /* CALayer+LookinServer.h in Headers */, - 46EB2E000064F0 /* Color+Lookin.h in Headers */, - 46EB2E00006500 /* Image+Lookin.h in Headers */, - 46EB2E00006410 /* LKS_AttrGroupsMaker.h in Headers */, - 46EB2E000063B0 /* LKS_AttrModificationPatchHandler.h in Headers */, - 46EB2E00006390 /* LKS_ConnectionManager.h in Headers */, - 46EB2E00006420 /* LKS_CustomAttrGroupsMaker.h in Headers */, - 46EB2E000063C0 /* LKS_CustomAttrModificationHandler.h in Headers */, - 46EB2E00006430 /* LKS_CustomAttrSetterManager.h in Headers */, - 46EB2E00006440 /* LKS_CustomDisplayItemsMaker.h in Headers */, - 46EB2E00006450 /* LKS_EventHandlerMaker.h in Headers */, - 46EB2E00006460 /* LKS_ExportManager.h in Headers */, - 46EB2E00006470 /* LKS_GestureTargetActionsSearcher.h in Headers */, - 46EB2E00006480 /* LKS_Helper.h in Headers */, - 46EB2E000063D0 /* LKS_HierarchyDetailsHandler.h in Headers */, - 46EB2E00006490 /* LKS_HierarchyDisplayItemsMaker.h in Headers */, - 46EB2E000063E0 /* LKS_InbuiltAttrModificationHandler.h in Headers */, - 46EB2E000064A0 /* LKS_MultiplatformAdapter.h in Headers */, - 46EB2E000064B0 /* LKS_ObjectRegistry.h in Headers */, - 46EB2E000063A0 /* LKS_RequestHandler.h in Headers */, - 46EB2E000064C0 /* LKS_TraceManager.h in Headers */, - 46EB2E00006400 /* LKSConfigManager.h in Headers */, - 46EB2E000066D0 /* Lookin_PTChannel.h in Headers */, - 46EB2E000066E0 /* Lookin_PTPrivate.h in Headers */, - 46EB2E000066F0 /* Lookin_PTProtocol.h in Headers */, - 46EB2E00006700 /* Lookin_PTUSBHub.h in Headers */, - 46EB2E00006550 /* LookinAppInfo.h in Headers */, - 46EB2E00006560 /* LookinAttribute.h in Headers */, - 46EB2E00006570 /* LookinAttributeModification.h in Headers */, - 46EB2E00006580 /* LookinAttributesGroup.h in Headers */, - 46EB2E00006590 /* LookinAttributesSection.h in Headers */, - 46EB2E000065A0 /* LookinAttrIdentifiers.h in Headers */, - 46EB2E000065B0 /* LookinAttrType.h in Headers */, - 46EB2E000065C0 /* LookinAutoLayoutConstraint.h in Headers */, - 46EB2E000065D0 /* LookinCodingValueType.h in Headers */, - 46EB2E000065E0 /* LookinConnectionAttachment.h in Headers */, - 46EB2E000065F0 /* LookinConnectionResponseAttachment.h in Headers */, - 46EB2E00006600 /* LookinCustomAttrModification.h in Headers */, - 46EB2E00006610 /* LookinCustomDisplayItemInfo.h in Headers */, - 46EB2E00006620 /* LookinDashboardBlueprint.h in Headers */, - 46EB2E00006630 /* LookinDefines.h in Headers */, - 46EB2E00006640 /* LookinDisplayItem.h in Headers */, - 46EB2E00006650 /* LookinDisplayItemDetail.h in Headers */, - 46EB2E00006660 /* LookinEventHandler.h in Headers */, - 46EB2E00006670 /* LookinHierarchyFile.h in Headers */, - 46EB2E00006680 /* LookinHierarchyInfo.h in Headers */, - 46EB2E00006720 /* LookinIvarTrace.h in Headers */, - 46EB2E00006690 /* LookinObject.h in Headers */, - 46EB2E000063F0 /* LookinServer.h in Headers */, - 46EB2E00006780 /* LookinServer-umbrella.h in Headers */, - 46EB2E000064D0 /* LookinServerDefines.h in Headers */, - 46EB2E000066A0 /* LookinStaticAsyncUpdateTask.h in Headers */, - 46EB2E000066B0 /* LookinTuple.h in Headers */, - 46EB2E000066C0 /* LookinWeakContainer.h in Headers */, - 46EB2E00006510 /* NSArray+Lookin.h in Headers */, - 46EB2E00006520 /* NSObject+Lookin.h in Headers */, - 46EB2E000062D0 /* NSObject+LookinServer.h in Headers */, - 46EB2E00006530 /* NSSet+Lookin.h in Headers */, - 46EB2E00006540 /* NSString+Lookin.h in Headers */, - 46EB2E00006710 /* Peertalk.h in Headers */, - 46EB2E000062E0 /* UIBlurEffect+LookinServer.h in Headers */, - 46EB2E000062F0 /* UIColor+LookinServer.h in Headers */, - 46EB2E00006300 /* UIImage+LookinServer.h in Headers */, - 46EB2E00006310 /* UIImageView+LookinServer.h in Headers */, - 46EB2E00006320 /* UILabel+LookinServer.h in Headers */, - 46EB2E00006330 /* UITableView+LookinServer.h in Headers */, - 46EB2E00006340 /* UITextField+LookinServer.h in Headers */, - 46EB2E00006350 /* UITextView+LookinServer.h in Headers */, - 46EB2E00006360 /* UIView+LookinServer.h in Headers */, - 46EB2E00006370 /* UIViewController+LookinServer.h in Headers */, - 46EB2E00006380 /* UIVisualEffectView+LookinServer.h in Headers */, + 46EB2E000064A0 /* CALayer+Lookin.h in Headers */, + 46EB2E00006280 /* CALayer+LookinServer.h in Headers */, + 46EB2E000064B0 /* Color+Lookin.h in Headers */, + 46EB2E000064C0 /* Image+Lookin.h in Headers */, + 46EB2E000063D0 /* LKS_AttrGroupsMaker.h in Headers */, + 46EB2E00006370 /* LKS_AttrModificationPatchHandler.h in Headers */, + 46EB2E00006350 /* LKS_ConnectionManager.h in Headers */, + 46EB2E000063E0 /* LKS_CustomAttrGroupsMaker.h in Headers */, + 46EB2E00006380 /* LKS_CustomAttrModificationHandler.h in Headers */, + 46EB2E000063F0 /* LKS_CustomAttrSetterManager.h in Headers */, + 46EB2E00006400 /* LKS_CustomDisplayItemsMaker.h in Headers */, + 46EB2E00006410 /* LKS_EventHandlerMaker.h in Headers */, + 46EB2E00006420 /* LKS_ExportManager.h in Headers */, + 46EB2E00006430 /* LKS_GestureTargetActionsSearcher.h in Headers */, + 46EB2E00006440 /* LKS_Helper.h in Headers */, + 46EB2E00006390 /* LKS_HierarchyDetailsHandler.h in Headers */, + 46EB2E00006450 /* LKS_HierarchyDisplayItemsMaker.h in Headers */, + 46EB2E000063A0 /* LKS_InbuiltAttrModificationHandler.h in Headers */, + 46EB2E00006460 /* LKS_MultiplatformAdapter.h in Headers */, + 46EB2E00006470 /* LKS_ObjectRegistry.h in Headers */, + 46EB2E00006360 /* LKS_RequestHandler.h in Headers */, + 46EB2E00006480 /* LKS_TraceManager.h in Headers */, + 46EB2E000063C0 /* LKSConfigManager.h in Headers */, + 46EB2E00006690 /* Lookin_PTChannel.h in Headers */, + 46EB2E000066A0 /* Lookin_PTPrivate.h in Headers */, + 46EB2E000066B0 /* Lookin_PTProtocol.h in Headers */, + 46EB2E000066C0 /* Lookin_PTUSBHub.h in Headers */, + 46EB2E00006510 /* LookinAppInfo.h in Headers */, + 46EB2E00006520 /* LookinAttribute.h in Headers */, + 46EB2E00006530 /* LookinAttributeModification.h in Headers */, + 46EB2E00006540 /* LookinAttributesGroup.h in Headers */, + 46EB2E00006550 /* LookinAttributesSection.h in Headers */, + 46EB2E00006560 /* LookinAttrIdentifiers.h in Headers */, + 46EB2E00006570 /* LookinAttrType.h in Headers */, + 46EB2E00006580 /* LookinAutoLayoutConstraint.h in Headers */, + 46EB2E00006590 /* LookinCodingValueType.h in Headers */, + 46EB2E000065A0 /* LookinConnectionAttachment.h in Headers */, + 46EB2E000065B0 /* LookinConnectionResponseAttachment.h in Headers */, + 46EB2E000065C0 /* LookinCustomAttrModification.h in Headers */, + 46EB2E000065D0 /* LookinCustomDisplayItemInfo.h in Headers */, + 46EB2E000065E0 /* LookinDashboardBlueprint.h in Headers */, + 46EB2E000065F0 /* LookinDefines.h in Headers */, + 46EB2E00006600 /* LookinDisplayItem.h in Headers */, + 46EB2E00006610 /* LookinDisplayItemDetail.h in Headers */, + 46EB2E00006620 /* LookinEventHandler.h in Headers */, + 46EB2E00006630 /* LookinHierarchyFile.h in Headers */, + 46EB2E00006640 /* LookinHierarchyInfo.h in Headers */, + 46EB2E000066E0 /* LookinIvarTrace.h in Headers */, + 46EB2E00006650 /* LookinObject.h in Headers */, + 46EB2E000063B0 /* LookinServer.h in Headers */, + 46EB2E00006740 /* LookinServer-umbrella.h in Headers */, + 46EB2E00006490 /* LookinServerDefines.h in Headers */, + 46EB2E00006660 /* LookinStaticAsyncUpdateTask.h in Headers */, + 46EB2E00006670 /* LookinTuple.h in Headers */, + 46EB2E00006680 /* LookinWeakContainer.h in Headers */, + 46EB2E000064D0 /* NSArray+Lookin.h in Headers */, + 46EB2E000064E0 /* NSObject+Lookin.h in Headers */, + 46EB2E00006290 /* NSObject+LookinServer.h in Headers */, + 46EB2E000064F0 /* NSSet+Lookin.h in Headers */, + 46EB2E00006500 /* NSString+Lookin.h in Headers */, + 46EB2E000066D0 /* Peertalk.h in Headers */, + 46EB2E000062A0 /* UIBlurEffect+LookinServer.h in Headers */, + 46EB2E000062B0 /* UIColor+LookinServer.h in Headers */, + 46EB2E000062C0 /* UIImage+LookinServer.h in Headers */, + 46EB2E000062D0 /* UIImageView+LookinServer.h in Headers */, + 46EB2E000062E0 /* UILabel+LookinServer.h in Headers */, + 46EB2E000062F0 /* UITableView+LookinServer.h in Headers */, + 46EB2E00006300 /* UITextField+LookinServer.h in Headers */, + 46EB2E00006310 /* UITextView+LookinServer.h in Headers */, + 46EB2E00006320 /* UIView+LookinServer.h in Headers */, + 46EB2E00006330 /* UIViewController+LookinServer.h in Headers */, + 46EB2E00006340 /* UIVisualEffectView+LookinServer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006810 /* Headers */ = { + 46EB2E000067D0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00006990 /* MJExtension.h in Headers */, - 46EB2E00006A80 /* MJExtension-umbrella.h in Headers */, - 46EB2E000069A0 /* MJExtensionConst.h in Headers */, - 46EB2E000069B0 /* MJFoundation.h in Headers */, - 46EB2E000069C0 /* MJProperty.h in Headers */, - 46EB2E000069D0 /* MJPropertyKey.h in Headers */, - 46EB2E000069E0 /* MJPropertyType.h in Headers */, - 46EB2E000069F0 /* NSObject+MJClass.h in Headers */, - 46EB2E00006A00 /* NSObject+MJCoding.h in Headers */, - 46EB2E00006A10 /* NSObject+MJKeyValue.h in Headers */, - 46EB2E00006A20 /* NSObject+MJProperty.h in Headers */, - 46EB2E00006A30 /* NSString+MJExtension.h in Headers */, + 46EB2E00006940 /* MJExtension.h in Headers */, + 46EB2E00006A30 /* MJExtension-umbrella.h in Headers */, + 46EB2E00006950 /* MJExtensionConst.h in Headers */, + 46EB2E00006960 /* MJFoundation.h in Headers */, + 46EB2E00006970 /* MJProperty.h in Headers */, + 46EB2E00006980 /* MJPropertyKey.h in Headers */, + 46EB2E00006990 /* MJPropertyType.h in Headers */, + 46EB2E000069A0 /* NSObject+MJClass.h in Headers */, + 46EB2E000069B0 /* NSObject+MJCoding.h in Headers */, + 46EB2E000069C0 /* NSObject+MJKeyValue.h in Headers */, + 46EB2E000069D0 /* NSObject+MJProperty.h in Headers */, + 46EB2E000069E0 /* NSString+MJExtension.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006B10 /* Headers */ = { + 46EB2E00006AC0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00006BE0 /* MASCompositeConstraint.h in Headers */, - 46EB2E00006C00 /* MASConstraint.h in Headers */, - 46EB2E00006BF0 /* MASConstraint+Private.h in Headers */, - 46EB2E00006C10 /* MASConstraintMaker.h in Headers */, - 46EB2E00006C20 /* MASLayoutConstraint.h in Headers */, - 46EB2E00006C30 /* Masonry.h in Headers */, - 46EB2E00006D20 /* Masonry-umbrella.h in Headers */, - 46EB2E00006C40 /* MASUtilities.h in Headers */, - 46EB2E00006C50 /* MASViewAttribute.h in Headers */, - 46EB2E00006C60 /* MASViewConstraint.h in Headers */, - 46EB2E00006C70 /* NSArray+MASAdditions.h in Headers */, - 46EB2E00006C80 /* NSArray+MASShorthandAdditions.h in Headers */, - 46EB2E00006C90 /* NSLayoutConstraint+MASDebugAdditions.h in Headers */, - 46EB2E00006CA0 /* View+MASAdditions.h in Headers */, - 46EB2E00006CB0 /* View+MASShorthandAdditions.h in Headers */, - 46EB2E00006CC0 /* ViewController+MASAdditions.h in Headers */, + 46EB2E00006B90 /* MASCompositeConstraint.h in Headers */, + 46EB2E00006BB0 /* MASConstraint.h in Headers */, + 46EB2E00006BA0 /* MASConstraint+Private.h in Headers */, + 46EB2E00006BC0 /* MASConstraintMaker.h in Headers */, + 46EB2E00006BD0 /* MASLayoutConstraint.h in Headers */, + 46EB2E00006BE0 /* Masonry.h in Headers */, + 46EB2E00006CD0 /* Masonry-umbrella.h in Headers */, + 46EB2E00006BF0 /* MASUtilities.h in Headers */, + 46EB2E00006C00 /* MASViewAttribute.h in Headers */, + 46EB2E00006C10 /* MASViewConstraint.h in Headers */, + 46EB2E00006C20 /* NSArray+MASAdditions.h in Headers */, + 46EB2E00006C30 /* NSArray+MASShorthandAdditions.h in Headers */, + 46EB2E00006C40 /* NSLayoutConstraint+MASDebugAdditions.h in Headers */, + 46EB2E00006C50 /* View+MASAdditions.h in Headers */, + 46EB2E00006C60 /* View+MASShorthandAdditions.h in Headers */, + 46EB2E00006C70 /* ViewController+MASAdditions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006DB0 /* Headers */ = { + 46EB2E00006D60 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000076E0 /* NSBezierPath+SDRoundedCorners.h in Headers */, - 46EB2E00007310 /* NSButton+WebCache.h in Headers */, - 46EB2E00007320 /* NSData+ImageContentType.h in Headers */, - 46EB2E00007330 /* NSImage+Compatibility.h in Headers */, - 46EB2E00007340 /* SDAnimatedImage.h in Headers */, - 46EB2E00007350 /* SDAnimatedImagePlayer.h in Headers */, - 46EB2E00007360 /* SDAnimatedImageRep.h in Headers */, - 46EB2E00007380 /* SDAnimatedImageView.h in Headers */, - 46EB2E00007370 /* SDAnimatedImageView+WebCache.h in Headers */, - 46EB2E000076F0 /* SDAssociatedObject.h in Headers */, - 46EB2E00007700 /* SDAsyncBlockOperation.h in Headers */, - 46EB2E00007390 /* SDCallbackQueue.h in Headers */, - 46EB2E00007710 /* SDDeviceHelper.h in Headers */, - 46EB2E000073A0 /* SDDiskCache.h in Headers */, - 46EB2E00007720 /* SDDisplayLink.h in Headers */, - 46EB2E00007730 /* SDFileAttributeHelper.h in Headers */, - 46EB2E000073B0 /* SDGraphicsImageRenderer.h in Headers */, - 46EB2E000073C0 /* SDImageAPNGCoder.h in Headers */, - 46EB2E00007740 /* SDImageAssetManager.h in Headers */, - 46EB2E000073D0 /* SDImageAWebPCoder.h in Headers */, - 46EB2E000073E0 /* SDImageCache.h in Headers */, - 46EB2E000073F0 /* SDImageCacheConfig.h in Headers */, - 46EB2E00007400 /* SDImageCacheDefine.h in Headers */, - 46EB2E00007410 /* SDImageCachesManager.h in Headers */, - 46EB2E00007750 /* SDImageCachesManagerOperation.h in Headers */, - 46EB2E00007420 /* SDImageCoder.h in Headers */, - 46EB2E00007430 /* SDImageCoderHelper.h in Headers */, - 46EB2E00007440 /* SDImageCodersManager.h in Headers */, - 46EB2E00007450 /* SDImageFrame.h in Headers */, - 46EB2E00007760 /* SDImageFramePool.h in Headers */, - 46EB2E00007460 /* SDImageGIFCoder.h in Headers */, - 46EB2E00007470 /* SDImageGraphics.h in Headers */, - 46EB2E00007480 /* SDImageHEICCoder.h in Headers */, - 46EB2E00007490 /* SDImageIOAnimatedCoder.h in Headers */, - 46EB2E00007770 /* SDImageIOAnimatedCoderInternal.h in Headers */, - 46EB2E000074A0 /* SDImageIOCoder.h in Headers */, - 46EB2E000074B0 /* SDImageLoader.h in Headers */, - 46EB2E000074C0 /* SDImageLoadersManager.h in Headers */, - 46EB2E000074D0 /* SDImageTransformer.h in Headers */, - 46EB2E00007780 /* SDInternalMacros.h in Headers */, - 46EB2E000074E0 /* SDMemoryCache.h in Headers */, - 46EB2E00007790 /* SDmetamacros.h in Headers */, - 46EB2E000077A0 /* SDWeakProxy.h in Headers */, - 46EB2E000076D0 /* SDWebImage.h in Headers */, - 46EB2E00007810 /* SDWebImage-umbrella.h in Headers */, - 46EB2E000074F0 /* SDWebImageCacheKeyFilter.h in Headers */, - 46EB2E00007500 /* SDWebImageCacheSerializer.h in Headers */, - 46EB2E00007510 /* SDWebImageCompat.h in Headers */, - 46EB2E00007520 /* SDWebImageDefine.h in Headers */, - 46EB2E00007530 /* SDWebImageDownloader.h in Headers */, - 46EB2E00007540 /* SDWebImageDownloaderConfig.h in Headers */, - 46EB2E00007550 /* SDWebImageDownloaderDecryptor.h in Headers */, - 46EB2E00007560 /* SDWebImageDownloaderOperation.h in Headers */, - 46EB2E00007570 /* SDWebImageDownloaderRequestModifier.h in Headers */, - 46EB2E00007580 /* SDWebImageDownloaderResponseModifier.h in Headers */, - 46EB2E00007590 /* SDWebImageError.h in Headers */, - 46EB2E000075A0 /* SDWebImageIndicator.h in Headers */, - 46EB2E000075B0 /* SDWebImageManager.h in Headers */, - 46EB2E000075C0 /* SDWebImageOperation.h in Headers */, - 46EB2E000075D0 /* SDWebImageOptionsProcessor.h in Headers */, - 46EB2E000075E0 /* SDWebImagePrefetcher.h in Headers */, - 46EB2E000075F0 /* SDWebImageTransition.h in Headers */, - 46EB2E000077B0 /* SDWebImageTransitionInternal.h in Headers */, - 46EB2E00007600 /* UIButton+WebCache.h in Headers */, - 46EB2E000077C0 /* UIColor+SDHexString.h in Headers */, - 46EB2E00007610 /* UIImage+ExtendedCacheData.h in Headers */, - 46EB2E00007620 /* UIImage+ForceDecode.h in Headers */, - 46EB2E00007630 /* UIImage+GIF.h in Headers */, - 46EB2E00007640 /* UIImage+MemoryCacheCost.h in Headers */, - 46EB2E00007650 /* UIImage+Metadata.h in Headers */, - 46EB2E00007660 /* UIImage+MultiFormat.h in Headers */, - 46EB2E00007670 /* UIImage+Transform.h in Headers */, - 46EB2E00007680 /* UIImageView+HighlightedWebCache.h in Headers */, - 46EB2E00007690 /* UIImageView+WebCache.h in Headers */, - 46EB2E000076A0 /* UIView+WebCache.h in Headers */, - 46EB2E000076B0 /* UIView+WebCacheOperation.h in Headers */, - 46EB2E000076C0 /* UIView+WebCacheState.h in Headers */, + 46EB2E00007690 /* NSBezierPath+SDRoundedCorners.h in Headers */, + 46EB2E000072C0 /* NSButton+WebCache.h in Headers */, + 46EB2E000072D0 /* NSData+ImageContentType.h in Headers */, + 46EB2E000072E0 /* NSImage+Compatibility.h in Headers */, + 46EB2E000072F0 /* SDAnimatedImage.h in Headers */, + 46EB2E00007300 /* SDAnimatedImagePlayer.h in Headers */, + 46EB2E00007310 /* SDAnimatedImageRep.h in Headers */, + 46EB2E00007330 /* SDAnimatedImageView.h in Headers */, + 46EB2E00007320 /* SDAnimatedImageView+WebCache.h in Headers */, + 46EB2E000076A0 /* SDAssociatedObject.h in Headers */, + 46EB2E000076B0 /* SDAsyncBlockOperation.h in Headers */, + 46EB2E00007340 /* SDCallbackQueue.h in Headers */, + 46EB2E000076C0 /* SDDeviceHelper.h in Headers */, + 46EB2E00007350 /* SDDiskCache.h in Headers */, + 46EB2E000076D0 /* SDDisplayLink.h in Headers */, + 46EB2E000076E0 /* SDFileAttributeHelper.h in Headers */, + 46EB2E00007360 /* SDGraphicsImageRenderer.h in Headers */, + 46EB2E00007370 /* SDImageAPNGCoder.h in Headers */, + 46EB2E000076F0 /* SDImageAssetManager.h in Headers */, + 46EB2E00007380 /* SDImageAWebPCoder.h in Headers */, + 46EB2E00007390 /* SDImageCache.h in Headers */, + 46EB2E000073A0 /* SDImageCacheConfig.h in Headers */, + 46EB2E000073B0 /* SDImageCacheDefine.h in Headers */, + 46EB2E000073C0 /* SDImageCachesManager.h in Headers */, + 46EB2E00007700 /* SDImageCachesManagerOperation.h in Headers */, + 46EB2E000073D0 /* SDImageCoder.h in Headers */, + 46EB2E000073E0 /* SDImageCoderHelper.h in Headers */, + 46EB2E000073F0 /* SDImageCodersManager.h in Headers */, + 46EB2E00007400 /* SDImageFrame.h in Headers */, + 46EB2E00007710 /* SDImageFramePool.h in Headers */, + 46EB2E00007410 /* SDImageGIFCoder.h in Headers */, + 46EB2E00007420 /* SDImageGraphics.h in Headers */, + 46EB2E00007430 /* SDImageHEICCoder.h in Headers */, + 46EB2E00007440 /* SDImageIOAnimatedCoder.h in Headers */, + 46EB2E00007720 /* SDImageIOAnimatedCoderInternal.h in Headers */, + 46EB2E00007450 /* SDImageIOCoder.h in Headers */, + 46EB2E00007460 /* SDImageLoader.h in Headers */, + 46EB2E00007470 /* SDImageLoadersManager.h in Headers */, + 46EB2E00007480 /* SDImageTransformer.h in Headers */, + 46EB2E00007730 /* SDInternalMacros.h in Headers */, + 46EB2E00007490 /* SDMemoryCache.h in Headers */, + 46EB2E00007740 /* SDmetamacros.h in Headers */, + 46EB2E00007750 /* SDWeakProxy.h in Headers */, + 46EB2E00007680 /* SDWebImage.h in Headers */, + 46EB2E000077C0 /* SDWebImage-umbrella.h in Headers */, + 46EB2E000074A0 /* SDWebImageCacheKeyFilter.h in Headers */, + 46EB2E000074B0 /* SDWebImageCacheSerializer.h in Headers */, + 46EB2E000074C0 /* SDWebImageCompat.h in Headers */, + 46EB2E000074D0 /* SDWebImageDefine.h in Headers */, + 46EB2E000074E0 /* SDWebImageDownloader.h in Headers */, + 46EB2E000074F0 /* SDWebImageDownloaderConfig.h in Headers */, + 46EB2E00007500 /* SDWebImageDownloaderDecryptor.h in Headers */, + 46EB2E00007510 /* SDWebImageDownloaderOperation.h in Headers */, + 46EB2E00007520 /* SDWebImageDownloaderRequestModifier.h in Headers */, + 46EB2E00007530 /* SDWebImageDownloaderResponseModifier.h in Headers */, + 46EB2E00007540 /* SDWebImageError.h in Headers */, + 46EB2E00007550 /* SDWebImageIndicator.h in Headers */, + 46EB2E00007560 /* SDWebImageManager.h in Headers */, + 46EB2E00007570 /* SDWebImageOperation.h in Headers */, + 46EB2E00007580 /* SDWebImageOptionsProcessor.h in Headers */, + 46EB2E00007590 /* SDWebImagePrefetcher.h in Headers */, + 46EB2E000075A0 /* SDWebImageTransition.h in Headers */, + 46EB2E00007760 /* SDWebImageTransitionInternal.h in Headers */, + 46EB2E000075B0 /* UIButton+WebCache.h in Headers */, + 46EB2E00007770 /* UIColor+SDHexString.h in Headers */, + 46EB2E000075C0 /* UIImage+ExtendedCacheData.h in Headers */, + 46EB2E000075D0 /* UIImage+ForceDecode.h in Headers */, + 46EB2E000075E0 /* UIImage+GIF.h in Headers */, + 46EB2E000075F0 /* UIImage+MemoryCacheCost.h in Headers */, + 46EB2E00007600 /* UIImage+Metadata.h in Headers */, + 46EB2E00007610 /* UIImage+MultiFormat.h in Headers */, + 46EB2E00007620 /* UIImage+Transform.h in Headers */, + 46EB2E00007630 /* UIImageView+HighlightedWebCache.h in Headers */, + 46EB2E00007640 /* UIImageView+WebCache.h in Headers */, + 46EB2E00007650 /* UIView+WebCache.h in Headers */, + 46EB2E00007660 /* UIView+WebCacheOperation.h in Headers */, + 46EB2E00007670 /* UIView+WebCacheState.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000078A0 /* Headers */ = { + 46EB2E00007850 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007900 /* SDImageWebPCoder.h in Headers */, - 46EB2E00007930 /* SDInternalMacros.h in Headers */, - 46EB2E00007940 /* SDmetamacros.h in Headers */, - 46EB2E00007950 /* SDWebImageWebPCoder.h in Headers */, - 46EB2E00007910 /* SDWebImageWebPCoderDefine.h in Headers */, - 46EB2E00007920 /* UIImage+WebP.h in Headers */, + 46EB2E000078B0 /* SDImageWebPCoder.h in Headers */, + 46EB2E000078E0 /* SDInternalMacros.h in Headers */, + 46EB2E000078F0 /* SDmetamacros.h in Headers */, + 46EB2E00007900 /* SDWebImageWebPCoder.h in Headers */, + 46EB2E000078C0 /* SDWebImageWebPCoderDefine.h in Headers */, + 46EB2E000078D0 /* UIImage+WebP.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007A20 /* Headers */ = { + 46EB2E000079D0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007D90 /* SnapKit-umbrella.h in Headers */, + 46EB2E00007D30 /* SnapKit-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007EA0 /* Headers */ = { + 46EB2E00007E40 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007FD0 /* SwiftyJSON-umbrella.h in Headers */, + 46EB2E00007F70 /* SwiftyJSON-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008070 /* Headers */ = { + 46EB2E00008010 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000081B0 /* NSBundle+TZImagePicker.h in Headers */, - 46EB2E000081C0 /* TZAssetCell.h in Headers */, - 46EB2E000081D0 /* TZAssetModel.h in Headers */, - 46EB2E000081E0 /* TZAuthLimitedFooterTipView.h in Headers */, - 46EB2E000081F0 /* TZGifPhotoPreviewController.h in Headers */, - 46EB2E00008200 /* TZImageCropManager.h in Headers */, - 46EB2E00008210 /* TZImageManager.h in Headers */, - 46EB2E00008220 /* TZImagePickerController.h in Headers */, - 46EB2E00008330 /* TZImagePickerController-umbrella.h in Headers */, - 46EB2E00008230 /* TZImageRequestOperation.h in Headers */, - 46EB2E000082D0 /* TZLocationManager.h in Headers */, - 46EB2E00008240 /* TZPhotoPickerController.h in Headers */, - 46EB2E00008250 /* TZPhotoPreviewCell.h in Headers */, - 46EB2E00008260 /* TZPhotoPreviewController.h in Headers */, - 46EB2E00008270 /* TZProgressView.h in Headers */, - 46EB2E00008280 /* TZVideoCropController.h in Headers */, - 46EB2E00008290 /* TZVideoEditedPreviewController.h in Headers */, - 46EB2E000082A0 /* TZVideoPlayerController.h in Headers */, - 46EB2E000082B0 /* UIView+TZLayout.h in Headers */, + 46EB2E00008150 /* NSBundle+TZImagePicker.h in Headers */, + 46EB2E00008160 /* TZAssetCell.h in Headers */, + 46EB2E00008170 /* TZAssetModel.h in Headers */, + 46EB2E00008180 /* TZAuthLimitedFooterTipView.h in Headers */, + 46EB2E00008190 /* TZGifPhotoPreviewController.h in Headers */, + 46EB2E000081A0 /* TZImageCropManager.h in Headers */, + 46EB2E000081B0 /* TZImageManager.h in Headers */, + 46EB2E000081C0 /* TZImagePickerController.h in Headers */, + 46EB2E000082D0 /* TZImagePickerController-umbrella.h in Headers */, + 46EB2E000081D0 /* TZImageRequestOperation.h in Headers */, + 46EB2E00008270 /* TZLocationManager.h in Headers */, + 46EB2E000081E0 /* TZPhotoPickerController.h in Headers */, + 46EB2E000081F0 /* TZPhotoPreviewCell.h in Headers */, + 46EB2E00008200 /* TZPhotoPreviewController.h in Headers */, + 46EB2E00008210 /* TZProgressView.h in Headers */, + 46EB2E00008220 /* TZVideoCropController.h in Headers */, + 46EB2E00008230 /* TZVideoEditedPreviewController.h in Headers */, + 46EB2E00008240 /* TZVideoPlayerController.h in Headers */, + 46EB2E00008250 /* UIView+TZLayout.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000083C0 /* Headers */ = { + 46EB2E00008360 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00008E00 /* alphai_dec.h in Headers */, - 46EB2E00008460 /* animi.h in Headers */, - 46EB2E00008E60 /* backward_references_enc.h in Headers */, - 46EB2E00008C70 /* bit_reader_inl_utils.h in Headers */, - 46EB2E00008C80 /* bit_reader_utils.h in Headers */, - 46EB2E00008C90 /* bit_writer_utils.h in Headers */, - 46EB2E00008CA0 /* color_cache_utils.h in Headers */, - 46EB2E00008E10 /* common_dec.h in Headers */, - 46EB2E00008D50 /* common_sse2.h in Headers */, - 46EB2E00008D60 /* common_sse41.h in Headers */, - 46EB2E00008E70 /* cost_enc.h in Headers */, - 46EB2E00008D70 /* cpu.h in Headers */, - 46EB2E00008C20 /* decode.h in Headers */, - 46EB2E00008410 /* demux.h in Headers */, - 46EB2E00008D80 /* dsp.h in Headers */, - 46EB2E00008C30 /* encode.h in Headers */, - 46EB2E00008CB0 /* endian_inl_utils.h in Headers */, - 46EB2E00008CC0 /* filters_utils.h in Headers */, - 46EB2E00008C60 /* format_constants.h in Headers */, - 46EB2E00008E80 /* histogram_enc.h in Headers */, - 46EB2E00008CD0 /* huffman_encode_utils.h in Headers */, - 46EB2E00008CE0 /* huffman_utils.h in Headers */, - 46EB2E00008F00 /* libwebp-umbrella.h in Headers */, - 46EB2E00008D90 /* lossless.h in Headers */, - 46EB2E00008DA0 /* lossless_common.h in Headers */, - 46EB2E00008DB0 /* mips_macro.h in Headers */, - 46EB2E00008DC0 /* msa_macro.h in Headers */, - 46EB2E00008480 /* mux.h in Headers */, - 46EB2E00008C50 /* mux_types.h in Headers */, - 46EB2E00008470 /* muxi.h in Headers */, - 46EB2E00008DD0 /* neon.h in Headers */, - 46EB2E00008DE0 /* quant.h in Headers */, - 46EB2E00008CF0 /* quant_levels_dec_utils.h in Headers */, - 46EB2E00008D00 /* quant_levels_utils.h in Headers */, - 46EB2E00008D10 /* random_utils.h in Headers */, - 46EB2E00008D20 /* rescaler_utils.h in Headers */, - 46EB2E00008500 /* sharpyuv.h in Headers */, - 46EB2E00008510 /* sharpyuv_cpu.h in Headers */, - 46EB2E00008520 /* sharpyuv_csp.h in Headers */, - 46EB2E00008530 /* sharpyuv_dsp.h in Headers */, - 46EB2E00008540 /* sharpyuv_gamma.h in Headers */, - 46EB2E00008D30 /* thread_utils.h in Headers */, - 46EB2E00008C40 /* types.h in Headers */, - 46EB2E00008D40 /* utils.h in Headers */, - 46EB2E00008E40 /* vp8_dec.h in Headers */, - 46EB2E00008E20 /* vp8i_dec.h in Headers */, - 46EB2E00008E90 /* vp8i_enc.h in Headers */, - 46EB2E00008E30 /* vp8li_dec.h in Headers */, - 46EB2E00008EA0 /* vp8li_enc.h in Headers */, - 46EB2E00008E50 /* webpi_dec.h in Headers */, - 46EB2E00008DF0 /* yuv.h in Headers */, + 46EB2E00008DA0 /* alphai_dec.h in Headers */, + 46EB2E00008400 /* animi.h in Headers */, + 46EB2E00008E00 /* backward_references_enc.h in Headers */, + 46EB2E00008C10 /* bit_reader_inl_utils.h in Headers */, + 46EB2E00008C20 /* bit_reader_utils.h in Headers */, + 46EB2E00008C30 /* bit_writer_utils.h in Headers */, + 46EB2E00008C40 /* color_cache_utils.h in Headers */, + 46EB2E00008DB0 /* common_dec.h in Headers */, + 46EB2E00008CF0 /* common_sse2.h in Headers */, + 46EB2E00008D00 /* common_sse41.h in Headers */, + 46EB2E00008E10 /* cost_enc.h in Headers */, + 46EB2E00008D10 /* cpu.h in Headers */, + 46EB2E00008BC0 /* decode.h in Headers */, + 46EB2E000083B0 /* demux.h in Headers */, + 46EB2E00008D20 /* dsp.h in Headers */, + 46EB2E00008BD0 /* encode.h in Headers */, + 46EB2E00008C50 /* endian_inl_utils.h in Headers */, + 46EB2E00008C60 /* filters_utils.h in Headers */, + 46EB2E00008C00 /* format_constants.h in Headers */, + 46EB2E00008E20 /* histogram_enc.h in Headers */, + 46EB2E00008C70 /* huffman_encode_utils.h in Headers */, + 46EB2E00008C80 /* huffman_utils.h in Headers */, + 46EB2E00008EA0 /* libwebp-umbrella.h in Headers */, + 46EB2E00008D30 /* lossless.h in Headers */, + 46EB2E00008D40 /* lossless_common.h in Headers */, + 46EB2E00008D50 /* mips_macro.h in Headers */, + 46EB2E00008D60 /* msa_macro.h in Headers */, + 46EB2E00008420 /* mux.h in Headers */, + 46EB2E00008BF0 /* mux_types.h in Headers */, + 46EB2E00008410 /* muxi.h in Headers */, + 46EB2E00008D70 /* neon.h in Headers */, + 46EB2E00008D80 /* quant.h in Headers */, + 46EB2E00008C90 /* quant_levels_dec_utils.h in Headers */, + 46EB2E00008CA0 /* quant_levels_utils.h in Headers */, + 46EB2E00008CB0 /* random_utils.h in Headers */, + 46EB2E00008CC0 /* rescaler_utils.h in Headers */, + 46EB2E000084A0 /* sharpyuv.h in Headers */, + 46EB2E000084B0 /* sharpyuv_cpu.h in Headers */, + 46EB2E000084C0 /* sharpyuv_csp.h in Headers */, + 46EB2E000084D0 /* sharpyuv_dsp.h in Headers */, + 46EB2E000084E0 /* sharpyuv_gamma.h in Headers */, + 46EB2E00008CD0 /* thread_utils.h in Headers */, + 46EB2E00008BE0 /* types.h in Headers */, + 46EB2E00008CE0 /* utils.h in Headers */, + 46EB2E00008DE0 /* vp8_dec.h in Headers */, + 46EB2E00008DC0 /* vp8i_dec.h in Headers */, + 46EB2E00008E30 /* vp8i_enc.h in Headers */, + 46EB2E00008DD0 /* vp8li_dec.h in Headers */, + 46EB2E00008E40 /* vp8li_enc.h in Headers */, + 46EB2E00008DF0 /* webpi_dec.h in Headers */, + 46EB2E00008D90 /* yuv.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008F90 /* Headers */ = { + 46EB2E00008F30 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E0000A210 /* lottie-ios-umbrella.h in Headers */, + 46EB2E0000A1B0 /* lottie-ios-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A2B0 /* Headers */ = { + 46EB2E0000A250 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A3B0 /* Headers */ = { + 46EB2E0000A350 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E0000A430 /* Pods-CLDemo-Swift-umbrella.h in Headers */, + 46EB2E0000A3D0 /* Pods-CLDemo-Swift-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4948,17 +4926,17 @@ /* Begin PBXNativeTarget section */ 0B967D7F8561D42493EE289EC8D450D1 /* lottie-ios */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00008F50 /* Build configuration list for PBXNativeTarget "lottie-ios" */; + buildConfigurationList = 46EB2E00008EF0 /* Build configuration list for PBXNativeTarget "lottie-ios" */; buildPhases = ( - 46EB2E00008F90 /* Headers */, - 46EB2E00008FA0 /* Sources */, - 46EB2E00008FB0 /* Frameworks */, - 46EB2E0000A220 /* Copy generated compatibility header */, + 46EB2E00008F30 /* Headers */, + 46EB2E00008F40 /* Sources */, + 46EB2E00008F50 /* Frameworks */, + 46EB2E0000A1C0 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A800 /* PBXTargetDependency */, + 46EB2E0000A7A0 /* PBXTargetDependency */, ); name = "lottie-ios"; productName = "lottie-ios"; @@ -4967,21 +4945,21 @@ }; 14DD0ADF057DB9A1946B24BD98363372 /* Pods-CLDemo-OC */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E0000A270 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-OC" */; + buildConfigurationList = 46EB2E0000A210 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-OC" */; buildPhases = ( - 46EB2E0000A2B0 /* Headers */, - 46EB2E0000A2C0 /* Sources */, - 46EB2E0000A2D0 /* Frameworks */, + 46EB2E0000A250 /* Headers */, + 46EB2E0000A260 /* Sources */, + 46EB2E0000A270 /* Frameworks */, ); buildRules = ( ); dependencies = ( + 46EB2E0000A440 /* PBXTargetDependency */, + 46EB2E0000A460 /* PBXTargetDependency */, + 46EB2E0000A480 /* PBXTargetDependency */, 46EB2E0000A4A0 /* PBXTargetDependency */, 46EB2E0000A4C0 /* PBXTargetDependency */, 46EB2E0000A4E0 /* PBXTargetDependency */, - 46EB2E0000A500 /* PBXTargetDependency */, - 46EB2E0000A520 /* PBXTargetDependency */, - 46EB2E0000A540 /* PBXTargetDependency */, ); name = "Pods-CLDemo-OC"; productName = "Pods-CLDemo-OC"; @@ -4990,17 +4968,17 @@ }; 1953860EA9853AA2BC8022B242F08512 /* SDWebImageWebPCoder */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00007860 /* Build configuration list for PBXNativeTarget "SDWebImageWebPCoder" */; + buildConfigurationList = 46EB2E00007810 /* Build configuration list for PBXNativeTarget "SDWebImageWebPCoder" */; buildPhases = ( - 46EB2E000078A0 /* Headers */, - 46EB2E000078B0 /* Sources */, - 46EB2E000078C0 /* Frameworks */, + 46EB2E00007850 /* Headers */, + 46EB2E00007860 /* Sources */, + 46EB2E00007870 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A780 /* PBXTargetDependency */, - 46EB2E0000A7A0 /* PBXTargetDependency */, + 46EB2E0000A720 /* PBXTargetDependency */, + 46EB2E0000A740 /* PBXTargetDependency */, ); name = SDWebImageWebPCoder; productName = SDWebImageWebPCoder; @@ -5009,17 +4987,17 @@ }; 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E000079E0 /* Build configuration list for PBXNativeTarget "SnapKit" */; + buildConfigurationList = 46EB2E00007990 /* Build configuration list for PBXNativeTarget "SnapKit" */; buildPhases = ( - 46EB2E00007A20 /* Headers */, - 46EB2E00007A30 /* Sources */, - 46EB2E00007A40 /* Frameworks */, - 46EB2E00007DA0 /* Copy generated compatibility header */, + 46EB2E000079D0 /* Headers */, + 46EB2E000079E0 /* Sources */, + 46EB2E000079F0 /* Frameworks */, + 46EB2E00007D40 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A7C0 /* PBXTargetDependency */, + 46EB2E0000A760 /* PBXTargetDependency */, ); name = SnapKit; productName = SnapKit; @@ -5028,12 +5006,12 @@ }; 2808B98A5B29AEEB5B7418EEA8B1B92C /* CLPopoverManager */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00004A50 /* Build configuration list for PBXNativeTarget "CLPopoverManager" */; + buildConfigurationList = 46EB2E00004A10 /* Build configuration list for PBXNativeTarget "CLPopoverManager" */; buildPhases = ( - 46EB2E00004A90 /* Headers */, - 46EB2E00004AA0 /* Sources */, - 46EB2E00004AB0 /* Frameworks */, - 46EB2E00004B70 /* Copy generated compatibility header */, + 46EB2E00004A50 /* Headers */, + 46EB2E00004A60 /* Sources */, + 46EB2E00004A70 /* Frameworks */, + 46EB2E00004B30 /* Copy generated compatibility header */, ); buildRules = ( ); @@ -5046,11 +5024,11 @@ }; 2B1A4F9261E8F421732B6CB1319CCC3E /* DateTools */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00005490 /* Build configuration list for PBXNativeTarget "DateTools" */; + buildConfigurationList = 46EB2E00005450 /* Build configuration list for PBXNativeTarget "DateTools" */; buildPhases = ( - 46EB2E000054D0 /* Headers */, - 46EB2E000054E0 /* Sources */, - 46EB2E000054F0 /* Frameworks */, + 46EB2E00005490 /* Headers */, + 46EB2E000054A0 /* Sources */, + 46EB2E000054B0 /* Frameworks */, ); buildRules = ( ); @@ -5063,16 +5041,16 @@ }; 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00006D70 /* Build configuration list for PBXNativeTarget "SDWebImage" */; + buildConfigurationList = 46EB2E00006D20 /* Build configuration list for PBXNativeTarget "SDWebImage" */; buildPhases = ( - 46EB2E00006DB0 /* Headers */, - 46EB2E00006DC0 /* Sources */, - 46EB2E00006DD0 /* Frameworks */, + 46EB2E00006D60 /* Headers */, + 46EB2E00006D70 /* Sources */, + 46EB2E00006D80 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A760 /* PBXTargetDependency */, + 46EB2E0000A700 /* PBXTargetDependency */, ); name = SDWebImage; productName = SDWebImage; @@ -5081,11 +5059,11 @@ }; 47D2E85A78C25869BB13521D8561A638 /* libwebp */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00008380 /* Build configuration list for PBXNativeTarget "libwebp" */; + buildConfigurationList = 46EB2E00008320 /* Build configuration list for PBXNativeTarget "libwebp" */; buildPhases = ( - 46EB2E000083C0 /* Headers */, - 46EB2E000083D0 /* Sources */, - 46EB2E000083E0 /* Frameworks */, + 46EB2E00008360 /* Headers */, + 46EB2E00008370 /* Sources */, + 46EB2E00008380 /* Frameworks */, ); buildRules = ( ); @@ -5098,16 +5076,16 @@ }; 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E000067D0 /* Build configuration list for PBXNativeTarget "MJExtension" */; + buildConfigurationList = 46EB2E00006790 /* Build configuration list for PBXNativeTarget "MJExtension" */; buildPhases = ( - 46EB2E00006810 /* Headers */, - 46EB2E00006820 /* Sources */, - 46EB2E00006830 /* Frameworks */, + 46EB2E000067D0 /* Headers */, + 46EB2E000067E0 /* Sources */, + 46EB2E000067F0 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A740 /* PBXTargetDependency */, + 46EB2E0000A6E0 /* PBXTargetDependency */, ); name = MJExtension; productName = MJExtension; @@ -5116,11 +5094,11 @@ }; 55AF53E6C77A10ED4985E04D74A8878E /* Masonry */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00006AD0 /* Build configuration list for PBXNativeTarget "Masonry" */; + buildConfigurationList = 46EB2E00006A80 /* Build configuration list for PBXNativeTarget "Masonry" */; buildPhases = ( - 46EB2E00006B10 /* Headers */, - 46EB2E00006B20 /* Sources */, - 46EB2E00006B30 /* Frameworks */, + 46EB2E00006AC0 /* Headers */, + 46EB2E00006AD0 /* Sources */, + 46EB2E00006AE0 /* Frameworks */, ); buildRules = ( ); @@ -5133,11 +5111,11 @@ }; 638FEAAFC575BB76BC6AC055CDDA3506 /* LookinServer */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00005E50 /* Build configuration list for PBXNativeTarget "LookinServer" */; + buildConfigurationList = 46EB2E00005E10 /* Build configuration list for PBXNativeTarget "LookinServer" */; buildPhases = ( - 46EB2E00005E90 /* Headers */, - 46EB2E00005EA0 /* Sources */, - 46EB2E00005EB0 /* Frameworks */, + 46EB2E00005E50 /* Headers */, + 46EB2E00005E60 /* Sources */, + 46EB2E00005E70 /* Frameworks */, ); buildRules = ( ); @@ -5150,11 +5128,11 @@ }; 677650A76A720691B88A6959EFED6418 /* SwiftyJSON-SwiftyJSON */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00007EE0 /* Build configuration list for PBXNativeTarget "SwiftyJSON-SwiftyJSON" */; + buildConfigurationList = 46EB2E00007E80 /* Build configuration list for PBXNativeTarget "SwiftyJSON-SwiftyJSON" */; buildPhases = ( - 46EB2E00007F20 /* Sources */, - 46EB2E00007F30 /* Frameworks */, - 46EB2E00007F40 /* Resources */, + 46EB2E00007EC0 /* Sources */, + 46EB2E00007ED0 /* Frameworks */, + 46EB2E00007EE0 /* Resources */, ); buildRules = ( ); @@ -5167,17 +5145,17 @@ }; 7B01858F4318778678571D6E58E2D832 /* CLCamera */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00004800 /* Build configuration list for PBXNativeTarget "CLCamera" */; + buildConfigurationList = 46EB2E000047C0 /* Build configuration list for PBXNativeTarget "CLCamera" */; buildPhases = ( - 46EB2E00004840 /* Headers */, - 46EB2E00004850 /* Sources */, - 46EB2E00004860 /* Frameworks */, - 46EB2E00004A00 /* Copy generated compatibility header */, + 46EB2E00004800 /* Headers */, + 46EB2E00004810 /* Sources */, + 46EB2E00004820 /* Frameworks */, + 46EB2E000049C0 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A6E0 /* PBXTargetDependency */, + 46EB2E0000A680 /* PBXTargetDependency */, ); name = CLCamera; productName = CLCamera; @@ -5186,11 +5164,11 @@ }; 8A8DB685241263AFDF5E6B20FE67B93A /* SnapKit-SnapKit_Privacy */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00007A60 /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */; + buildConfigurationList = 46EB2E00007A10 /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */; buildPhases = ( - 46EB2E00007AA0 /* Sources */, - 46EB2E00007AB0 /* Frameworks */, - 46EB2E00007AC0 /* Resources */, + 46EB2E00007A50 /* Sources */, + 46EB2E00007A60 /* Frameworks */, + 46EB2E00007A70 /* Resources */, ); buildRules = ( ); @@ -5203,11 +5181,11 @@ }; 94CFBA7D633ECA58DF85C327B035E6A3 /* SDWebImage-SDWebImage */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00006DF0 /* Build configuration list for PBXNativeTarget "SDWebImage-SDWebImage" */; + buildConfigurationList = 46EB2E00006DA0 /* Build configuration list for PBXNativeTarget "SDWebImage-SDWebImage" */; buildPhases = ( - 46EB2E00006E30 /* Sources */, - 46EB2E00006E40 /* Frameworks */, - 46EB2E00006E50 /* Resources */, + 46EB2E00006DE0 /* Sources */, + 46EB2E00006DF0 /* Frameworks */, + 46EB2E00006E00 /* Resources */, ); buildRules = ( ); @@ -5220,11 +5198,11 @@ }; 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00005920 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */; + buildConfigurationList = 46EB2E000058E0 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */; buildPhases = ( - 46EB2E00005960 /* Sources */, - 46EB2E00005970 /* Frameworks */, - 46EB2E00005980 /* Resources */, + 46EB2E00005920 /* Sources */, + 46EB2E00005930 /* Frameworks */, + 46EB2E00005940 /* Resources */, ); buildRules = ( ); @@ -5237,17 +5215,17 @@ }; 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00004BC0 /* Build configuration list for PBXNativeTarget "CryptoSwift" */; + buildConfigurationList = 46EB2E00004B80 /* Build configuration list for PBXNativeTarget "CryptoSwift" */; buildPhases = ( - 46EB2E00004C00 /* Headers */, - 46EB2E00004C10 /* Sources */, - 46EB2E00004C20 /* Frameworks */, - 46EB2E00005440 /* Copy generated compatibility header */, + 46EB2E00004BC0 /* Headers */, + 46EB2E00004BD0 /* Sources */, + 46EB2E00004BE0 /* Frameworks */, + 46EB2E00005400 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A700 /* PBXTargetDependency */, + 46EB2E0000A6A0 /* PBXTargetDependency */, ); name = CryptoSwift; productName = CryptoSwift; @@ -5256,27 +5234,27 @@ }; A698FBD3CCFD66AFE010911F8D15B550 /* Pods-CLDemo-Swift */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E0000A370 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-Swift" */; + buildConfigurationList = 46EB2E0000A310 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-Swift" */; buildPhases = ( - 46EB2E0000A3B0 /* Headers */, - 46EB2E0000A3C0 /* Sources */, - 46EB2E0000A3D0 /* Frameworks */, + 46EB2E0000A350 /* Headers */, + 46EB2E0000A360 /* Sources */, + 46EB2E0000A370 /* Frameworks */, ); buildRules = ( ); dependencies = ( + 46EB2E0000A520 /* PBXTargetDependency */, + 46EB2E0000A540 /* PBXTargetDependency */, + 46EB2E0000A560 /* PBXTargetDependency */, 46EB2E0000A580 /* PBXTargetDependency */, 46EB2E0000A5A0 /* PBXTargetDependency */, 46EB2E0000A5C0 /* PBXTargetDependency */, + 46EB2E0000A500 /* PBXTargetDependency */, 46EB2E0000A5E0 /* PBXTargetDependency */, 46EB2E0000A600 /* PBXTargetDependency */, 46EB2E0000A620 /* PBXTargetDependency */, - 46EB2E0000A560 /* PBXTargetDependency */, 46EB2E0000A640 /* PBXTargetDependency */, 46EB2E0000A660 /* PBXTargetDependency */, - 46EB2E0000A680 /* PBXTargetDependency */, - 46EB2E0000A6A0 /* PBXTargetDependency */, - 46EB2E0000A6C0 /* PBXTargetDependency */, ); name = "Pods-CLDemo-Swift"; productName = "Pods-CLDemo-Swift"; @@ -5285,11 +5263,11 @@ }; A96BBB982D62BB807B5BD10774BE2D07 /* TZImagePickerController */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00008030 /* Build configuration list for PBXNativeTarget "TZImagePickerController" */; + buildConfigurationList = 46EB2E00007FD0 /* Build configuration list for PBXNativeTarget "TZImagePickerController" */; buildPhases = ( - 46EB2E00008070 /* Headers */, - 46EB2E00008080 /* Sources */, - 46EB2E00008090 /* Frameworks */, + 46EB2E00008010 /* Headers */, + 46EB2E00008020 /* Sources */, + 46EB2E00008030 /* Frameworks */, ); buildRules = ( ); @@ -5302,11 +5280,11 @@ }; B32AF3F43989CBA171BB1FB3957A4509 /* MJExtension-MJExtension */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00006850 /* Build configuration list for PBXNativeTarget "MJExtension-MJExtension" */; + buildConfigurationList = 46EB2E00006810 /* Build configuration list for PBXNativeTarget "MJExtension-MJExtension" */; buildPhases = ( - 46EB2E00006890 /* Sources */, - 46EB2E000068A0 /* Frameworks */, - 46EB2E000068B0 /* Resources */, + 46EB2E00006850 /* Sources */, + 46EB2E00006860 /* Frameworks */, + 46EB2E00006870 /* Resources */, ); buildRules = ( ); @@ -5319,11 +5297,11 @@ }; BF2A15FEC3F3424BBC4B9AD5F86F2D54 /* lottie-ios-LottiePrivacyInfo */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00008FD0 /* Build configuration list for PBXNativeTarget "lottie-ios-LottiePrivacyInfo" */; + buildConfigurationList = 46EB2E00008F70 /* Build configuration list for PBXNativeTarget "lottie-ios-LottiePrivacyInfo" */; buildPhases = ( - 46EB2E00009010 /* Sources */, - 46EB2E00009020 /* Frameworks */, - 46EB2E00009030 /* Resources */, + 46EB2E00008FB0 /* Sources */, + 46EB2E00008FC0 /* Frameworks */, + 46EB2E00008FD0 /* Resources */, ); buildRules = ( ); @@ -5336,12 +5314,12 @@ }; CCB5EA80CC733D89D54DAEB30E93351D /* DateToolsSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00005690 /* Build configuration list for PBXNativeTarget "DateToolsSwift" */; + buildConfigurationList = 46EB2E00005650 /* Build configuration list for PBXNativeTarget "DateToolsSwift" */; buildPhases = ( - 46EB2E000056D0 /* Headers */, - 46EB2E000056E0 /* Sources */, - 46EB2E000056F0 /* Frameworks */, - 46EB2E00005850 /* Copy generated compatibility header */, + 46EB2E00005690 /* Headers */, + 46EB2E000056A0 /* Sources */, + 46EB2E000056B0 /* Frameworks */, + 46EB2E00005810 /* Copy generated compatibility header */, ); buildRules = ( ); @@ -5354,17 +5332,17 @@ }; D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00007E60 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */; + buildConfigurationList = 46EB2E00007E00 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */; buildPhases = ( - 46EB2E00007EA0 /* Headers */, - 46EB2E00007EB0 /* Sources */, - 46EB2E00007EC0 /* Frameworks */, - 46EB2E00007FE0 /* Copy generated compatibility header */, + 46EB2E00007E40 /* Headers */, + 46EB2E00007E50 /* Sources */, + 46EB2E00007E60 /* Frameworks */, + 46EB2E00007F80 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A7E0 /* PBXTargetDependency */, + 46EB2E0000A780 /* PBXTargetDependency */, ); name = SwiftyJSON; productName = SwiftyJSON; @@ -5373,17 +5351,17 @@ }; E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E000058A0 /* Build configuration list for PBXNativeTarget "Kingfisher" */; + buildConfigurationList = 46EB2E00005860 /* Build configuration list for PBXNativeTarget "Kingfisher" */; buildPhases = ( - 46EB2E000058E0 /* Headers */, - 46EB2E000058F0 /* Sources */, - 46EB2E00005900 /* Frameworks */, - 46EB2E00005E00 /* Copy generated compatibility header */, + 46EB2E000058A0 /* Headers */, + 46EB2E000058B0 /* Sources */, + 46EB2E000058C0 /* Frameworks */, + 46EB2E00005DC0 /* Copy generated compatibility header */, ); buildRules = ( ); dependencies = ( - 46EB2E0000A720 /* PBXTargetDependency */, + 46EB2E0000A6C0 /* PBXTargetDependency */, ); name = Kingfisher; productName = Kingfisher; @@ -5392,11 +5370,11 @@ }; EBC10B6451F5FE5244D138B5176C2A02 /* CryptoSwift-CryptoSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 46EB2E00004C40 /* Build configuration list for PBXNativeTarget "CryptoSwift-CryptoSwift" */; + buildConfigurationList = 46EB2E00004C00 /* Build configuration list for PBXNativeTarget "CryptoSwift-CryptoSwift" */; buildPhases = ( - 46EB2E00004C80 /* Sources */, - 46EB2E00004C90 /* Frameworks */, - 46EB2E00004CA0 /* Resources */, + 46EB2E00004C40 /* Sources */, + 46EB2E00004C50 /* Frameworks */, + 46EB2E00004C60 /* Resources */, ); buildRules = ( ); @@ -5417,7 +5395,7 @@ LastUpgradeCheck = 1600; }; buildConfigurationList = 46EB2E00000030 /* Build configuration list for PBXProject "Pods" */; - compatibilityVersion = "Xcode 10.0"; + compatibilityVersion = "Xcode 12.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -5462,66 +5440,64 @@ /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 46EB2E00004CA0 /* Resources */ = { + 46EB2E00004C60 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00004CB0 /* PrivacyInfo.xcprivacy in Resources */, + 46EB2E00004C70 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005980 /* Resources */ = { + 46EB2E00005940 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005990 /* PrivacyInfo.xcprivacy in Resources */, + 46EB2E00005950 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000068B0 /* Resources */ = { + 46EB2E00006870 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000068C0 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006E50 /* Resources */ = { + 46EB2E00006E00 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00006E60 /* PrivacyInfo.xcprivacy in Resources */, + 46EB2E00006E10 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007AC0 /* Resources */ = { + 46EB2E00007A70 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007AD0 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007F40 /* Resources */ = { + 46EB2E00007EE0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007F50 /* PrivacyInfo.xcprivacy in Resources */, + 46EB2E00007EF0 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00009030 /* Resources */ = { + 46EB2E00008FD0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00009040 /* PrivacyInfo.xcprivacy in Resources */, + 46EB2E00008FE0 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 46EB2E00004A00 /* Copy generated compatibility header */ = { + 46EB2E000049C0 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5545,7 +5521,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CLCamera/CLCamera.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CLCamera/CLCamera-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00004B70 /* Copy generated compatibility header */ = { + 46EB2E00004B30 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5569,7 +5545,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CLPopoverManager/CLPopoverManager.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CLPopoverManager/CLPopoverManager-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00005440 /* Copy generated compatibility header */ = { + 46EB2E00005400 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5593,7 +5569,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CryptoSwift/CryptoSwift.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/CryptoSwift/CryptoSwift-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00005850 /* Copy generated compatibility header */ = { + 46EB2E00005810 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5617,7 +5593,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/DateToolsSwift/DateToolsSwift.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/DateToolsSwift/DateToolsSwift-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00005E00 /* Copy generated compatibility header */ = { + 46EB2E00005DC0 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5641,7 +5617,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/Kingfisher/Kingfisher.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/Kingfisher/Kingfisher-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00007DA0 /* Copy generated compatibility header */ = { + 46EB2E00007D40 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5665,7 +5641,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SnapKit/SnapKit.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SnapKit/SnapKit-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E00007FE0 /* Copy generated compatibility header */ = { + 46EB2E00007F80 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5689,7 +5665,7 @@ shellPath = /bin/sh; shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SwiftyJSON/SwiftyJSON.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SwiftyJSON/SwiftyJSON-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; }; - 46EB2E0000A220 /* Copy generated compatibility header */ = { + 46EB2E0000A1C0 /* Copy generated compatibility header */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -5716,1206 +5692,1206 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 46EB2E00004850 /* Sources */ = { + 46EB2E00004810 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000048A0 /* AVCaptureDevice+Extension.swift in Sources */, - 46EB2E000048B0 /* AVCapturePhoto+Extension.swift in Sources */, - 46EB2E00004A30 /* CLCamera-dummy.m in Sources */, - 46EB2E00004940 /* CLCameraButton.swift in Sources */, - 46EB2E000048D0 /* CLCameraConfig.swift in Sources */, - 46EB2E00004870 /* CLCameraController.swift in Sources */, - 46EB2E00004950 /* CLCameraControlView.swift in Sources */, - 46EB2E000048E0 /* CLCameraEnum.swift in Sources */, - 46EB2E000048F0 /* CLCameraError.swift in Sources */, - 46EB2E00004900 /* CLCameraHelper.swift in Sources */, - 46EB2E00004880 /* CLCameraImagePreviewController.swift in Sources */, - 46EB2E00004910 /* CLCameraOrientation.swift in Sources */, - 46EB2E00004960 /* CLCameraPreviewToolBar.swift in Sources */, - 46EB2E00004890 /* CLCameraVideoPreviewController.swift in Sources */, - 46EB2E00004970 /* CLLoadingHUD.swift in Sources */, - 46EB2E00004980 /* CLLoadingHUDView.swift in Sources */, - 46EB2E00004990 /* CLLoadingProgressView.swift in Sources */, - 46EB2E00004920 /* CLPermissionInterface.swift in Sources */, - 46EB2E00004930 /* CLPermissions.swift in Sources */, - 46EB2E000048C0 /* UIImage+Extension.swift in Sources */, + 46EB2E00004860 /* AVCaptureDevice+Extension.swift in Sources */, + 46EB2E00004870 /* AVCapturePhoto+Extension.swift in Sources */, + 46EB2E000049F0 /* CLCamera-dummy.m in Sources */, + 46EB2E00004900 /* CLCameraButton.swift in Sources */, + 46EB2E00004890 /* CLCameraConfig.swift in Sources */, + 46EB2E00004830 /* CLCameraController.swift in Sources */, + 46EB2E00004910 /* CLCameraControlView.swift in Sources */, + 46EB2E000048A0 /* CLCameraEnum.swift in Sources */, + 46EB2E000048B0 /* CLCameraError.swift in Sources */, + 46EB2E000048C0 /* CLCameraHelper.swift in Sources */, + 46EB2E00004840 /* CLCameraImagePreviewController.swift in Sources */, + 46EB2E000048D0 /* CLCameraOrientation.swift in Sources */, + 46EB2E00004920 /* CLCameraPreviewToolBar.swift in Sources */, + 46EB2E00004850 /* CLCameraVideoPreviewController.swift in Sources */, + 46EB2E00004930 /* CLLoadingHUD.swift in Sources */, + 46EB2E00004940 /* CLLoadingHUDView.swift in Sources */, + 46EB2E00004950 /* CLLoadingProgressView.swift in Sources */, + 46EB2E000048E0 /* CLPermissionInterface.swift in Sources */, + 46EB2E000048F0 /* CLPermissions.swift in Sources */, + 46EB2E00004880 /* UIImage+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004AA0 /* Sources */ = { + 46EB2E00004A60 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00004AC0 /* CLPopoverConfig.swift in Sources */, - 46EB2E00004AD0 /* CLPopoverController.swift in Sources */, - 46EB2E00004AE0 /* CLPopoverManager.swift in Sources */, - 46EB2E00004BA0 /* CLPopoverManager-dummy.m in Sources */, - 46EB2E00004AF0 /* CLPopoverProtocol.swift in Sources */, - 46EB2E00004B00 /* CLPopoverWindow.swift in Sources */, + 46EB2E00004A80 /* CLPopoverConfig.swift in Sources */, + 46EB2E00004A90 /* CLPopoverController.swift in Sources */, + 46EB2E00004AA0 /* CLPopoverManager.swift in Sources */, + 46EB2E00004B60 /* CLPopoverManager-dummy.m in Sources */, + 46EB2E00004AB0 /* CLPopoverProtocol.swift in Sources */, + 46EB2E00004AC0 /* CLPopoverWindow.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004C10 /* Sources */ = { + 46EB2E00004BD0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00004F40 /* Addition.swift in Sources */, - 46EB2E00004CE0 /* AEAD.swift in Sources */, - 46EB2E00004CF0 /* AEADChaCha20Poly1305.swift in Sources */, - 46EB2E00004D00 /* AEADXChaCha20Poly1305.swift in Sources */, - 46EB2E00004D20 /* AES.swift in Sources */, - 46EB2E000050D0 /* AES+Foundation.swift in Sources */, - 46EB2E00004D10 /* AES.Cryptors.swift in Sources */, - 46EB2E00004D30 /* Array+Extension.swift in Sources */, - 46EB2E000050E0 /* Array+Foundation.swift in Sources */, - 46EB2E00004D40 /* ASN1.swift in Sources */, - 46EB2E00004D50 /* ASN1Decoder.swift in Sources */, - 46EB2E00004D60 /* ASN1Encoder.swift in Sources */, - 46EB2E00004D70 /* ASN1Scanner.swift in Sources */, - 46EB2E00004D80 /* Authenticator.swift in Sources */, - 46EB2E00004D90 /* BatchedCollection.swift in Sources */, - 46EB2E00004F50 /* BigInt.swift in Sources */, - 46EB2E00004F60 /* BigUInt.swift in Sources */, - 46EB2E00004DA0 /* Bit.swift in Sources */, - 46EB2E00004F70 /* BitwiseOps.swift in Sources */, - 46EB2E00004DB0 /* BlockCipher.swift in Sources */, - 46EB2E00004DC0 /* BlockDecryptor.swift in Sources */, - 46EB2E00004DD0 /* BlockEncryptor.swift in Sources */, - 46EB2E00004DE0 /* BlockMode.swift in Sources */, - 46EB2E00004DF0 /* BlockModeOptions.swift in Sources */, - 46EB2E00004EA0 /* Blowfish.swift in Sources */, - 46EB2E000050F0 /* Blowfish+Foundation.swift in Sources */, - 46EB2E00004E00 /* CBC.swift in Sources */, - 46EB2E00004EB0 /* CBCMAC.swift in Sources */, - 46EB2E00004E10 /* CCM.swift in Sources */, - 46EB2E00004E20 /* CFB.swift in Sources */, - 46EB2E00004EC0 /* ChaCha20.swift in Sources */, - 46EB2E00005100 /* ChaCha20+Foundation.swift in Sources */, - 46EB2E00004ED0 /* Checksum.swift in Sources */, - 46EB2E00004EE0 /* Cipher.swift in Sources */, - 46EB2E00004E30 /* CipherModeWorker.swift in Sources */, - 46EB2E00004EF0 /* CMAC.swift in Sources */, - 46EB2E00004F80 /* Codable.swift in Sources */, - 46EB2E00004F00 /* Collection+Extension.swift in Sources */, - 46EB2E00004F10 /* CompactMap.swift in Sources */, - 46EB2E00004F90 /* Comparable.swift in Sources */, - 46EB2E00004F20 /* Cryptor.swift in Sources */, - 46EB2E00004F30 /* Cryptors.swift in Sources */, - 46EB2E00005470 /* CryptoSwift-dummy.m in Sources */, - 46EB2E00004FA0 /* CS.swift in Sources */, - 46EB2E00004E40 /* CTR.swift in Sources */, - 46EB2E00005110 /* Data+Extension.swift in Sources */, - 46EB2E00004FB0 /* DataConversion.swift in Sources */, - 46EB2E00005210 /* DER.swift in Sources */, - 46EB2E000050B0 /* Digest.swift in Sources */, - 46EB2E000050C0 /* DigestType.swift in Sources */, - 46EB2E00004FC0 /* Division.swift in Sources */, - 46EB2E00004E50 /* ECB.swift in Sources */, - 46EB2E00004FD0 /* Exponentiation.swift in Sources */, - 46EB2E00004FE0 /* FloatingPointConversion.swift in Sources */, - 46EB2E00004FF0 /* GCD.swift in Sources */, - 46EB2E00004E60 /* GCM.swift in Sources */, - 46EB2E00005170 /* Generics.swift in Sources */, - 46EB2E00005000 /* Hashable.swift in Sources */, - 46EB2E00005180 /* HKDF.swift in Sources */, - 46EB2E00005190 /* HMAC.swift in Sources */, - 46EB2E00005120 /* HMAC+Foundation.swift in Sources */, - 46EB2E000051A0 /* Int+Extension.swift in Sources */, - 46EB2E00005010 /* IntegerConversion.swift in Sources */, - 46EB2E000051B0 /* ISO10126Padding.swift in Sources */, - 46EB2E000051C0 /* ISO78164Padding.swift in Sources */, - 46EB2E000051D0 /* MD5.swift in Sources */, - 46EB2E00005020 /* Multiplication.swift in Sources */, - 46EB2E000051E0 /* NoPadding.swift in Sources */, - 46EB2E00004E70 /* OCB.swift in Sources */, - 46EB2E00004E80 /* OFB.swift in Sources */, - 46EB2E000051F0 /* Operators.swift in Sources */, - 46EB2E00005200 /* Padding.swift in Sources */, - 46EB2E00005220 /* PBKDF1.swift in Sources */, - 46EB2E00005230 /* PBKDF2.swift in Sources */, - 46EB2E00004E90 /* PCBC.swift in Sources */, - 46EB2E00005240 /* PKCS1v15.swift in Sources */, - 46EB2E00005250 /* PKCS5.swift in Sources */, - 46EB2E00005260 /* PKCS7.swift in Sources */, - 46EB2E00005270 /* PKCS7Padding.swift in Sources */, - 46EB2E00005280 /* Poly1305.swift in Sources */, - 46EB2E00005030 /* PrimeTest.swift in Sources */, - 46EB2E00005290 /* Rabbit.swift in Sources */, - 46EB2E00005130 /* Rabbit+Foundation.swift in Sources */, - 46EB2E00005040 /* Random.swift in Sources */, - 46EB2E000052C0 /* RSA.swift in Sources */, - 46EB2E000052A0 /* RSA+Cipher.swift in Sources */, - 46EB2E000052B0 /* RSA+Signature.swift in Sources */, - 46EB2E000052D0 /* Scrypt.swift in Sources */, - 46EB2E000052E0 /* SecureBytes.swift in Sources */, - 46EB2E000052F0 /* SHA1.swift in Sources */, - 46EB2E00005300 /* SHA2.swift in Sources */, - 46EB2E00005310 /* SHA3.swift in Sources */, - 46EB2E00005050 /* Shifts.swift in Sources */, - 46EB2E00005320 /* Signature.swift in Sources */, - 46EB2E00005060 /* SquareRoot.swift in Sources */, - 46EB2E00005330 /* StreamDecryptor.swift in Sources */, - 46EB2E00005340 /* StreamEncryptor.swift in Sources */, - 46EB2E00005070 /* Strideable.swift in Sources */, - 46EB2E00005350 /* String+Extension.swift in Sources */, - 46EB2E00005140 /* String+FoundationExtension.swift in Sources */, - 46EB2E00005080 /* StringConversion.swift in Sources */, - 46EB2E00005090 /* Subtraction.swift in Sources */, - 46EB2E00005360 /* UInt128.swift in Sources */, - 46EB2E00005370 /* UInt16+Extension.swift in Sources */, - 46EB2E00005380 /* UInt32+Extension.swift in Sources */, - 46EB2E00005390 /* UInt64+Extension.swift in Sources */, - 46EB2E000053A0 /* UInt8+Extension.swift in Sources */, - 46EB2E000053B0 /* Updatable.swift in Sources */, - 46EB2E000053C0 /* Utils.swift in Sources */, - 46EB2E00005150 /* Utils+Foundation.swift in Sources */, - 46EB2E000050A0 /* WordsAndBits.swift in Sources */, - 46EB2E000053D0 /* XChaCha20.swift in Sources */, - 46EB2E00005160 /* XChaCha20+Foundation.swift in Sources */, - 46EB2E000053E0 /* ZeroPadding.swift in Sources */, + 46EB2E00004F00 /* Addition.swift in Sources */, + 46EB2E00004CA0 /* AEAD.swift in Sources */, + 46EB2E00004CB0 /* AEADChaCha20Poly1305.swift in Sources */, + 46EB2E00004CC0 /* AEADXChaCha20Poly1305.swift in Sources */, + 46EB2E00004CE0 /* AES.swift in Sources */, + 46EB2E00005090 /* AES+Foundation.swift in Sources */, + 46EB2E00004CD0 /* AES.Cryptors.swift in Sources */, + 46EB2E00004CF0 /* Array+Extension.swift in Sources */, + 46EB2E000050A0 /* Array+Foundation.swift in Sources */, + 46EB2E00004D00 /* ASN1.swift in Sources */, + 46EB2E00004D10 /* ASN1Decoder.swift in Sources */, + 46EB2E00004D20 /* ASN1Encoder.swift in Sources */, + 46EB2E00004D30 /* ASN1Scanner.swift in Sources */, + 46EB2E00004D40 /* Authenticator.swift in Sources */, + 46EB2E00004D50 /* BatchedCollection.swift in Sources */, + 46EB2E00004F10 /* BigInt.swift in Sources */, + 46EB2E00004F20 /* BigUInt.swift in Sources */, + 46EB2E00004D60 /* Bit.swift in Sources */, + 46EB2E00004F30 /* BitwiseOps.swift in Sources */, + 46EB2E00004D70 /* BlockCipher.swift in Sources */, + 46EB2E00004D80 /* BlockDecryptor.swift in Sources */, + 46EB2E00004D90 /* BlockEncryptor.swift in Sources */, + 46EB2E00004DA0 /* BlockMode.swift in Sources */, + 46EB2E00004DB0 /* BlockModeOptions.swift in Sources */, + 46EB2E00004E60 /* Blowfish.swift in Sources */, + 46EB2E000050B0 /* Blowfish+Foundation.swift in Sources */, + 46EB2E00004DC0 /* CBC.swift in Sources */, + 46EB2E00004E70 /* CBCMAC.swift in Sources */, + 46EB2E00004DD0 /* CCM.swift in Sources */, + 46EB2E00004DE0 /* CFB.swift in Sources */, + 46EB2E00004E80 /* ChaCha20.swift in Sources */, + 46EB2E000050C0 /* ChaCha20+Foundation.swift in Sources */, + 46EB2E00004E90 /* Checksum.swift in Sources */, + 46EB2E00004EA0 /* Cipher.swift in Sources */, + 46EB2E00004DF0 /* CipherModeWorker.swift in Sources */, + 46EB2E00004EB0 /* CMAC.swift in Sources */, + 46EB2E00004F40 /* Codable.swift in Sources */, + 46EB2E00004EC0 /* Collection+Extension.swift in Sources */, + 46EB2E00004ED0 /* CompactMap.swift in Sources */, + 46EB2E00004F50 /* Comparable.swift in Sources */, + 46EB2E00004EE0 /* Cryptor.swift in Sources */, + 46EB2E00004EF0 /* Cryptors.swift in Sources */, + 46EB2E00005430 /* CryptoSwift-dummy.m in Sources */, + 46EB2E00004F60 /* CS.swift in Sources */, + 46EB2E00004E00 /* CTR.swift in Sources */, + 46EB2E000050D0 /* Data+Extension.swift in Sources */, + 46EB2E00004F70 /* DataConversion.swift in Sources */, + 46EB2E000051D0 /* DER.swift in Sources */, + 46EB2E00005070 /* Digest.swift in Sources */, + 46EB2E00005080 /* DigestType.swift in Sources */, + 46EB2E00004F80 /* Division.swift in Sources */, + 46EB2E00004E10 /* ECB.swift in Sources */, + 46EB2E00004F90 /* Exponentiation.swift in Sources */, + 46EB2E00004FA0 /* FloatingPointConversion.swift in Sources */, + 46EB2E00004FB0 /* GCD.swift in Sources */, + 46EB2E00004E20 /* GCM.swift in Sources */, + 46EB2E00005130 /* Generics.swift in Sources */, + 46EB2E00004FC0 /* Hashable.swift in Sources */, + 46EB2E00005140 /* HKDF.swift in Sources */, + 46EB2E00005150 /* HMAC.swift in Sources */, + 46EB2E000050E0 /* HMAC+Foundation.swift in Sources */, + 46EB2E00005160 /* Int+Extension.swift in Sources */, + 46EB2E00004FD0 /* IntegerConversion.swift in Sources */, + 46EB2E00005170 /* ISO10126Padding.swift in Sources */, + 46EB2E00005180 /* ISO78164Padding.swift in Sources */, + 46EB2E00005190 /* MD5.swift in Sources */, + 46EB2E00004FE0 /* Multiplication.swift in Sources */, + 46EB2E000051A0 /* NoPadding.swift in Sources */, + 46EB2E00004E30 /* OCB.swift in Sources */, + 46EB2E00004E40 /* OFB.swift in Sources */, + 46EB2E000051B0 /* Operators.swift in Sources */, + 46EB2E000051C0 /* Padding.swift in Sources */, + 46EB2E000051E0 /* PBKDF1.swift in Sources */, + 46EB2E000051F0 /* PBKDF2.swift in Sources */, + 46EB2E00004E50 /* PCBC.swift in Sources */, + 46EB2E00005200 /* PKCS1v15.swift in Sources */, + 46EB2E00005210 /* PKCS5.swift in Sources */, + 46EB2E00005220 /* PKCS7.swift in Sources */, + 46EB2E00005230 /* PKCS7Padding.swift in Sources */, + 46EB2E00005240 /* Poly1305.swift in Sources */, + 46EB2E00004FF0 /* PrimeTest.swift in Sources */, + 46EB2E00005250 /* Rabbit.swift in Sources */, + 46EB2E000050F0 /* Rabbit+Foundation.swift in Sources */, + 46EB2E00005000 /* Random.swift in Sources */, + 46EB2E00005280 /* RSA.swift in Sources */, + 46EB2E00005260 /* RSA+Cipher.swift in Sources */, + 46EB2E00005270 /* RSA+Signature.swift in Sources */, + 46EB2E00005290 /* Scrypt.swift in Sources */, + 46EB2E000052A0 /* SecureBytes.swift in Sources */, + 46EB2E000052B0 /* SHA1.swift in Sources */, + 46EB2E000052C0 /* SHA2.swift in Sources */, + 46EB2E000052D0 /* SHA3.swift in Sources */, + 46EB2E00005010 /* Shifts.swift in Sources */, + 46EB2E000052E0 /* Signature.swift in Sources */, + 46EB2E00005020 /* SquareRoot.swift in Sources */, + 46EB2E000052F0 /* StreamDecryptor.swift in Sources */, + 46EB2E00005300 /* StreamEncryptor.swift in Sources */, + 46EB2E00005030 /* Strideable.swift in Sources */, + 46EB2E00005310 /* String+Extension.swift in Sources */, + 46EB2E00005100 /* String+FoundationExtension.swift in Sources */, + 46EB2E00005040 /* StringConversion.swift in Sources */, + 46EB2E00005050 /* Subtraction.swift in Sources */, + 46EB2E00005320 /* UInt128.swift in Sources */, + 46EB2E00005330 /* UInt16+Extension.swift in Sources */, + 46EB2E00005340 /* UInt32+Extension.swift in Sources */, + 46EB2E00005350 /* UInt64+Extension.swift in Sources */, + 46EB2E00005360 /* UInt8+Extension.swift in Sources */, + 46EB2E00005370 /* Updatable.swift in Sources */, + 46EB2E00005380 /* Utils.swift in Sources */, + 46EB2E00005110 /* Utils+Foundation.swift in Sources */, + 46EB2E00005060 /* WordsAndBits.swift in Sources */, + 46EB2E00005390 /* XChaCha20.swift in Sources */, + 46EB2E00005120 /* XChaCha20+Foundation.swift in Sources */, + 46EB2E000053A0 /* ZeroPadding.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00004C80 /* Sources */ = { + 46EB2E00004C40 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000054E0 /* Sources */ = { + 46EB2E000054A0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005670 /* DateTools-dummy.m in Sources */, - 46EB2E00005500 /* DTConstants.m in Sources */, - 46EB2E00005510 /* DTError.m in Sources */, - 46EB2E00005520 /* DTTimePeriod.m in Sources */, - 46EB2E00005530 /* DTTimePeriodChain.m in Sources */, - 46EB2E00005540 /* DTTimePeriodCollection.m in Sources */, - 46EB2E00005550 /* DTTimePeriodGroup.m in Sources */, - 46EB2E00005560 /* NSDate+DateTools.m in Sources */, + 46EB2E00005630 /* DateTools-dummy.m in Sources */, + 46EB2E000054C0 /* DTConstants.m in Sources */, + 46EB2E000054D0 /* DTError.m in Sources */, + 46EB2E000054E0 /* DTTimePeriod.m in Sources */, + 46EB2E000054F0 /* DTTimePeriodChain.m in Sources */, + 46EB2E00005500 /* DTTimePeriodCollection.m in Sources */, + 46EB2E00005510 /* DTTimePeriodGroup.m in Sources */, + 46EB2E00005520 /* NSDate+DateTools.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000056E0 /* Sources */ = { + 46EB2E000056A0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005700 /* Constants.swift in Sources */, - 46EB2E00005710 /* Date+Bundle.swift in Sources */, - 46EB2E00005720 /* Date+Comparators.swift in Sources */, - 46EB2E00005730 /* Date+Components.swift in Sources */, - 46EB2E00005740 /* Date+Format.swift in Sources */, - 46EB2E00005750 /* Date+Inits.swift in Sources */, - 46EB2E00005760 /* Date+Manipulations.swift in Sources */, - 46EB2E00005770 /* Date+TimeAgo.swift in Sources */, - 46EB2E00005880 /* DateToolsSwift-dummy.m in Sources */, - 46EB2E00005780 /* Enums.swift in Sources */, - 46EB2E00005790 /* Integer+DateTools.swift in Sources */, - 46EB2E000057A0 /* TimeChunk.swift in Sources */, - 46EB2E000057B0 /* TimePeriod.swift in Sources */, - 46EB2E000057C0 /* TimePeriodChain.swift in Sources */, - 46EB2E000057D0 /* TimePeriodCollection.swift in Sources */, - 46EB2E000057E0 /* TimePeriodGroup.swift in Sources */, + 46EB2E000056C0 /* Constants.swift in Sources */, + 46EB2E000056D0 /* Date+Bundle.swift in Sources */, + 46EB2E000056E0 /* Date+Comparators.swift in Sources */, + 46EB2E000056F0 /* Date+Components.swift in Sources */, + 46EB2E00005700 /* Date+Format.swift in Sources */, + 46EB2E00005710 /* Date+Inits.swift in Sources */, + 46EB2E00005720 /* Date+Manipulations.swift in Sources */, + 46EB2E00005730 /* Date+TimeAgo.swift in Sources */, + 46EB2E00005840 /* DateToolsSwift-dummy.m in Sources */, + 46EB2E00005740 /* Enums.swift in Sources */, + 46EB2E00005750 /* Integer+DateTools.swift in Sources */, + 46EB2E00005760 /* TimeChunk.swift in Sources */, + 46EB2E00005770 /* TimePeriod.swift in Sources */, + 46EB2E00005780 /* TimePeriodChain.swift in Sources */, + 46EB2E00005790 /* TimePeriodCollection.swift in Sources */, + 46EB2E000057A0 /* TimePeriodGroup.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000058F0 /* Sources */ = { + 46EB2E000058B0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00005D90 /* AnimatedImageView.swift in Sources */, - 46EB2E00005BE0 /* AuthenticationChallengeResponsable.swift in Sources */, - 46EB2E00005A90 /* AVAssetImageDataProvider.swift in Sources */, - 46EB2E00005D00 /* Box.swift in Sources */, - 46EB2E000059C0 /* CacheSerializer.swift in Sources */, - 46EB2E00005D10 /* CallbackQueue.swift in Sources */, - 46EB2E00005A20 /* CPListItem+Kingfisher.swift in Sources */, - 46EB2E00005D20 /* Delegate.swift in Sources */, - 46EB2E000059D0 /* DiskStorage.swift in Sources */, - 46EB2E00005D30 /* DisplayLink.swift in Sources */, - 46EB2E00005D40 /* ExtensionHelpers.swift in Sources */, - 46EB2E00005B40 /* Filter.swift in Sources */, - 46EB2E000059E0 /* FormatIndicatedCacheSerializer.swift in Sources */, - 46EB2E00005B50 /* GIFAnimatedImage.swift in Sources */, - 46EB2E00005B60 /* GraphicsContext.swift in Sources */, - 46EB2E00005B70 /* Image.swift in Sources */, - 46EB2E00005C90 /* ImageBinder.swift in Sources */, - 46EB2E000059F0 /* ImageCache.swift in Sources */, - 46EB2E00005CA0 /* ImageContext.swift in Sources */, - 46EB2E00005BF0 /* ImageDataProcessor.swift in Sources */, - 46EB2E00005AA0 /* ImageDataProvider.swift in Sources */, - 46EB2E00005C00 /* ImageDownloader.swift in Sources */, - 46EB2E00005C10 /* ImageDownloaderDelegate.swift in Sources */, - 46EB2E00005B80 /* ImageDrawing.swift in Sources */, - 46EB2E00005B90 /* ImageFormat.swift in Sources */, - 46EB2E00005C20 /* ImageModifier.swift in Sources */, - 46EB2E00005C30 /* ImagePrefetcher.swift in Sources */, - 46EB2E00005BA0 /* ImageProcessor.swift in Sources */, - 46EB2E00005BB0 /* ImageProgressive.swift in Sources */, - 46EB2E00005BC0 /* ImageTransition.swift in Sources */, - 46EB2E00005A30 /* ImageView+Kingfisher.swift in Sources */, - 46EB2E00005DA0 /* Indicator.swift in Sources */, - 46EB2E00005AE0 /* KF.swift in Sources */, - 46EB2E00005CB0 /* KFAnimatedImage.swift in Sources */, - 46EB2E00005CC0 /* KFImage.swift in Sources */, - 46EB2E00005CD0 /* KFImageOptions.swift in Sources */, - 46EB2E00005CE0 /* KFImageProtocol.swift in Sources */, - 46EB2E00005CF0 /* KFImageRenderer.swift in Sources */, - 46EB2E00005AF0 /* KFOptionsSetter.swift in Sources */, - 46EB2E00005B00 /* Kingfisher.swift in Sources */, - 46EB2E00005E30 /* Kingfisher-dummy.m in Sources */, - 46EB2E00005B10 /* KingfisherError.swift in Sources */, - 46EB2E00005B20 /* KingfisherManager.swift in Sources */, - 46EB2E00005B30 /* KingfisherOptionsInfo.swift in Sources */, - 46EB2E00005A00 /* MemoryStorage.swift in Sources */, - 46EB2E00005A40 /* NSButton+Kingfisher.swift in Sources */, - 46EB2E00005A50 /* NSTextAttachment+Kingfisher.swift in Sources */, - 46EB2E00005AB0 /* PHPickerResultImageDataProvider.swift in Sources */, - 46EB2E00005BD0 /* Placeholder.swift in Sources */, - 46EB2E00005C40 /* RedirectHandler.swift in Sources */, - 46EB2E00005C50 /* RequestModifier.swift in Sources */, - 46EB2E00005AC0 /* Resource.swift in Sources */, - 46EB2E00005D50 /* Result.swift in Sources */, - 46EB2E00005C60 /* RetryStrategy.swift in Sources */, - 46EB2E00005D60 /* Runtime.swift in Sources */, - 46EB2E00005C70 /* SessionDataTask.swift in Sources */, - 46EB2E00005C80 /* SessionDelegate.swift in Sources */, - 46EB2E00005D70 /* SizeExtensions.swift in Sources */, - 46EB2E00005AD0 /* Source.swift in Sources */, - 46EB2E00005A10 /* Storage.swift in Sources */, - 46EB2E00005D80 /* String+MD5.swift in Sources */, - 46EB2E00005A60 /* TVMonogramView+Kingfisher.swift in Sources */, - 46EB2E00005A70 /* UIButton+Kingfisher.swift in Sources */, - 46EB2E00005A80 /* WKInterfaceImage+Kingfisher.swift in Sources */, + 46EB2E00005D50 /* AnimatedImageView.swift in Sources */, + 46EB2E00005BA0 /* AuthenticationChallengeResponsable.swift in Sources */, + 46EB2E00005A50 /* AVAssetImageDataProvider.swift in Sources */, + 46EB2E00005CC0 /* Box.swift in Sources */, + 46EB2E00005980 /* CacheSerializer.swift in Sources */, + 46EB2E00005CD0 /* CallbackQueue.swift in Sources */, + 46EB2E000059E0 /* CPListItem+Kingfisher.swift in Sources */, + 46EB2E00005CE0 /* Delegate.swift in Sources */, + 46EB2E00005990 /* DiskStorage.swift in Sources */, + 46EB2E00005CF0 /* DisplayLink.swift in Sources */, + 46EB2E00005D00 /* ExtensionHelpers.swift in Sources */, + 46EB2E00005B00 /* Filter.swift in Sources */, + 46EB2E000059A0 /* FormatIndicatedCacheSerializer.swift in Sources */, + 46EB2E00005B10 /* GIFAnimatedImage.swift in Sources */, + 46EB2E00005B20 /* GraphicsContext.swift in Sources */, + 46EB2E00005B30 /* Image.swift in Sources */, + 46EB2E00005C50 /* ImageBinder.swift in Sources */, + 46EB2E000059B0 /* ImageCache.swift in Sources */, + 46EB2E00005C60 /* ImageContext.swift in Sources */, + 46EB2E00005BB0 /* ImageDataProcessor.swift in Sources */, + 46EB2E00005A60 /* ImageDataProvider.swift in Sources */, + 46EB2E00005BC0 /* ImageDownloader.swift in Sources */, + 46EB2E00005BD0 /* ImageDownloaderDelegate.swift in Sources */, + 46EB2E00005B40 /* ImageDrawing.swift in Sources */, + 46EB2E00005B50 /* ImageFormat.swift in Sources */, + 46EB2E00005BE0 /* ImageModifier.swift in Sources */, + 46EB2E00005BF0 /* ImagePrefetcher.swift in Sources */, + 46EB2E00005B60 /* ImageProcessor.swift in Sources */, + 46EB2E00005B70 /* ImageProgressive.swift in Sources */, + 46EB2E00005B80 /* ImageTransition.swift in Sources */, + 46EB2E000059F0 /* ImageView+Kingfisher.swift in Sources */, + 46EB2E00005D60 /* Indicator.swift in Sources */, + 46EB2E00005AA0 /* KF.swift in Sources */, + 46EB2E00005C70 /* KFAnimatedImage.swift in Sources */, + 46EB2E00005C80 /* KFImage.swift in Sources */, + 46EB2E00005C90 /* KFImageOptions.swift in Sources */, + 46EB2E00005CA0 /* KFImageProtocol.swift in Sources */, + 46EB2E00005CB0 /* KFImageRenderer.swift in Sources */, + 46EB2E00005AB0 /* KFOptionsSetter.swift in Sources */, + 46EB2E00005AC0 /* Kingfisher.swift in Sources */, + 46EB2E00005DF0 /* Kingfisher-dummy.m in Sources */, + 46EB2E00005AD0 /* KingfisherError.swift in Sources */, + 46EB2E00005AE0 /* KingfisherManager.swift in Sources */, + 46EB2E00005AF0 /* KingfisherOptionsInfo.swift in Sources */, + 46EB2E000059C0 /* MemoryStorage.swift in Sources */, + 46EB2E00005A00 /* NSButton+Kingfisher.swift in Sources */, + 46EB2E00005A10 /* NSTextAttachment+Kingfisher.swift in Sources */, + 46EB2E00005A70 /* PHPickerResultImageDataProvider.swift in Sources */, + 46EB2E00005B90 /* Placeholder.swift in Sources */, + 46EB2E00005C00 /* RedirectHandler.swift in Sources */, + 46EB2E00005C10 /* RequestModifier.swift in Sources */, + 46EB2E00005A80 /* Resource.swift in Sources */, + 46EB2E00005D10 /* Result.swift in Sources */, + 46EB2E00005C20 /* RetryStrategy.swift in Sources */, + 46EB2E00005D20 /* Runtime.swift in Sources */, + 46EB2E00005C30 /* SessionDataTask.swift in Sources */, + 46EB2E00005C40 /* SessionDelegate.swift in Sources */, + 46EB2E00005D30 /* SizeExtensions.swift in Sources */, + 46EB2E00005A90 /* Source.swift in Sources */, + 46EB2E000059D0 /* Storage.swift in Sources */, + 46EB2E00005D40 /* String+MD5.swift in Sources */, + 46EB2E00005A20 /* TVMonogramView+Kingfisher.swift in Sources */, + 46EB2E00005A30 /* UIButton+Kingfisher.swift in Sources */, + 46EB2E00005A40 /* WKInterfaceImage+Kingfisher.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005960 /* Sources */ = { + 46EB2E00005920 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00005EA0 /* Sources */ = { + 46EB2E00005E60 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000060C0 /* CALayer+Lookin.m in Sources */, - 46EB2E00005EC0 /* CALayer+LookinServer.m in Sources */, - 46EB2E000060D0 /* Color+Lookin.m in Sources */, - 46EB2E000060E0 /* Image+Lookin.m in Sources */, - 46EB2E00006000 /* LKS_AttrGroupsMaker.m in Sources */, - 46EB2E00005FB0 /* LKS_AttrModificationPatchHandler.m in Sources */, - 46EB2E00005F90 /* LKS_ConnectionManager.m in Sources */, - 46EB2E00006010 /* LKS_CustomAttrGroupsMaker.m in Sources */, - 46EB2E00005FC0 /* LKS_CustomAttrModificationHandler.m in Sources */, - 46EB2E00006020 /* LKS_CustomAttrSetterManager.m in Sources */, - 46EB2E00006030 /* LKS_CustomDisplayItemsMaker.m in Sources */, - 46EB2E00006040 /* LKS_EventHandlerMaker.m in Sources */, - 46EB2E00006050 /* LKS_ExportManager.m in Sources */, - 46EB2E00006060 /* LKS_GestureTargetActionsSearcher.m in Sources */, - 46EB2E00006070 /* LKS_Helper.m in Sources */, - 46EB2E00005FD0 /* LKS_HierarchyDetailsHandler.m in Sources */, - 46EB2E00006080 /* LKS_HierarchyDisplayItemsMaker.m in Sources */, - 46EB2E00005FE0 /* LKS_InbuiltAttrModificationHandler.m in Sources */, - 46EB2E00006090 /* LKS_MultiplatformAdapter.m in Sources */, - 46EB2E000060A0 /* LKS_ObjectRegistry.m in Sources */, - 46EB2E00005FA0 /* LKS_RequestHandler.m in Sources */, - 46EB2E000060B0 /* LKS_TraceManager.m in Sources */, - 46EB2E00005FF0 /* LKSConfigManager.m in Sources */, - 46EB2E00006280 /* Lookin_PTChannel.m in Sources */, - 46EB2E00006290 /* Lookin_PTProtocol.m in Sources */, - 46EB2E000062A0 /* Lookin_PTUSBHub.m in Sources */, - 46EB2E00006130 /* LookinAppInfo.m in Sources */, - 46EB2E00006140 /* LookinAttribute.m in Sources */, - 46EB2E00006150 /* LookinAttributeModification.m in Sources */, - 46EB2E00006160 /* LookinAttributesGroup.m in Sources */, - 46EB2E00006170 /* LookinAttributesSection.m in Sources */, - 46EB2E00006180 /* LookinAttrIdentifiers.m in Sources */, - 46EB2E00006190 /* LookinAutoLayoutConstraint.m in Sources */, - 46EB2E000061A0 /* LookinConnectionAttachment.m in Sources */, - 46EB2E000061B0 /* LookinConnectionResponseAttachment.m in Sources */, - 46EB2E000061C0 /* LookinCustomAttrModification.m in Sources */, - 46EB2E000061D0 /* LookinCustomDisplayItemInfo.m in Sources */, - 46EB2E000061E0 /* LookinDashboardBlueprint.m in Sources */, - 46EB2E000061F0 /* LookinDisplayItem.m in Sources */, - 46EB2E00006200 /* LookinDisplayItemDetail.m in Sources */, - 46EB2E00006210 /* LookinEventHandler.m in Sources */, - 46EB2E00006220 /* LookinHierarchyFile.m in Sources */, - 46EB2E00006230 /* LookinHierarchyInfo.m in Sources */, - 46EB2E000062B0 /* LookinIvarTrace.m in Sources */, - 46EB2E00006240 /* LookinObject.m in Sources */, - 46EB2E000067B0 /* LookinServer-dummy.m in Sources */, - 46EB2E00006250 /* LookinStaticAsyncUpdateTask.m in Sources */, - 46EB2E00006260 /* LookinTuple.m in Sources */, - 46EB2E00006270 /* LookinWeakContainer.m in Sources */, - 46EB2E000060F0 /* NSArray+Lookin.m in Sources */, - 46EB2E00006100 /* NSObject+Lookin.m in Sources */, - 46EB2E00005ED0 /* NSObject+LookinServer.m in Sources */, - 46EB2E00006110 /* NSSet+Lookin.m in Sources */, - 46EB2E00006120 /* NSString+Lookin.m in Sources */, - 46EB2E00005EE0 /* UIBlurEffect+LookinServer.m in Sources */, - 46EB2E00005EF0 /* UIColor+LookinServer.m in Sources */, - 46EB2E00005F00 /* UIImage+LookinServer.m in Sources */, - 46EB2E00005F10 /* UIImageView+LookinServer.m in Sources */, - 46EB2E00005F20 /* UILabel+LookinServer.m in Sources */, - 46EB2E00005F30 /* UITableView+LookinServer.m in Sources */, - 46EB2E00005F40 /* UITextField+LookinServer.m in Sources */, - 46EB2E00005F50 /* UITextView+LookinServer.m in Sources */, - 46EB2E00005F60 /* UIView+LookinServer.m in Sources */, - 46EB2E00005F70 /* UIViewController+LookinServer.m in Sources */, - 46EB2E00005F80 /* UIVisualEffectView+LookinServer.m in Sources */, + 46EB2E00006080 /* CALayer+Lookin.m in Sources */, + 46EB2E00005E80 /* CALayer+LookinServer.m in Sources */, + 46EB2E00006090 /* Color+Lookin.m in Sources */, + 46EB2E000060A0 /* Image+Lookin.m in Sources */, + 46EB2E00005FC0 /* LKS_AttrGroupsMaker.m in Sources */, + 46EB2E00005F70 /* LKS_AttrModificationPatchHandler.m in Sources */, + 46EB2E00005F50 /* LKS_ConnectionManager.m in Sources */, + 46EB2E00005FD0 /* LKS_CustomAttrGroupsMaker.m in Sources */, + 46EB2E00005F80 /* LKS_CustomAttrModificationHandler.m in Sources */, + 46EB2E00005FE0 /* LKS_CustomAttrSetterManager.m in Sources */, + 46EB2E00005FF0 /* LKS_CustomDisplayItemsMaker.m in Sources */, + 46EB2E00006000 /* LKS_EventHandlerMaker.m in Sources */, + 46EB2E00006010 /* LKS_ExportManager.m in Sources */, + 46EB2E00006020 /* LKS_GestureTargetActionsSearcher.m in Sources */, + 46EB2E00006030 /* LKS_Helper.m in Sources */, + 46EB2E00005F90 /* LKS_HierarchyDetailsHandler.m in Sources */, + 46EB2E00006040 /* LKS_HierarchyDisplayItemsMaker.m in Sources */, + 46EB2E00005FA0 /* LKS_InbuiltAttrModificationHandler.m in Sources */, + 46EB2E00006050 /* LKS_MultiplatformAdapter.m in Sources */, + 46EB2E00006060 /* LKS_ObjectRegistry.m in Sources */, + 46EB2E00005F60 /* LKS_RequestHandler.m in Sources */, + 46EB2E00006070 /* LKS_TraceManager.m in Sources */, + 46EB2E00005FB0 /* LKSConfigManager.m in Sources */, + 46EB2E00006240 /* Lookin_PTChannel.m in Sources */, + 46EB2E00006250 /* Lookin_PTProtocol.m in Sources */, + 46EB2E00006260 /* Lookin_PTUSBHub.m in Sources */, + 46EB2E000060F0 /* LookinAppInfo.m in Sources */, + 46EB2E00006100 /* LookinAttribute.m in Sources */, + 46EB2E00006110 /* LookinAttributeModification.m in Sources */, + 46EB2E00006120 /* LookinAttributesGroup.m in Sources */, + 46EB2E00006130 /* LookinAttributesSection.m in Sources */, + 46EB2E00006140 /* LookinAttrIdentifiers.m in Sources */, + 46EB2E00006150 /* LookinAutoLayoutConstraint.m in Sources */, + 46EB2E00006160 /* LookinConnectionAttachment.m in Sources */, + 46EB2E00006170 /* LookinConnectionResponseAttachment.m in Sources */, + 46EB2E00006180 /* LookinCustomAttrModification.m in Sources */, + 46EB2E00006190 /* LookinCustomDisplayItemInfo.m in Sources */, + 46EB2E000061A0 /* LookinDashboardBlueprint.m in Sources */, + 46EB2E000061B0 /* LookinDisplayItem.m in Sources */, + 46EB2E000061C0 /* LookinDisplayItemDetail.m in Sources */, + 46EB2E000061D0 /* LookinEventHandler.m in Sources */, + 46EB2E000061E0 /* LookinHierarchyFile.m in Sources */, + 46EB2E000061F0 /* LookinHierarchyInfo.m in Sources */, + 46EB2E00006270 /* LookinIvarTrace.m in Sources */, + 46EB2E00006200 /* LookinObject.m in Sources */, + 46EB2E00006770 /* LookinServer-dummy.m in Sources */, + 46EB2E00006210 /* LookinStaticAsyncUpdateTask.m in Sources */, + 46EB2E00006220 /* LookinTuple.m in Sources */, + 46EB2E00006230 /* LookinWeakContainer.m in Sources */, + 46EB2E000060B0 /* NSArray+Lookin.m in Sources */, + 46EB2E000060C0 /* NSObject+Lookin.m in Sources */, + 46EB2E00005E90 /* NSObject+LookinServer.m in Sources */, + 46EB2E000060D0 /* NSSet+Lookin.m in Sources */, + 46EB2E000060E0 /* NSString+Lookin.m in Sources */, + 46EB2E00005EA0 /* UIBlurEffect+LookinServer.m in Sources */, + 46EB2E00005EB0 /* UIColor+LookinServer.m in Sources */, + 46EB2E00005EC0 /* UIImage+LookinServer.m in Sources */, + 46EB2E00005ED0 /* UIImageView+LookinServer.m in Sources */, + 46EB2E00005EE0 /* UILabel+LookinServer.m in Sources */, + 46EB2E00005EF0 /* UITableView+LookinServer.m in Sources */, + 46EB2E00005F00 /* UITextField+LookinServer.m in Sources */, + 46EB2E00005F10 /* UITextView+LookinServer.m in Sources */, + 46EB2E00005F20 /* UIView+LookinServer.m in Sources */, + 46EB2E00005F30 /* UIViewController+LookinServer.m in Sources */, + 46EB2E00005F40 /* UIVisualEffectView+LookinServer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006820 /* Sources */ = { + 46EB2E000067E0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00006AB0 /* MJExtension-dummy.m in Sources */, - 46EB2E000068F0 /* MJExtensionConst.m in Sources */, - 46EB2E00006900 /* MJFoundation.m in Sources */, - 46EB2E00006910 /* MJProperty.m in Sources */, - 46EB2E00006920 /* MJPropertyKey.m in Sources */, - 46EB2E00006930 /* MJPropertyType.m in Sources */, - 46EB2E00006940 /* NSObject+MJClass.m in Sources */, - 46EB2E00006950 /* NSObject+MJCoding.m in Sources */, - 46EB2E00006960 /* NSObject+MJKeyValue.m in Sources */, - 46EB2E00006970 /* NSObject+MJProperty.m in Sources */, - 46EB2E00006980 /* NSString+MJExtension.m in Sources */, + 46EB2E00006A60 /* MJExtension-dummy.m in Sources */, + 46EB2E000068A0 /* MJExtensionConst.m in Sources */, + 46EB2E000068B0 /* MJFoundation.m in Sources */, + 46EB2E000068C0 /* MJProperty.m in Sources */, + 46EB2E000068D0 /* MJPropertyKey.m in Sources */, + 46EB2E000068E0 /* MJPropertyType.m in Sources */, + 46EB2E000068F0 /* NSObject+MJClass.m in Sources */, + 46EB2E00006900 /* NSObject+MJCoding.m in Sources */, + 46EB2E00006910 /* NSObject+MJKeyValue.m in Sources */, + 46EB2E00006920 /* NSObject+MJProperty.m in Sources */, + 46EB2E00006930 /* NSString+MJExtension.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006890 /* Sources */ = { + 46EB2E00006850 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006B20 /* Sources */ = { + 46EB2E00006AD0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00006B40 /* MASCompositeConstraint.m in Sources */, - 46EB2E00006B50 /* MASConstraint.m in Sources */, - 46EB2E00006B60 /* MASConstraintMaker.m in Sources */, - 46EB2E00006B70 /* MASLayoutConstraint.m in Sources */, - 46EB2E00006D50 /* Masonry-dummy.m in Sources */, - 46EB2E00006B80 /* MASViewAttribute.m in Sources */, - 46EB2E00006B90 /* MASViewConstraint.m in Sources */, - 46EB2E00006BA0 /* NSArray+MASAdditions.m in Sources */, - 46EB2E00006BB0 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */, - 46EB2E00006BC0 /* View+MASAdditions.m in Sources */, - 46EB2E00006BD0 /* ViewController+MASAdditions.m in Sources */, + 46EB2E00006AF0 /* MASCompositeConstraint.m in Sources */, + 46EB2E00006B00 /* MASConstraint.m in Sources */, + 46EB2E00006B10 /* MASConstraintMaker.m in Sources */, + 46EB2E00006B20 /* MASLayoutConstraint.m in Sources */, + 46EB2E00006D00 /* Masonry-dummy.m in Sources */, + 46EB2E00006B30 /* MASViewAttribute.m in Sources */, + 46EB2E00006B40 /* MASViewConstraint.m in Sources */, + 46EB2E00006B50 /* NSArray+MASAdditions.m in Sources */, + 46EB2E00006B60 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */, + 46EB2E00006B70 /* View+MASAdditions.m in Sources */, + 46EB2E00006B80 /* ViewController+MASAdditions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006DC0 /* Sources */ = { + 46EB2E00006D70 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007250 /* NSBezierPath+SDRoundedCorners.m in Sources */, - 46EB2E00006E90 /* NSButton+WebCache.m in Sources */, - 46EB2E00006EA0 /* NSData+ImageContentType.m in Sources */, - 46EB2E00006EB0 /* NSImage+Compatibility.m in Sources */, - 46EB2E00006EC0 /* SDAnimatedImage.m in Sources */, - 46EB2E00006ED0 /* SDAnimatedImagePlayer.m in Sources */, - 46EB2E00006EE0 /* SDAnimatedImageRep.m in Sources */, - 46EB2E00006F00 /* SDAnimatedImageView.m in Sources */, - 46EB2E00006EF0 /* SDAnimatedImageView+WebCache.m in Sources */, - 46EB2E00007260 /* SDAssociatedObject.m in Sources */, - 46EB2E00007270 /* SDAsyncBlockOperation.m in Sources */, - 46EB2E00006F10 /* SDCallbackQueue.m in Sources */, - 46EB2E00007280 /* SDDeviceHelper.m in Sources */, - 46EB2E00006F20 /* SDDiskCache.m in Sources */, - 46EB2E00007290 /* SDDisplayLink.m in Sources */, - 46EB2E000072A0 /* SDFileAttributeHelper.m in Sources */, - 46EB2E00006F30 /* SDGraphicsImageRenderer.m in Sources */, - 46EB2E00006F40 /* SDImageAPNGCoder.m in Sources */, - 46EB2E000072B0 /* SDImageAssetManager.m in Sources */, - 46EB2E00006F50 /* SDImageAWebPCoder.m in Sources */, - 46EB2E00006F60 /* SDImageCache.m in Sources */, - 46EB2E00006F70 /* SDImageCacheConfig.m in Sources */, - 46EB2E00006F80 /* SDImageCacheDefine.m in Sources */, - 46EB2E00006F90 /* SDImageCachesManager.m in Sources */, - 46EB2E000072C0 /* SDImageCachesManagerOperation.m in Sources */, - 46EB2E00006FA0 /* SDImageCoder.m in Sources */, - 46EB2E00006FB0 /* SDImageCoderHelper.m in Sources */, - 46EB2E00006FC0 /* SDImageCodersManager.m in Sources */, - 46EB2E00006FD0 /* SDImageFrame.m in Sources */, - 46EB2E000072D0 /* SDImageFramePool.m in Sources */, - 46EB2E00006FE0 /* SDImageGIFCoder.m in Sources */, - 46EB2E00006FF0 /* SDImageGraphics.m in Sources */, - 46EB2E00007000 /* SDImageHEICCoder.m in Sources */, - 46EB2E00007010 /* SDImageIOAnimatedCoder.m in Sources */, - 46EB2E00007020 /* SDImageIOCoder.m in Sources */, - 46EB2E00007030 /* SDImageLoader.m in Sources */, - 46EB2E00007040 /* SDImageLoadersManager.m in Sources */, - 46EB2E00007050 /* SDImageTransformer.m in Sources */, - 46EB2E000072E0 /* SDInternalMacros.m in Sources */, - 46EB2E00007060 /* SDMemoryCache.m in Sources */, - 46EB2E000072F0 /* SDWeakProxy.m in Sources */, - 46EB2E00007840 /* SDWebImage-dummy.m in Sources */, - 46EB2E00007070 /* SDWebImageCacheKeyFilter.m in Sources */, - 46EB2E00007080 /* SDWebImageCacheSerializer.m in Sources */, - 46EB2E00007090 /* SDWebImageCompat.m in Sources */, - 46EB2E000070A0 /* SDWebImageDefine.m in Sources */, - 46EB2E000070B0 /* SDWebImageDownloader.m in Sources */, - 46EB2E000070C0 /* SDWebImageDownloaderConfig.m in Sources */, - 46EB2E000070D0 /* SDWebImageDownloaderDecryptor.m in Sources */, - 46EB2E000070E0 /* SDWebImageDownloaderOperation.m in Sources */, - 46EB2E000070F0 /* SDWebImageDownloaderRequestModifier.m in Sources */, - 46EB2E00007100 /* SDWebImageDownloaderResponseModifier.m in Sources */, - 46EB2E00007110 /* SDWebImageError.m in Sources */, - 46EB2E00007120 /* SDWebImageIndicator.m in Sources */, - 46EB2E00007130 /* SDWebImageManager.m in Sources */, - 46EB2E00007140 /* SDWebImageOperation.m in Sources */, - 46EB2E00007150 /* SDWebImageOptionsProcessor.m in Sources */, - 46EB2E00007160 /* SDWebImagePrefetcher.m in Sources */, - 46EB2E00007170 /* SDWebImageTransition.m in Sources */, - 46EB2E00007180 /* UIButton+WebCache.m in Sources */, - 46EB2E00007300 /* UIColor+SDHexString.m in Sources */, - 46EB2E00007190 /* UIImage+ExtendedCacheData.m in Sources */, - 46EB2E000071A0 /* UIImage+ForceDecode.m in Sources */, - 46EB2E000071B0 /* UIImage+GIF.m in Sources */, - 46EB2E000071C0 /* UIImage+MemoryCacheCost.m in Sources */, - 46EB2E000071D0 /* UIImage+Metadata.m in Sources */, - 46EB2E000071E0 /* UIImage+MultiFormat.m in Sources */, - 46EB2E000071F0 /* UIImage+Transform.m in Sources */, - 46EB2E00007200 /* UIImageView+HighlightedWebCache.m in Sources */, - 46EB2E00007210 /* UIImageView+WebCache.m in Sources */, - 46EB2E00007220 /* UIView+WebCache.m in Sources */, - 46EB2E00007230 /* UIView+WebCacheOperation.m in Sources */, - 46EB2E00007240 /* UIView+WebCacheState.m in Sources */, + 46EB2E00007200 /* NSBezierPath+SDRoundedCorners.m in Sources */, + 46EB2E00006E40 /* NSButton+WebCache.m in Sources */, + 46EB2E00006E50 /* NSData+ImageContentType.m in Sources */, + 46EB2E00006E60 /* NSImage+Compatibility.m in Sources */, + 46EB2E00006E70 /* SDAnimatedImage.m in Sources */, + 46EB2E00006E80 /* SDAnimatedImagePlayer.m in Sources */, + 46EB2E00006E90 /* SDAnimatedImageRep.m in Sources */, + 46EB2E00006EB0 /* SDAnimatedImageView.m in Sources */, + 46EB2E00006EA0 /* SDAnimatedImageView+WebCache.m in Sources */, + 46EB2E00007210 /* SDAssociatedObject.m in Sources */, + 46EB2E00007220 /* SDAsyncBlockOperation.m in Sources */, + 46EB2E00006EC0 /* SDCallbackQueue.m in Sources */, + 46EB2E00007230 /* SDDeviceHelper.m in Sources */, + 46EB2E00006ED0 /* SDDiskCache.m in Sources */, + 46EB2E00007240 /* SDDisplayLink.m in Sources */, + 46EB2E00007250 /* SDFileAttributeHelper.m in Sources */, + 46EB2E00006EE0 /* SDGraphicsImageRenderer.m in Sources */, + 46EB2E00006EF0 /* SDImageAPNGCoder.m in Sources */, + 46EB2E00007260 /* SDImageAssetManager.m in Sources */, + 46EB2E00006F00 /* SDImageAWebPCoder.m in Sources */, + 46EB2E00006F10 /* SDImageCache.m in Sources */, + 46EB2E00006F20 /* SDImageCacheConfig.m in Sources */, + 46EB2E00006F30 /* SDImageCacheDefine.m in Sources */, + 46EB2E00006F40 /* SDImageCachesManager.m in Sources */, + 46EB2E00007270 /* SDImageCachesManagerOperation.m in Sources */, + 46EB2E00006F50 /* SDImageCoder.m in Sources */, + 46EB2E00006F60 /* SDImageCoderHelper.m in Sources */, + 46EB2E00006F70 /* SDImageCodersManager.m in Sources */, + 46EB2E00006F80 /* SDImageFrame.m in Sources */, + 46EB2E00007280 /* SDImageFramePool.m in Sources */, + 46EB2E00006F90 /* SDImageGIFCoder.m in Sources */, + 46EB2E00006FA0 /* SDImageGraphics.m in Sources */, + 46EB2E00006FB0 /* SDImageHEICCoder.m in Sources */, + 46EB2E00006FC0 /* SDImageIOAnimatedCoder.m in Sources */, + 46EB2E00006FD0 /* SDImageIOCoder.m in Sources */, + 46EB2E00006FE0 /* SDImageLoader.m in Sources */, + 46EB2E00006FF0 /* SDImageLoadersManager.m in Sources */, + 46EB2E00007000 /* SDImageTransformer.m in Sources */, + 46EB2E00007290 /* SDInternalMacros.m in Sources */, + 46EB2E00007010 /* SDMemoryCache.m in Sources */, + 46EB2E000072A0 /* SDWeakProxy.m in Sources */, + 46EB2E000077F0 /* SDWebImage-dummy.m in Sources */, + 46EB2E00007020 /* SDWebImageCacheKeyFilter.m in Sources */, + 46EB2E00007030 /* SDWebImageCacheSerializer.m in Sources */, + 46EB2E00007040 /* SDWebImageCompat.m in Sources */, + 46EB2E00007050 /* SDWebImageDefine.m in Sources */, + 46EB2E00007060 /* SDWebImageDownloader.m in Sources */, + 46EB2E00007070 /* SDWebImageDownloaderConfig.m in Sources */, + 46EB2E00007080 /* SDWebImageDownloaderDecryptor.m in Sources */, + 46EB2E00007090 /* SDWebImageDownloaderOperation.m in Sources */, + 46EB2E000070A0 /* SDWebImageDownloaderRequestModifier.m in Sources */, + 46EB2E000070B0 /* SDWebImageDownloaderResponseModifier.m in Sources */, + 46EB2E000070C0 /* SDWebImageError.m in Sources */, + 46EB2E000070D0 /* SDWebImageIndicator.m in Sources */, + 46EB2E000070E0 /* SDWebImageManager.m in Sources */, + 46EB2E000070F0 /* SDWebImageOperation.m in Sources */, + 46EB2E00007100 /* SDWebImageOptionsProcessor.m in Sources */, + 46EB2E00007110 /* SDWebImagePrefetcher.m in Sources */, + 46EB2E00007120 /* SDWebImageTransition.m in Sources */, + 46EB2E00007130 /* UIButton+WebCache.m in Sources */, + 46EB2E000072B0 /* UIColor+SDHexString.m in Sources */, + 46EB2E00007140 /* UIImage+ExtendedCacheData.m in Sources */, + 46EB2E00007150 /* UIImage+ForceDecode.m in Sources */, + 46EB2E00007160 /* UIImage+GIF.m in Sources */, + 46EB2E00007170 /* UIImage+MemoryCacheCost.m in Sources */, + 46EB2E00007180 /* UIImage+Metadata.m in Sources */, + 46EB2E00007190 /* UIImage+MultiFormat.m in Sources */, + 46EB2E000071A0 /* UIImage+Transform.m in Sources */, + 46EB2E000071B0 /* UIImageView+HighlightedWebCache.m in Sources */, + 46EB2E000071C0 /* UIImageView+WebCache.m in Sources */, + 46EB2E000071D0 /* UIView+WebCache.m in Sources */, + 46EB2E000071E0 /* UIView+WebCacheOperation.m in Sources */, + 46EB2E000071F0 /* UIView+WebCacheState.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00006E30 /* Sources */ = { + 46EB2E00006DE0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000078B0 /* Sources */ = { + 46EB2E00007860 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000078D0 /* SDImageWebPCoder.m in Sources */, - 46EB2E000079C0 /* SDWebImageWebPCoder-dummy.m in Sources */, - 46EB2E000078E0 /* SDWebImageWebPCoderDefine.m in Sources */, - 46EB2E000078F0 /* UIImage+WebP.m in Sources */, + 46EB2E00007880 /* SDImageWebPCoder.m in Sources */, + 46EB2E00007970 /* SDWebImageWebPCoder-dummy.m in Sources */, + 46EB2E00007890 /* SDWebImageWebPCoderDefine.m in Sources */, + 46EB2E000078A0 /* UIImage+WebP.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007A30 /* Sources */ = { + 46EB2E000079E0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007B00 /* Constraint.swift in Sources */, - 46EB2E00007B10 /* ConstraintAttributes.swift in Sources */, - 46EB2E00007B20 /* ConstraintConfig.swift in Sources */, - 46EB2E00007B30 /* ConstraintConstantTarget.swift in Sources */, - 46EB2E00007B40 /* ConstraintDescription.swift in Sources */, - 46EB2E00007B50 /* ConstraintDirectionalInsets.swift in Sources */, - 46EB2E00007B60 /* ConstraintDirectionalInsetTarget.swift in Sources */, - 46EB2E00007B70 /* ConstraintDSL.swift in Sources */, - 46EB2E00007B80 /* ConstraintInsets.swift in Sources */, - 46EB2E00007B90 /* ConstraintInsetTarget.swift in Sources */, - 46EB2E00007BA0 /* ConstraintItem.swift in Sources */, - 46EB2E00007BC0 /* ConstraintLayoutGuide.swift in Sources */, - 46EB2E00007BB0 /* ConstraintLayoutGuide+Extensions.swift in Sources */, - 46EB2E00007BD0 /* ConstraintLayoutGuideDSL.swift in Sources */, - 46EB2E00007BE0 /* ConstraintLayoutSupport.swift in Sources */, - 46EB2E00007BF0 /* ConstraintLayoutSupportDSL.swift in Sources */, - 46EB2E00007C00 /* ConstraintMaker.swift in Sources */, - 46EB2E00007C10 /* ConstraintMakerEditable.swift in Sources */, - 46EB2E00007C20 /* ConstraintMakerExtendable.swift in Sources */, - 46EB2E00007C30 /* ConstraintMakerFinalizable.swift in Sources */, - 46EB2E00007C40 /* ConstraintMakerPrioritizable.swift in Sources */, - 46EB2E00007C60 /* ConstraintMakerRelatable.swift in Sources */, - 46EB2E00007C50 /* ConstraintMakerRelatable+Extensions.swift in Sources */, - 46EB2E00007C70 /* ConstraintMultiplierTarget.swift in Sources */, - 46EB2E00007C80 /* ConstraintOffsetTarget.swift in Sources */, - 46EB2E00007C90 /* ConstraintPriority.swift in Sources */, - 46EB2E00007CA0 /* ConstraintPriorityTarget.swift in Sources */, - 46EB2E00007CB0 /* ConstraintRelatableTarget.swift in Sources */, - 46EB2E00007CC0 /* ConstraintRelation.swift in Sources */, - 46EB2E00007CE0 /* ConstraintView.swift in Sources */, - 46EB2E00007CD0 /* ConstraintView+Extensions.swift in Sources */, - 46EB2E00007CF0 /* ConstraintViewDSL.swift in Sources */, - 46EB2E00007D00 /* Debugging.swift in Sources */, - 46EB2E00007D10 /* LayoutConstraint.swift in Sources */, - 46EB2E00007D20 /* LayoutConstraintItem.swift in Sources */, - 46EB2E00007DD0 /* SnapKit-dummy.m in Sources */, - 46EB2E00007D30 /* Typealiases.swift in Sources */, - 46EB2E00007D40 /* UILayoutSupport+Extensions.swift in Sources */, + 46EB2E00007AA0 /* Constraint.swift in Sources */, + 46EB2E00007AB0 /* ConstraintAttributes.swift in Sources */, + 46EB2E00007AC0 /* ConstraintConfig.swift in Sources */, + 46EB2E00007AD0 /* ConstraintConstantTarget.swift in Sources */, + 46EB2E00007AE0 /* ConstraintDescription.swift in Sources */, + 46EB2E00007AF0 /* ConstraintDirectionalInsets.swift in Sources */, + 46EB2E00007B00 /* ConstraintDirectionalInsetTarget.swift in Sources */, + 46EB2E00007B10 /* ConstraintDSL.swift in Sources */, + 46EB2E00007B20 /* ConstraintInsets.swift in Sources */, + 46EB2E00007B30 /* ConstraintInsetTarget.swift in Sources */, + 46EB2E00007B40 /* ConstraintItem.swift in Sources */, + 46EB2E00007B60 /* ConstraintLayoutGuide.swift in Sources */, + 46EB2E00007B50 /* ConstraintLayoutGuide+Extensions.swift in Sources */, + 46EB2E00007B70 /* ConstraintLayoutGuideDSL.swift in Sources */, + 46EB2E00007B80 /* ConstraintLayoutSupport.swift in Sources */, + 46EB2E00007B90 /* ConstraintLayoutSupportDSL.swift in Sources */, + 46EB2E00007BA0 /* ConstraintMaker.swift in Sources */, + 46EB2E00007BB0 /* ConstraintMakerEditable.swift in Sources */, + 46EB2E00007BC0 /* ConstraintMakerExtendable.swift in Sources */, + 46EB2E00007BD0 /* ConstraintMakerFinalizable.swift in Sources */, + 46EB2E00007BE0 /* ConstraintMakerPrioritizable.swift in Sources */, + 46EB2E00007C00 /* ConstraintMakerRelatable.swift in Sources */, + 46EB2E00007BF0 /* ConstraintMakerRelatable+Extensions.swift in Sources */, + 46EB2E00007C10 /* ConstraintMultiplierTarget.swift in Sources */, + 46EB2E00007C20 /* ConstraintOffsetTarget.swift in Sources */, + 46EB2E00007C30 /* ConstraintPriority.swift in Sources */, + 46EB2E00007C40 /* ConstraintPriorityTarget.swift in Sources */, + 46EB2E00007C50 /* ConstraintRelatableTarget.swift in Sources */, + 46EB2E00007C60 /* ConstraintRelation.swift in Sources */, + 46EB2E00007C80 /* ConstraintView.swift in Sources */, + 46EB2E00007C70 /* ConstraintView+Extensions.swift in Sources */, + 46EB2E00007C90 /* ConstraintViewDSL.swift in Sources */, + 46EB2E00007CA0 /* Debugging.swift in Sources */, + 46EB2E00007CB0 /* LayoutConstraint.swift in Sources */, + 46EB2E00007CC0 /* LayoutConstraintItem.swift in Sources */, + 46EB2E00007D70 /* SnapKit-dummy.m in Sources */, + 46EB2E00007CD0 /* Typealiases.swift in Sources */, + 46EB2E00007CE0 /* UILayoutSupport+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007AA0 /* Sources */ = { + 46EB2E00007A50 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007EB0 /* Sources */ = { + 46EB2E00007E50 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00007F80 /* SwiftyJSON.swift in Sources */, - 46EB2E00008010 /* SwiftyJSON-dummy.m in Sources */, + 46EB2E00007F20 /* SwiftyJSON.swift in Sources */, + 46EB2E00007FB0 /* SwiftyJSON-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00007F20 /* Sources */ = { + 46EB2E00007EC0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008080 /* Sources */ = { + 46EB2E00008020 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E000080A0 /* NSBundle+TZImagePicker.m in Sources */, - 46EB2E000080B0 /* TZAssetCell.m in Sources */, - 46EB2E000080C0 /* TZAssetModel.m in Sources */, - 46EB2E000080D0 /* TZAuthLimitedFooterTipView.m in Sources */, - 46EB2E000080E0 /* TZGifPhotoPreviewController.m in Sources */, - 46EB2E000080F0 /* TZImageCropManager.m in Sources */, - 46EB2E00008100 /* TZImageManager.m in Sources */, - 46EB2E00008110 /* TZImagePickerController.m in Sources */, - 46EB2E00008360 /* TZImagePickerController-dummy.m in Sources */, - 46EB2E00008120 /* TZImageRequestOperation.m in Sources */, - 46EB2E000082C0 /* TZLocationManager.m in Sources */, - 46EB2E00008130 /* TZPhotoPickerController.m in Sources */, - 46EB2E00008140 /* TZPhotoPreviewCell.m in Sources */, - 46EB2E00008150 /* TZPhotoPreviewController.m in Sources */, - 46EB2E00008160 /* TZProgressView.m in Sources */, - 46EB2E00008170 /* TZVideoCropController.m in Sources */, - 46EB2E00008180 /* TZVideoEditedPreviewController.m in Sources */, - 46EB2E00008190 /* TZVideoPlayerController.m in Sources */, - 46EB2E000081A0 /* UIView+TZLayout.m in Sources */, + 46EB2E00008040 /* NSBundle+TZImagePicker.m in Sources */, + 46EB2E00008050 /* TZAssetCell.m in Sources */, + 46EB2E00008060 /* TZAssetModel.m in Sources */, + 46EB2E00008070 /* TZAuthLimitedFooterTipView.m in Sources */, + 46EB2E00008080 /* TZGifPhotoPreviewController.m in Sources */, + 46EB2E00008090 /* TZImageCropManager.m in Sources */, + 46EB2E000080A0 /* TZImageManager.m in Sources */, + 46EB2E000080B0 /* TZImagePickerController.m in Sources */, + 46EB2E00008300 /* TZImagePickerController-dummy.m in Sources */, + 46EB2E000080C0 /* TZImageRequestOperation.m in Sources */, + 46EB2E00008260 /* TZLocationManager.m in Sources */, + 46EB2E000080D0 /* TZPhotoPickerController.m in Sources */, + 46EB2E000080E0 /* TZPhotoPreviewCell.m in Sources */, + 46EB2E000080F0 /* TZPhotoPreviewController.m in Sources */, + 46EB2E00008100 /* TZProgressView.m in Sources */, + 46EB2E00008110 /* TZVideoCropController.m in Sources */, + 46EB2E00008120 /* TZVideoEditedPreviewController.m in Sources */, + 46EB2E00008130 /* TZVideoPlayerController.m in Sources */, + 46EB2E00008140 /* UIView+TZLayout.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E000083D0 /* Sources */ = { + 46EB2E00008370 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00008A10 /* alpha_dec.c in Sources */, - 46EB2E00008AB0 /* alpha_enc.c in Sources */, - 46EB2E00008610 /* alpha_processing.c in Sources */, - 46EB2E00008620 /* alpha_processing_mips_dsp_r2.c in Sources */, - 46EB2E00008630 /* alpha_processing_neon.c in Sources */, - 46EB2E00008640 /* alpha_processing_sse2.c in Sources */, - 46EB2E00008650 /* alpha_processing_sse41.c in Sources */, - 46EB2E00008AC0 /* analysis_enc.c in Sources */, - 46EB2E000083F0 /* anim_decode.c in Sources */, - 46EB2E00008420 /* anim_encode.c in Sources */, - 46EB2E00008AD0 /* backward_references_cost_enc.c in Sources */, - 46EB2E00008AE0 /* backward_references_enc.c in Sources */, - 46EB2E00008550 /* bit_reader_utils.c in Sources */, - 46EB2E00008560 /* bit_writer_utils.c in Sources */, - 46EB2E00008A20 /* buffer_dec.c in Sources */, - 46EB2E00008570 /* color_cache_utils.c in Sources */, - 46EB2E00008AF0 /* config_enc.c in Sources */, - 46EB2E00008660 /* cost.c in Sources */, - 46EB2E00008B00 /* cost_enc.c in Sources */, - 46EB2E00008670 /* cost_mips32.c in Sources */, - 46EB2E00008680 /* cost_mips_dsp_r2.c in Sources */, - 46EB2E00008690 /* cost_neon.c in Sources */, - 46EB2E000086A0 /* cost_sse2.c in Sources */, - 46EB2E000086B0 /* cpu.c in Sources */, - 46EB2E000086C0 /* dec.c in Sources */, - 46EB2E000086D0 /* dec_clip_tables.c in Sources */, - 46EB2E000086E0 /* dec_mips32.c in Sources */, - 46EB2E000086F0 /* dec_mips_dsp_r2.c in Sources */, - 46EB2E00008700 /* dec_msa.c in Sources */, - 46EB2E00008710 /* dec_neon.c in Sources */, - 46EB2E00008720 /* dec_sse2.c in Sources */, - 46EB2E00008730 /* dec_sse41.c in Sources */, - 46EB2E00008400 /* demux.c in Sources */, - 46EB2E00008740 /* enc.c in Sources */, - 46EB2E00008750 /* enc_mips32.c in Sources */, - 46EB2E00008760 /* enc_mips_dsp_r2.c in Sources */, - 46EB2E00008770 /* enc_msa.c in Sources */, - 46EB2E00008780 /* enc_neon.c in Sources */, - 46EB2E00008790 /* enc_sse2.c in Sources */, - 46EB2E000087A0 /* enc_sse41.c in Sources */, - 46EB2E00008B10 /* filter_enc.c in Sources */, - 46EB2E000087B0 /* filters.c in Sources */, - 46EB2E000087C0 /* filters_mips_dsp_r2.c in Sources */, - 46EB2E000087D0 /* filters_msa.c in Sources */, - 46EB2E000087E0 /* filters_neon.c in Sources */, - 46EB2E000087F0 /* filters_sse2.c in Sources */, - 46EB2E00008580 /* filters_utils.c in Sources */, - 46EB2E00008A30 /* frame_dec.c in Sources */, - 46EB2E00008B20 /* frame_enc.c in Sources */, - 46EB2E00008B30 /* histogram_enc.c in Sources */, - 46EB2E00008590 /* huffman_encode_utils.c in Sources */, - 46EB2E000085A0 /* huffman_utils.c in Sources */, - 46EB2E00008A40 /* idec_dec.c in Sources */, - 46EB2E00008A50 /* io_dec.c in Sources */, - 46EB2E00008B40 /* iterator_enc.c in Sources */, - 46EB2E00008F30 /* libwebp-dummy.m in Sources */, - 46EB2E00008800 /* lossless.c in Sources */, - 46EB2E00008810 /* lossless_enc.c in Sources */, - 46EB2E00008820 /* lossless_enc_mips32.c in Sources */, - 46EB2E00008830 /* lossless_enc_mips_dsp_r2.c in Sources */, - 46EB2E00008840 /* lossless_enc_msa.c in Sources */, - 46EB2E00008850 /* lossless_enc_neon.c in Sources */, - 46EB2E00008860 /* lossless_enc_sse2.c in Sources */, - 46EB2E00008870 /* lossless_enc_sse41.c in Sources */, - 46EB2E00008880 /* lossless_mips_dsp_r2.c in Sources */, - 46EB2E00008890 /* lossless_msa.c in Sources */, - 46EB2E000088A0 /* lossless_neon.c in Sources */, - 46EB2E000088B0 /* lossless_sse2.c in Sources */, - 46EB2E000088C0 /* lossless_sse41.c in Sources */, - 46EB2E00008430 /* muxedit.c in Sources */, - 46EB2E00008440 /* muxinternal.c in Sources */, - 46EB2E00008450 /* muxread.c in Sources */, - 46EB2E00008B50 /* near_lossless_enc.c in Sources */, - 46EB2E00008B60 /* picture_csp_enc.c in Sources */, - 46EB2E00008B70 /* picture_enc.c in Sources */, - 46EB2E00008B80 /* picture_psnr_enc.c in Sources */, - 46EB2E00008B90 /* picture_rescale_enc.c in Sources */, - 46EB2E00008BA0 /* picture_tools_enc.c in Sources */, - 46EB2E00008BB0 /* predictor_enc.c in Sources */, - 46EB2E00008A60 /* quant_dec.c in Sources */, - 46EB2E00008BC0 /* quant_enc.c in Sources */, - 46EB2E000085B0 /* quant_levels_dec_utils.c in Sources */, - 46EB2E000085C0 /* quant_levels_utils.c in Sources */, - 46EB2E000085D0 /* random_utils.c in Sources */, - 46EB2E000088D0 /* rescaler.c in Sources */, - 46EB2E000088E0 /* rescaler_mips32.c in Sources */, - 46EB2E000088F0 /* rescaler_mips_dsp_r2.c in Sources */, - 46EB2E00008900 /* rescaler_msa.c in Sources */, - 46EB2E00008910 /* rescaler_neon.c in Sources */, - 46EB2E00008920 /* rescaler_sse2.c in Sources */, - 46EB2E000085E0 /* rescaler_utils.c in Sources */, - 46EB2E00008490 /* sharpyuv.c in Sources */, - 46EB2E000084A0 /* sharpyuv_cpu.c in Sources */, - 46EB2E000084B0 /* sharpyuv_csp.c in Sources */, - 46EB2E000084C0 /* sharpyuv_dsp.c in Sources */, - 46EB2E000084D0 /* sharpyuv_gamma.c in Sources */, - 46EB2E000084E0 /* sharpyuv_neon.c in Sources */, - 46EB2E000084F0 /* sharpyuv_sse2.c in Sources */, - 46EB2E00008930 /* ssim.c in Sources */, - 46EB2E00008940 /* ssim_sse2.c in Sources */, - 46EB2E00008BD0 /* syntax_enc.c in Sources */, - 46EB2E000085F0 /* thread_utils.c in Sources */, - 46EB2E00008BE0 /* token_enc.c in Sources */, - 46EB2E00008A70 /* tree_dec.c in Sources */, - 46EB2E00008BF0 /* tree_enc.c in Sources */, - 46EB2E00008950 /* upsampling.c in Sources */, - 46EB2E00008960 /* upsampling_mips_dsp_r2.c in Sources */, - 46EB2E00008970 /* upsampling_msa.c in Sources */, - 46EB2E00008980 /* upsampling_neon.c in Sources */, - 46EB2E00008990 /* upsampling_sse2.c in Sources */, - 46EB2E000089A0 /* upsampling_sse41.c in Sources */, - 46EB2E00008600 /* utils.c in Sources */, - 46EB2E00008A90 /* vp8_dec.c in Sources */, - 46EB2E00008A80 /* vp8l_dec.c in Sources */, - 46EB2E00008C00 /* vp8l_enc.c in Sources */, - 46EB2E00008AA0 /* webp_dec.c in Sources */, - 46EB2E00008C10 /* webp_enc.c in Sources */, - 46EB2E000089B0 /* yuv.c in Sources */, - 46EB2E000089C0 /* yuv_mips32.c in Sources */, - 46EB2E000089D0 /* yuv_mips_dsp_r2.c in Sources */, - 46EB2E000089E0 /* yuv_neon.c in Sources */, - 46EB2E000089F0 /* yuv_sse2.c in Sources */, - 46EB2E00008A00 /* yuv_sse41.c in Sources */, + 46EB2E000089B0 /* alpha_dec.c in Sources */, + 46EB2E00008A50 /* alpha_enc.c in Sources */, + 46EB2E000085B0 /* alpha_processing.c in Sources */, + 46EB2E000085C0 /* alpha_processing_mips_dsp_r2.c in Sources */, + 46EB2E000085D0 /* alpha_processing_neon.c in Sources */, + 46EB2E000085E0 /* alpha_processing_sse2.c in Sources */, + 46EB2E000085F0 /* alpha_processing_sse41.c in Sources */, + 46EB2E00008A60 /* analysis_enc.c in Sources */, + 46EB2E00008390 /* anim_decode.c in Sources */, + 46EB2E000083C0 /* anim_encode.c in Sources */, + 46EB2E00008A70 /* backward_references_cost_enc.c in Sources */, + 46EB2E00008A80 /* backward_references_enc.c in Sources */, + 46EB2E000084F0 /* bit_reader_utils.c in Sources */, + 46EB2E00008500 /* bit_writer_utils.c in Sources */, + 46EB2E000089C0 /* buffer_dec.c in Sources */, + 46EB2E00008510 /* color_cache_utils.c in Sources */, + 46EB2E00008A90 /* config_enc.c in Sources */, + 46EB2E00008600 /* cost.c in Sources */, + 46EB2E00008AA0 /* cost_enc.c in Sources */, + 46EB2E00008610 /* cost_mips32.c in Sources */, + 46EB2E00008620 /* cost_mips_dsp_r2.c in Sources */, + 46EB2E00008630 /* cost_neon.c in Sources */, + 46EB2E00008640 /* cost_sse2.c in Sources */, + 46EB2E00008650 /* cpu.c in Sources */, + 46EB2E00008660 /* dec.c in Sources */, + 46EB2E00008670 /* dec_clip_tables.c in Sources */, + 46EB2E00008680 /* dec_mips32.c in Sources */, + 46EB2E00008690 /* dec_mips_dsp_r2.c in Sources */, + 46EB2E000086A0 /* dec_msa.c in Sources */, + 46EB2E000086B0 /* dec_neon.c in Sources */, + 46EB2E000086C0 /* dec_sse2.c in Sources */, + 46EB2E000086D0 /* dec_sse41.c in Sources */, + 46EB2E000083A0 /* demux.c in Sources */, + 46EB2E000086E0 /* enc.c in Sources */, + 46EB2E000086F0 /* enc_mips32.c in Sources */, + 46EB2E00008700 /* enc_mips_dsp_r2.c in Sources */, + 46EB2E00008710 /* enc_msa.c in Sources */, + 46EB2E00008720 /* enc_neon.c in Sources */, + 46EB2E00008730 /* enc_sse2.c in Sources */, + 46EB2E00008740 /* enc_sse41.c in Sources */, + 46EB2E00008AB0 /* filter_enc.c in Sources */, + 46EB2E00008750 /* filters.c in Sources */, + 46EB2E00008760 /* filters_mips_dsp_r2.c in Sources */, + 46EB2E00008770 /* filters_msa.c in Sources */, + 46EB2E00008780 /* filters_neon.c in Sources */, + 46EB2E00008790 /* filters_sse2.c in Sources */, + 46EB2E00008520 /* filters_utils.c in Sources */, + 46EB2E000089D0 /* frame_dec.c in Sources */, + 46EB2E00008AC0 /* frame_enc.c in Sources */, + 46EB2E00008AD0 /* histogram_enc.c in Sources */, + 46EB2E00008530 /* huffman_encode_utils.c in Sources */, + 46EB2E00008540 /* huffman_utils.c in Sources */, + 46EB2E000089E0 /* idec_dec.c in Sources */, + 46EB2E000089F0 /* io_dec.c in Sources */, + 46EB2E00008AE0 /* iterator_enc.c in Sources */, + 46EB2E00008ED0 /* libwebp-dummy.m in Sources */, + 46EB2E000087A0 /* lossless.c in Sources */, + 46EB2E000087B0 /* lossless_enc.c in Sources */, + 46EB2E000087C0 /* lossless_enc_mips32.c in Sources */, + 46EB2E000087D0 /* lossless_enc_mips_dsp_r2.c in Sources */, + 46EB2E000087E0 /* lossless_enc_msa.c in Sources */, + 46EB2E000087F0 /* lossless_enc_neon.c in Sources */, + 46EB2E00008800 /* lossless_enc_sse2.c in Sources */, + 46EB2E00008810 /* lossless_enc_sse41.c in Sources */, + 46EB2E00008820 /* lossless_mips_dsp_r2.c in Sources */, + 46EB2E00008830 /* lossless_msa.c in Sources */, + 46EB2E00008840 /* lossless_neon.c in Sources */, + 46EB2E00008850 /* lossless_sse2.c in Sources */, + 46EB2E00008860 /* lossless_sse41.c in Sources */, + 46EB2E000083D0 /* muxedit.c in Sources */, + 46EB2E000083E0 /* muxinternal.c in Sources */, + 46EB2E000083F0 /* muxread.c in Sources */, + 46EB2E00008AF0 /* near_lossless_enc.c in Sources */, + 46EB2E00008B00 /* picture_csp_enc.c in Sources */, + 46EB2E00008B10 /* picture_enc.c in Sources */, + 46EB2E00008B20 /* picture_psnr_enc.c in Sources */, + 46EB2E00008B30 /* picture_rescale_enc.c in Sources */, + 46EB2E00008B40 /* picture_tools_enc.c in Sources */, + 46EB2E00008B50 /* predictor_enc.c in Sources */, + 46EB2E00008A00 /* quant_dec.c in Sources */, + 46EB2E00008B60 /* quant_enc.c in Sources */, + 46EB2E00008550 /* quant_levels_dec_utils.c in Sources */, + 46EB2E00008560 /* quant_levels_utils.c in Sources */, + 46EB2E00008570 /* random_utils.c in Sources */, + 46EB2E00008870 /* rescaler.c in Sources */, + 46EB2E00008880 /* rescaler_mips32.c in Sources */, + 46EB2E00008890 /* rescaler_mips_dsp_r2.c in Sources */, + 46EB2E000088A0 /* rescaler_msa.c in Sources */, + 46EB2E000088B0 /* rescaler_neon.c in Sources */, + 46EB2E000088C0 /* rescaler_sse2.c in Sources */, + 46EB2E00008580 /* rescaler_utils.c in Sources */, + 46EB2E00008430 /* sharpyuv.c in Sources */, + 46EB2E00008440 /* sharpyuv_cpu.c in Sources */, + 46EB2E00008450 /* sharpyuv_csp.c in Sources */, + 46EB2E00008460 /* sharpyuv_dsp.c in Sources */, + 46EB2E00008470 /* sharpyuv_gamma.c in Sources */, + 46EB2E00008480 /* sharpyuv_neon.c in Sources */, + 46EB2E00008490 /* sharpyuv_sse2.c in Sources */, + 46EB2E000088D0 /* ssim.c in Sources */, + 46EB2E000088E0 /* ssim_sse2.c in Sources */, + 46EB2E00008B70 /* syntax_enc.c in Sources */, + 46EB2E00008590 /* thread_utils.c in Sources */, + 46EB2E00008B80 /* token_enc.c in Sources */, + 46EB2E00008A10 /* tree_dec.c in Sources */, + 46EB2E00008B90 /* tree_enc.c in Sources */, + 46EB2E000088F0 /* upsampling.c in Sources */, + 46EB2E00008900 /* upsampling_mips_dsp_r2.c in Sources */, + 46EB2E00008910 /* upsampling_msa.c in Sources */, + 46EB2E00008920 /* upsampling_neon.c in Sources */, + 46EB2E00008930 /* upsampling_sse2.c in Sources */, + 46EB2E00008940 /* upsampling_sse41.c in Sources */, + 46EB2E000085A0 /* utils.c in Sources */, + 46EB2E00008A30 /* vp8_dec.c in Sources */, + 46EB2E00008A20 /* vp8l_dec.c in Sources */, + 46EB2E00008BA0 /* vp8l_enc.c in Sources */, + 46EB2E00008A40 /* webp_dec.c in Sources */, + 46EB2E00008BB0 /* webp_enc.c in Sources */, + 46EB2E00008950 /* yuv.c in Sources */, + 46EB2E00008960 /* yuv_mips32.c in Sources */, + 46EB2E00008970 /* yuv_mips_dsp_r2.c in Sources */, + 46EB2E00008980 /* yuv_neon.c in Sources */, + 46EB2E00008990 /* yuv_sse2.c in Sources */, + 46EB2E000089A0 /* yuv_sse41.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00008FA0 /* Sources */ = { + 46EB2E00008F40 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E00009FB0 /* AnimatedButton.swift in Sources */, - 46EB2E00009FC0 /* AnimatedControl.swift in Sources */, - 46EB2E000093A0 /* AnimatedProviding.swift in Sources */, - 46EB2E00009FD0 /* AnimatedSwitch.swift in Sources */, - 46EB2E00009F30 /* AnimationCacheProvider.swift in Sources */, - 46EB2E00009DB0 /* AnimationContext.swift in Sources */, - 46EB2E0000A0D0 /* AnimationFontProvider.swift in Sources */, - 46EB2E0000A0E0 /* AnimationImageProvider.swift in Sources */, - 46EB2E0000A060 /* AnimationKeypath.swift in Sources */, - 46EB2E00009D40 /* AnimationKeypathExtension.swift in Sources */, - 46EB2E000091C0 /* AnimationLayer.swift in Sources */, - 46EB2E0000A0F0 /* AnimationSubview.swift in Sources */, - 46EB2E0000A1C0 /* AnimationTextProvider.swift in Sources */, - 46EB2E0000A190 /* AnimationTime.swift in Sources */, - 46EB2E000099A0 /* AnimatorNode.swift in Sources */, - 46EB2E00009D10 /* AnimatorNodeDebugging.swift in Sources */, - 46EB2E00009380 /* AnyEpoxyModelProperty.swift in Sources */, - 46EB2E00009DC0 /* AnyEquatable.swift in Sources */, - 46EB2E000097E0 /* AnyNodeProperty.swift in Sources */, - 46EB2E000097F0 /* AnyValueContainer.swift in Sources */, - 46EB2E0000A070 /* AnyValueProvider.swift in Sources */, - 46EB2E00009620 /* Archive.swift in Sources */, - 46EB2E00009590 /* Archive+BackingConfiguration.swift in Sources */, - 46EB2E000095A0 /* Archive+Helpers.swift in Sources */, - 46EB2E000095B0 /* Archive+MemoryFile.swift in Sources */, - 46EB2E000095C0 /* Archive+Progress.swift in Sources */, - 46EB2E000095D0 /* Archive+Reading.swift in Sources */, - 46EB2E000095E0 /* Archive+ReadingDeprecated.swift in Sources */, - 46EB2E000095F0 /* Archive+Writing.swift in Sources */, - 46EB2E00009600 /* Archive+WritingDeprecated.swift in Sources */, - 46EB2E00009610 /* Archive+ZIP64.swift in Sources */, - 46EB2E000099F0 /* Asset.swift in Sources */, - 46EB2E00009A00 /* AssetLibrary.swift in Sources */, - 46EB2E000091D0 /* BaseAnimationLayer.swift in Sources */, - 46EB2E000091E0 /* BaseCompositionLayer.swift in Sources */, - 46EB2E00009530 /* BehaviorsConfigurableView.swift in Sources */, - 46EB2E00009E30 /* BezierPath.swift in Sources */, - 46EB2E00009E40 /* BezierPathRoundExtension.swift in Sources */, - 46EB2E00009DD0 /* Binding+Map.swift in Sources */, - 46EB2E00009D50 /* BlendMode+Filter.swift in Sources */, - 46EB2E00009A80 /* Bundle.swift in Sources */, - 46EB2E0000A100 /* BundleImageProvider.swift in Sources */, - 46EB2E00009070 /* CAAnimation+TimingConfiguration.swift in Sources */, - 46EB2E00009740 /* CachedImageProvider.swift in Sources */, - 46EB2E00009080 /* CALayer+addAnimation.swift in Sources */, - 46EB2E00009180 /* CALayer+fillBounds.swift in Sources */, - 46EB2E000091F0 /* CALayer+setupLayerHierarchy.swift in Sources */, - 46EB2E00009330 /* CallbackContextEpoxyModeled.swift in Sources */, - 46EB2E00009D60 /* CGColor+RGB.swift in Sources */, - 46EB2E00009D70 /* CGFloatExtensions.swift in Sources */, - 46EB2E00009E50 /* CGPointExtension.swift in Sources */, - 46EB2E00009390 /* ClassReference.swift in Sources */, - 46EB2E000092D0 /* Collection+Diff.swift in Sources */, - 46EB2E00009AD0 /* ColorEffectValue.swift in Sources */, - 46EB2E00009E60 /* ColorExtension.swift in Sources */, - 46EB2E0000A080 /* ColorValueProvider.swift in Sources */, - 46EB2E00009090 /* CombinedShapeAnimation.swift in Sources */, - 46EB2E00009160 /* CompatibilityTracker.swift in Sources */, - 46EB2E0000A110 /* CompatibleAnimationKeypath.swift in Sources */, - 46EB2E0000A120 /* CompatibleAnimationView.swift in Sources */, - 46EB2E000096B0 /* CompositionLayer.swift in Sources */, - 46EB2E00009750 /* CompositionLayersInitializer.swift in Sources */, - 46EB2E00009E70 /* CompoundBezierPath.swift in Sources */, - 46EB2E00009540 /* ContentConfigurableView.swift in Sources */, - 46EB2E00009170 /* CoreAnimationLayer.swift in Sources */, - 46EB2E00009760 /* CoreTextRenderLayer.swift in Sources */, - 46EB2E00009E80 /* CurveVertex.swift in Sources */, - 46EB2E000090A0 /* CustomPathAnimation.swift in Sources */, - 46EB2E00009B90 /* DashPattern.swift in Sources */, - 46EB2E00009630 /* Data+Compression.swift in Sources */, - 46EB2E00009640 /* Data+CompressionDeprecated.swift in Sources */, - 46EB2E00009650 /* Data+Serialization.swift in Sources */, - 46EB2E00009D80 /* DataExtension.swift in Sources */, - 46EB2E000093B0 /* DataIDProviding.swift in Sources */, - 46EB2E00009F70 /* DecodingStrategy.swift in Sources */, - 46EB2E00009F40 /* DefaultAnimationCache.swift in Sources */, - 46EB2E00009A30 /* DictionaryInitializable.swift in Sources */, - 46EB2E000093C0 /* DidDisplayProviding.swift in Sources */, - 46EB2E000093D0 /* DidEndDisplayingProviding.swift in Sources */, - 46EB2E000093E0 /* DidSelectProviding.swift in Sources */, - 46EB2E000092E0 /* Diffable.swift in Sources */, - 46EB2E000092F0 /* DiffableSection.swift in Sources */, - 46EB2E00009A40 /* DotLottieAnimation.swift in Sources */, - 46EB2E0000A010 /* DotLottieCache.swift in Sources */, - 46EB2E0000A020 /* DotLottieCacheProvider.swift in Sources */, - 46EB2E0000A030 /* DotLottieConfiguration.swift in Sources */, - 46EB2E0000A040 /* DotLottieFile.swift in Sources */, - 46EB2E0000A050 /* DotLottieFileHelpers.swift in Sources */, - 46EB2E00009A50 /* DotLottieImageProvider.swift in Sources */, - 46EB2E00009A60 /* DotLottieManifest.swift in Sources */, - 46EB2E00009A70 /* DotLottieUtils.swift in Sources */, - 46EB2E000090B0 /* DropShadowAnimation.swift in Sources */, - 46EB2E00009AC0 /* DropShadowEffect.swift in Sources */, - 46EB2E00009B70 /* DropShadowStyle.swift in Sources */, - 46EB2E00009AE0 /* EffectValue.swift in Sources */, - 46EB2E00009BD0 /* Ellipse.swift in Sources */, - 46EB2E000090C0 /* EllipseAnimation.swift in Sources */, - 46EB2E000098F0 /* EllipseNode.swift in Sources */, - 46EB2E00009680 /* Entry.swift in Sources */, - 46EB2E00009660 /* Entry+Serialization.swift in Sources */, - 46EB2E00009670 /* Entry+ZIP64.swift in Sources */, - 46EB2E00009550 /* EpoxyableView.swift in Sources */, - 46EB2E00009490 /* EpoxyableView+SwiftUIView.swift in Sources */, - 46EB2E00009320 /* EpoxyLogger.swift in Sources */, - 46EB2E00009340 /* EpoxyModelArrayBuilder.swift in Sources */, - 46EB2E00009350 /* EpoxyModeled.swift in Sources */, - 46EB2E00009360 /* EpoxyModelProperty.swift in Sources */, - 46EB2E00009370 /* EpoxyModelStorage.swift in Sources */, - 46EB2E000094A0 /* EpoxySwiftUIHostingController.swift in Sources */, - 46EB2E000094B0 /* EpoxySwiftUIHostingView.swift in Sources */, - 46EB2E000094C0 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift in Sources */, - 46EB2E000094D0 /* EpoxySwiftUILayoutMargins.swift in Sources */, - 46EB2E000093F0 /* ErasedContentProviding.swift in Sources */, - 46EB2E00009690 /* FileManager+ZIP.swift in Sources */, - 46EB2E0000A130 /* FilepathImageProvider.swift in Sources */, - 46EB2E00009BE0 /* Fill.swift in Sources */, - 46EB2E00009950 /* FillNode.swift in Sources */, - 46EB2E000098A0 /* FillRenderer.swift in Sources */, - 46EB2E0000A090 /* FloatValueProvider.swift in Sources */, - 46EB2E00009CC0 /* Font.swift in Sources */, - 46EB2E00009CD0 /* Glyph.swift in Sources */, - 46EB2E000090D0 /* GradientAnimations.swift in Sources */, - 46EB2E00009BF0 /* GradientFill.swift in Sources */, - 46EB2E00009960 /* GradientFillNode.swift in Sources */, - 46EB2E000098B0 /* GradientFillRenderer.swift in Sources */, - 46EB2E00009200 /* GradientRenderLayer.swift in Sources */, - 46EB2E00009C00 /* GradientStroke.swift in Sources */, - 46EB2E00009970 /* GradientStrokeNode.swift in Sources */, - 46EB2E000098C0 /* GradientStrokeRenderer.swift in Sources */, - 46EB2E0000A0A0 /* GradientValueProvider.swift in Sources */, - 46EB2E00009C10 /* Group.swift in Sources */, - 46EB2E00009830 /* GroupInterpolator.swift in Sources */, - 46EB2E00009940 /* GroupNode.swift in Sources */, - 46EB2E00009870 /* GroupOutputNode.swift in Sources */, - 46EB2E00009A10 /* ImageAsset.swift in Sources */, - 46EB2E000096C0 /* ImageCompositionLayer.swift in Sources */, - 46EB2E00009210 /* ImageLayer.swift in Sources */, - 46EB2E00009B10 /* ImageLayerModel.swift in Sources */, - 46EB2E00009300 /* IndexChangeset.swift in Sources */, - 46EB2E00009220 /* InfiniteOpaqueAnimationLayer.swift in Sources */, - 46EB2E0000A160 /* Interpolatable.swift in Sources */, - 46EB2E00009DF0 /* InterpolatableExtensions.swift in Sources */, - 46EB2E00009770 /* InvertedMatteLayer.swift in Sources */, - 46EB2E000097C0 /* ItemsExtension.swift in Sources */, - 46EB2E00009A90 /* KeyedDecodingContainerExtensions.swift in Sources */, - 46EB2E0000A170 /* Keyframe.swift in Sources */, - 46EB2E00009AA0 /* KeyframeData.swift in Sources */, - 46EB2E00009E00 /* KeyframeExtensions.swift in Sources */, - 46EB2E00009AB0 /* KeyframeGroup.swift in Sources */, - 46EB2E00009190 /* KeyframeGroup+exactlyOneKeyframe.swift in Sources */, - 46EB2E00009E10 /* KeyframeInterpolator.swift in Sources */, - 46EB2E000091A0 /* Keyframes+combined.swift in Sources */, - 46EB2E000091B0 /* Keyframes+timeRemapping.swift in Sources */, - 46EB2E00009800 /* KeypathSearchable.swift in Sources */, - 46EB2E00009D20 /* LayerDebugging.swift in Sources */, - 46EB2E00009B00 /* LayerEffect.swift in Sources */, - 46EB2E00009780 /* LayerFontProvider.swift in Sources */, - 46EB2E00009790 /* LayerImageProvider.swift in Sources */, - 46EB2E00009B20 /* LayerModel.swift in Sources */, - 46EB2E00009230 /* LayerModel+makeAnimationLayer.swift in Sources */, - 46EB2E000090E0 /* LayerProperty.swift in Sources */, - 46EB2E00009B80 /* LayerStyle.swift in Sources */, - 46EB2E000097A0 /* LayerTextProvider.swift in Sources */, - 46EB2E000097B0 /* LayerTransformNode.swift in Sources */, - 46EB2E000098D0 /* LegacyGradientFillRenderer.swift in Sources */, - 46EB2E0000A250 /* lottie-ios-dummy.m in Sources */, - 46EB2E00009EC0 /* LottieAnimation.swift in Sources */, - 46EB2E00009F50 /* LottieAnimationCache.swift in Sources */, - 46EB2E00009ED0 /* LottieAnimationHelpers.swift in Sources */, - 46EB2E00009EE0 /* LottieAnimationLayer.swift in Sources */, - 46EB2E00009E20 /* LottieAnimationSource.swift in Sources */, - 46EB2E00009EF0 /* LottieAnimationView.swift in Sources */, - 46EB2E0000A140 /* LottieAnimationViewBase.swift in Sources */, - 46EB2E00009F00 /* LottieAnimationViewInitializers.swift in Sources */, - 46EB2E00009FE0 /* LottieButton.swift in Sources */, - 46EB2E0000A1A0 /* LottieColor.swift in Sources */, - 46EB2E00009F80 /* LottieConfiguration.swift in Sources */, - 46EB2E0000A180 /* LottieLogger.swift in Sources */, - 46EB2E00009F10 /* LottiePlaybackMode.swift in Sources */, - 46EB2E00009FF0 /* LottieSwitch.swift in Sources */, - 46EB2E00009F20 /* LottieView.swift in Sources */, - 46EB2E0000A000 /* LottieViewType.swift in Sources */, - 46EB2E00009F60 /* LRUAnimationCache.swift in Sources */, - 46EB2E00009580 /* LRUCache.swift in Sources */, - 46EB2E00009730 /* MainThreadAnimationLayer.swift in Sources */, - 46EB2E00009400 /* MakeViewProviding.swift in Sources */, - 46EB2E00009BA0 /* Marker.swift in Sources */, - 46EB2E00009BB0 /* Mask.swift in Sources */, - 46EB2E00009240 /* MaskCompositionLayer.swift in Sources */, - 46EB2E000096D0 /* MaskContainerLayer.swift in Sources */, - 46EB2E00009D90 /* MathKit.swift in Sources */, - 46EB2E000094E0 /* MeasuringViewRepresentable.swift in Sources */, - 46EB2E00009C20 /* Merge.swift in Sources */, - 46EB2E000097D0 /* NodeProperty.swift in Sources */, - 46EB2E00009810 /* NodePropertyMap.swift in Sources */, - 46EB2E000096E0 /* NullCompositionLayer.swift in Sources */, - 46EB2E000090F0 /* OpacityAnimation.swift in Sources */, - 46EB2E00009880 /* PassThroughOutputNode.swift in Sources */, - 46EB2E00009E90 /* PathElement.swift in Sources */, - 46EB2E000099B0 /* PathNode.swift in Sources */, - 46EB2E00009890 /* PathOutputNode.swift in Sources */, - 46EB2E0000A0B0 /* PointValueProvider.swift in Sources */, - 46EB2E00009900 /* PolygonNode.swift in Sources */, - 46EB2E00009A20 /* PrecompAsset.swift in Sources */, - 46EB2E00009250 /* PreCompLayer.swift in Sources */, - 46EB2E00009B30 /* PreCompLayerModel.swift in Sources */, - 46EB2E000096F0 /* PreCompositionLayer.swift in Sources */, - 46EB2E00009C30 /* Rectangle.swift in Sources */, - 46EB2E00009100 /* RectangleAnimation.swift in Sources */, - 46EB2E00009910 /* RectNode.swift in Sources */, - 46EB2E00009F90 /* ReducedMotionOption.swift in Sources */, - 46EB2E00009FA0 /* RenderingEngineOption.swift in Sources */, - 46EB2E000099C0 /* RenderNode.swift in Sources */, - 46EB2E00009C40 /* Repeater.swift in Sources */, - 46EB2E00009260 /* RepeaterLayer.swift in Sources */, - 46EB2E00009D00 /* RootAnimationLayer.swift in Sources */, - 46EB2E00009C50 /* RoundedCorners.swift in Sources */, - 46EB2E00009850 /* RoundedCornersNode.swift in Sources */, - 46EB2E00009310 /* SectionedChangeset.swift in Sources */, - 46EB2E00009410 /* SetBehaviorsProviding.swift in Sources */, - 46EB2E00009420 /* SetContentProviding.swift in Sources */, - 46EB2E00009C60 /* Shape.swift in Sources */, - 46EB2E00009110 /* ShapeAnimation.swift in Sources */, - 46EB2E00009700 /* ShapeCompositionLayer.swift in Sources */, - 46EB2E000099D0 /* ShapeContainerLayer.swift in Sources */, - 46EB2E00009C70 /* ShapeItem.swift in Sources */, - 46EB2E00009270 /* ShapeItemLayer.swift in Sources */, - 46EB2E00009280 /* ShapeLayer.swift in Sources */, - 46EB2E00009B40 /* ShapeLayerModel.swift in Sources */, - 46EB2E00009920 /* ShapeNode.swift in Sources */, - 46EB2E000099E0 /* ShapeRenderLayer.swift in Sources */, - 46EB2E00009C80 /* ShapeTransform.swift in Sources */, - 46EB2E00009840 /* SingleValueProvider.swift in Sources */, - 46EB2E0000A0C0 /* SizeValueProvider.swift in Sources */, - 46EB2E00009710 /* SolidCompositionLayer.swift in Sources */, - 46EB2E00009290 /* SolidLayer.swift in Sources */, - 46EB2E00009B50 /* SolidLayerModel.swift in Sources */, - 46EB2E00009C90 /* Star.swift in Sources */, - 46EB2E00009120 /* StarAnimation.swift in Sources */, - 46EB2E00009930 /* StarNode.swift in Sources */, - 46EB2E00009DA0 /* StringExtensions.swift in Sources */, - 46EB2E00009CA0 /* Stroke.swift in Sources */, - 46EB2E00009130 /* StrokeAnimation.swift in Sources */, - 46EB2E00009980 /* StrokeNode.swift in Sources */, - 46EB2E000098E0 /* StrokeRenderer.swift in Sources */, - 46EB2E00009560 /* StyledView.swift in Sources */, - 46EB2E00009430 /* StyleIDProviding.swift in Sources */, - 46EB2E000094F0 /* SwiftUIMeasurementContainer.swift in Sources */, - 46EB2E00009500 /* SwiftUIView.swift in Sources */, - 46EB2E00009D30 /* TestHelpers.swift in Sources */, - 46EB2E00009CE0 /* TextAnimator.swift in Sources */, - 46EB2E00009990 /* TextAnimatorNode.swift in Sources */, - 46EB2E00009720 /* TextCompositionLayer.swift in Sources */, - 46EB2E00009CF0 /* TextDocument.swift in Sources */, - 46EB2E000092A0 /* TextLayer.swift in Sources */, - 46EB2E00009B60 /* TextLayerModel.swift in Sources */, - 46EB2E00009440 /* TraitCollectionProviding.swift in Sources */, - 46EB2E00009BC0 /* Transform.swift in Sources */, - 46EB2E00009140 /* TransformAnimations.swift in Sources */, - 46EB2E000092B0 /* TransformLayer.swift in Sources */, - 46EB2E00009CB0 /* Trim.swift in Sources */, - 46EB2E00009860 /* TrimPathNode.swift in Sources */, - 46EB2E0000A150 /* UIColorExtension.swift in Sources */, - 46EB2E00009510 /* UIView+SwiftUIView.swift in Sources */, - 46EB2E00009520 /* UIViewConfiguringSwiftUIView.swift in Sources */, - 46EB2E00009EA0 /* UnitBezier.swift in Sources */, - 46EB2E000096A0 /* URL+ZIP.swift in Sources */, - 46EB2E00009820 /* ValueContainer.swift in Sources */, - 46EB2E000092C0 /* ValueProviderStore.swift in Sources */, - 46EB2E00009AF0 /* Vector1DEffectValue.swift in Sources */, - 46EB2E0000A1B0 /* Vectors.swift in Sources */, - 46EB2E00009EB0 /* VectorsExtensions.swift in Sources */, - 46EB2E00009DE0 /* View+ValueChanged.swift in Sources */, - 46EB2E00009450 /* ViewDifferentiatorProviding.swift in Sources */, - 46EB2E00009480 /* ViewEpoxyModeled.swift in Sources */, - 46EB2E00009460 /* ViewProviding.swift in Sources */, - 46EB2E00009570 /* ViewType.swift in Sources */, - 46EB2E00009150 /* VisibilityAnimation.swift in Sources */, - 46EB2E00009470 /* WillDisplayProviding.swift in Sources */, + 46EB2E00009F50 /* AnimatedButton.swift in Sources */, + 46EB2E00009F60 /* AnimatedControl.swift in Sources */, + 46EB2E00009340 /* AnimatedProviding.swift in Sources */, + 46EB2E00009F70 /* AnimatedSwitch.swift in Sources */, + 46EB2E00009ED0 /* AnimationCacheProvider.swift in Sources */, + 46EB2E00009D50 /* AnimationContext.swift in Sources */, + 46EB2E0000A070 /* AnimationFontProvider.swift in Sources */, + 46EB2E0000A080 /* AnimationImageProvider.swift in Sources */, + 46EB2E0000A000 /* AnimationKeypath.swift in Sources */, + 46EB2E00009CE0 /* AnimationKeypathExtension.swift in Sources */, + 46EB2E00009160 /* AnimationLayer.swift in Sources */, + 46EB2E0000A090 /* AnimationSubview.swift in Sources */, + 46EB2E0000A160 /* AnimationTextProvider.swift in Sources */, + 46EB2E0000A130 /* AnimationTime.swift in Sources */, + 46EB2E00009940 /* AnimatorNode.swift in Sources */, + 46EB2E00009CB0 /* AnimatorNodeDebugging.swift in Sources */, + 46EB2E00009320 /* AnyEpoxyModelProperty.swift in Sources */, + 46EB2E00009D60 /* AnyEquatable.swift in Sources */, + 46EB2E00009780 /* AnyNodeProperty.swift in Sources */, + 46EB2E00009790 /* AnyValueContainer.swift in Sources */, + 46EB2E0000A010 /* AnyValueProvider.swift in Sources */, + 46EB2E000095C0 /* Archive.swift in Sources */, + 46EB2E00009530 /* Archive+BackingConfiguration.swift in Sources */, + 46EB2E00009540 /* Archive+Helpers.swift in Sources */, + 46EB2E00009550 /* Archive+MemoryFile.swift in Sources */, + 46EB2E00009560 /* Archive+Progress.swift in Sources */, + 46EB2E00009570 /* Archive+Reading.swift in Sources */, + 46EB2E00009580 /* Archive+ReadingDeprecated.swift in Sources */, + 46EB2E00009590 /* Archive+Writing.swift in Sources */, + 46EB2E000095A0 /* Archive+WritingDeprecated.swift in Sources */, + 46EB2E000095B0 /* Archive+ZIP64.swift in Sources */, + 46EB2E00009990 /* Asset.swift in Sources */, + 46EB2E000099A0 /* AssetLibrary.swift in Sources */, + 46EB2E00009170 /* BaseAnimationLayer.swift in Sources */, + 46EB2E00009180 /* BaseCompositionLayer.swift in Sources */, + 46EB2E000094D0 /* BehaviorsConfigurableView.swift in Sources */, + 46EB2E00009DD0 /* BezierPath.swift in Sources */, + 46EB2E00009DE0 /* BezierPathRoundExtension.swift in Sources */, + 46EB2E00009D70 /* Binding+Map.swift in Sources */, + 46EB2E00009CF0 /* BlendMode+Filter.swift in Sources */, + 46EB2E00009A20 /* Bundle.swift in Sources */, + 46EB2E0000A0A0 /* BundleImageProvider.swift in Sources */, + 46EB2E00009010 /* CAAnimation+TimingConfiguration.swift in Sources */, + 46EB2E000096E0 /* CachedImageProvider.swift in Sources */, + 46EB2E00009020 /* CALayer+addAnimation.swift in Sources */, + 46EB2E00009120 /* CALayer+fillBounds.swift in Sources */, + 46EB2E00009190 /* CALayer+setupLayerHierarchy.swift in Sources */, + 46EB2E000092D0 /* CallbackContextEpoxyModeled.swift in Sources */, + 46EB2E00009D00 /* CGColor+RGB.swift in Sources */, + 46EB2E00009D10 /* CGFloatExtensions.swift in Sources */, + 46EB2E00009DF0 /* CGPointExtension.swift in Sources */, + 46EB2E00009330 /* ClassReference.swift in Sources */, + 46EB2E00009270 /* Collection+Diff.swift in Sources */, + 46EB2E00009A70 /* ColorEffectValue.swift in Sources */, + 46EB2E00009E00 /* ColorExtension.swift in Sources */, + 46EB2E0000A020 /* ColorValueProvider.swift in Sources */, + 46EB2E00009030 /* CombinedShapeAnimation.swift in Sources */, + 46EB2E00009100 /* CompatibilityTracker.swift in Sources */, + 46EB2E0000A0B0 /* CompatibleAnimationKeypath.swift in Sources */, + 46EB2E0000A0C0 /* CompatibleAnimationView.swift in Sources */, + 46EB2E00009650 /* CompositionLayer.swift in Sources */, + 46EB2E000096F0 /* CompositionLayersInitializer.swift in Sources */, + 46EB2E00009E10 /* CompoundBezierPath.swift in Sources */, + 46EB2E000094E0 /* ContentConfigurableView.swift in Sources */, + 46EB2E00009110 /* CoreAnimationLayer.swift in Sources */, + 46EB2E00009700 /* CoreTextRenderLayer.swift in Sources */, + 46EB2E00009E20 /* CurveVertex.swift in Sources */, + 46EB2E00009040 /* CustomPathAnimation.swift in Sources */, + 46EB2E00009B30 /* DashPattern.swift in Sources */, + 46EB2E000095D0 /* Data+Compression.swift in Sources */, + 46EB2E000095E0 /* Data+CompressionDeprecated.swift in Sources */, + 46EB2E000095F0 /* Data+Serialization.swift in Sources */, + 46EB2E00009D20 /* DataExtension.swift in Sources */, + 46EB2E00009350 /* DataIDProviding.swift in Sources */, + 46EB2E00009F10 /* DecodingStrategy.swift in Sources */, + 46EB2E00009EE0 /* DefaultAnimationCache.swift in Sources */, + 46EB2E000099D0 /* DictionaryInitializable.swift in Sources */, + 46EB2E00009360 /* DidDisplayProviding.swift in Sources */, + 46EB2E00009370 /* DidEndDisplayingProviding.swift in Sources */, + 46EB2E00009380 /* DidSelectProviding.swift in Sources */, + 46EB2E00009280 /* Diffable.swift in Sources */, + 46EB2E00009290 /* DiffableSection.swift in Sources */, + 46EB2E000099E0 /* DotLottieAnimation.swift in Sources */, + 46EB2E00009FB0 /* DotLottieCache.swift in Sources */, + 46EB2E00009FC0 /* DotLottieCacheProvider.swift in Sources */, + 46EB2E00009FD0 /* DotLottieConfiguration.swift in Sources */, + 46EB2E00009FE0 /* DotLottieFile.swift in Sources */, + 46EB2E00009FF0 /* DotLottieFileHelpers.swift in Sources */, + 46EB2E000099F0 /* DotLottieImageProvider.swift in Sources */, + 46EB2E00009A00 /* DotLottieManifest.swift in Sources */, + 46EB2E00009A10 /* DotLottieUtils.swift in Sources */, + 46EB2E00009050 /* DropShadowAnimation.swift in Sources */, + 46EB2E00009A60 /* DropShadowEffect.swift in Sources */, + 46EB2E00009B10 /* DropShadowStyle.swift in Sources */, + 46EB2E00009A80 /* EffectValue.swift in Sources */, + 46EB2E00009B70 /* Ellipse.swift in Sources */, + 46EB2E00009060 /* EllipseAnimation.swift in Sources */, + 46EB2E00009890 /* EllipseNode.swift in Sources */, + 46EB2E00009620 /* Entry.swift in Sources */, + 46EB2E00009600 /* Entry+Serialization.swift in Sources */, + 46EB2E00009610 /* Entry+ZIP64.swift in Sources */, + 46EB2E000094F0 /* EpoxyableView.swift in Sources */, + 46EB2E00009430 /* EpoxyableView+SwiftUIView.swift in Sources */, + 46EB2E000092C0 /* EpoxyLogger.swift in Sources */, + 46EB2E000092E0 /* EpoxyModelArrayBuilder.swift in Sources */, + 46EB2E000092F0 /* EpoxyModeled.swift in Sources */, + 46EB2E00009300 /* EpoxyModelProperty.swift in Sources */, + 46EB2E00009310 /* EpoxyModelStorage.swift in Sources */, + 46EB2E00009440 /* EpoxySwiftUIHostingController.swift in Sources */, + 46EB2E00009450 /* EpoxySwiftUIHostingView.swift in Sources */, + 46EB2E00009460 /* EpoxySwiftUIIntrinsicContentSizeInvalidator.swift in Sources */, + 46EB2E00009470 /* EpoxySwiftUILayoutMargins.swift in Sources */, + 46EB2E00009390 /* ErasedContentProviding.swift in Sources */, + 46EB2E00009630 /* FileManager+ZIP.swift in Sources */, + 46EB2E0000A0D0 /* FilepathImageProvider.swift in Sources */, + 46EB2E00009B80 /* Fill.swift in Sources */, + 46EB2E000098F0 /* FillNode.swift in Sources */, + 46EB2E00009840 /* FillRenderer.swift in Sources */, + 46EB2E0000A030 /* FloatValueProvider.swift in Sources */, + 46EB2E00009C60 /* Font.swift in Sources */, + 46EB2E00009C70 /* Glyph.swift in Sources */, + 46EB2E00009070 /* GradientAnimations.swift in Sources */, + 46EB2E00009B90 /* GradientFill.swift in Sources */, + 46EB2E00009900 /* GradientFillNode.swift in Sources */, + 46EB2E00009850 /* GradientFillRenderer.swift in Sources */, + 46EB2E000091A0 /* GradientRenderLayer.swift in Sources */, + 46EB2E00009BA0 /* GradientStroke.swift in Sources */, + 46EB2E00009910 /* GradientStrokeNode.swift in Sources */, + 46EB2E00009860 /* GradientStrokeRenderer.swift in Sources */, + 46EB2E0000A040 /* GradientValueProvider.swift in Sources */, + 46EB2E00009BB0 /* Group.swift in Sources */, + 46EB2E000097D0 /* GroupInterpolator.swift in Sources */, + 46EB2E000098E0 /* GroupNode.swift in Sources */, + 46EB2E00009810 /* GroupOutputNode.swift in Sources */, + 46EB2E000099B0 /* ImageAsset.swift in Sources */, + 46EB2E00009660 /* ImageCompositionLayer.swift in Sources */, + 46EB2E000091B0 /* ImageLayer.swift in Sources */, + 46EB2E00009AB0 /* ImageLayerModel.swift in Sources */, + 46EB2E000092A0 /* IndexChangeset.swift in Sources */, + 46EB2E000091C0 /* InfiniteOpaqueAnimationLayer.swift in Sources */, + 46EB2E0000A100 /* Interpolatable.swift in Sources */, + 46EB2E00009D90 /* InterpolatableExtensions.swift in Sources */, + 46EB2E00009710 /* InvertedMatteLayer.swift in Sources */, + 46EB2E00009760 /* ItemsExtension.swift in Sources */, + 46EB2E00009A30 /* KeyedDecodingContainerExtensions.swift in Sources */, + 46EB2E0000A110 /* Keyframe.swift in Sources */, + 46EB2E00009A40 /* KeyframeData.swift in Sources */, + 46EB2E00009DA0 /* KeyframeExtensions.swift in Sources */, + 46EB2E00009A50 /* KeyframeGroup.swift in Sources */, + 46EB2E00009130 /* KeyframeGroup+exactlyOneKeyframe.swift in Sources */, + 46EB2E00009DB0 /* KeyframeInterpolator.swift in Sources */, + 46EB2E00009140 /* Keyframes+combined.swift in Sources */, + 46EB2E00009150 /* Keyframes+timeRemapping.swift in Sources */, + 46EB2E000097A0 /* KeypathSearchable.swift in Sources */, + 46EB2E00009CC0 /* LayerDebugging.swift in Sources */, + 46EB2E00009AA0 /* LayerEffect.swift in Sources */, + 46EB2E00009720 /* LayerFontProvider.swift in Sources */, + 46EB2E00009730 /* LayerImageProvider.swift in Sources */, + 46EB2E00009AC0 /* LayerModel.swift in Sources */, + 46EB2E000091D0 /* LayerModel+makeAnimationLayer.swift in Sources */, + 46EB2E00009080 /* LayerProperty.swift in Sources */, + 46EB2E00009B20 /* LayerStyle.swift in Sources */, + 46EB2E00009740 /* LayerTextProvider.swift in Sources */, + 46EB2E00009750 /* LayerTransformNode.swift in Sources */, + 46EB2E00009870 /* LegacyGradientFillRenderer.swift in Sources */, + 46EB2E0000A1F0 /* lottie-ios-dummy.m in Sources */, + 46EB2E00009E60 /* LottieAnimation.swift in Sources */, + 46EB2E00009EF0 /* LottieAnimationCache.swift in Sources */, + 46EB2E00009E70 /* LottieAnimationHelpers.swift in Sources */, + 46EB2E00009E80 /* LottieAnimationLayer.swift in Sources */, + 46EB2E00009DC0 /* LottieAnimationSource.swift in Sources */, + 46EB2E00009E90 /* LottieAnimationView.swift in Sources */, + 46EB2E0000A0E0 /* LottieAnimationViewBase.swift in Sources */, + 46EB2E00009EA0 /* LottieAnimationViewInitializers.swift in Sources */, + 46EB2E00009F80 /* LottieButton.swift in Sources */, + 46EB2E0000A140 /* LottieColor.swift in Sources */, + 46EB2E00009F20 /* LottieConfiguration.swift in Sources */, + 46EB2E0000A120 /* LottieLogger.swift in Sources */, + 46EB2E00009EB0 /* LottiePlaybackMode.swift in Sources */, + 46EB2E00009F90 /* LottieSwitch.swift in Sources */, + 46EB2E00009EC0 /* LottieView.swift in Sources */, + 46EB2E00009FA0 /* LottieViewType.swift in Sources */, + 46EB2E00009F00 /* LRUAnimationCache.swift in Sources */, + 46EB2E00009520 /* LRUCache.swift in Sources */, + 46EB2E000096D0 /* MainThreadAnimationLayer.swift in Sources */, + 46EB2E000093A0 /* MakeViewProviding.swift in Sources */, + 46EB2E00009B40 /* Marker.swift in Sources */, + 46EB2E00009B50 /* Mask.swift in Sources */, + 46EB2E000091E0 /* MaskCompositionLayer.swift in Sources */, + 46EB2E00009670 /* MaskContainerLayer.swift in Sources */, + 46EB2E00009D30 /* MathKit.swift in Sources */, + 46EB2E00009480 /* MeasuringViewRepresentable.swift in Sources */, + 46EB2E00009BC0 /* Merge.swift in Sources */, + 46EB2E00009770 /* NodeProperty.swift in Sources */, + 46EB2E000097B0 /* NodePropertyMap.swift in Sources */, + 46EB2E00009680 /* NullCompositionLayer.swift in Sources */, + 46EB2E00009090 /* OpacityAnimation.swift in Sources */, + 46EB2E00009820 /* PassThroughOutputNode.swift in Sources */, + 46EB2E00009E30 /* PathElement.swift in Sources */, + 46EB2E00009950 /* PathNode.swift in Sources */, + 46EB2E00009830 /* PathOutputNode.swift in Sources */, + 46EB2E0000A050 /* PointValueProvider.swift in Sources */, + 46EB2E000098A0 /* PolygonNode.swift in Sources */, + 46EB2E000099C0 /* PrecompAsset.swift in Sources */, + 46EB2E000091F0 /* PreCompLayer.swift in Sources */, + 46EB2E00009AD0 /* PreCompLayerModel.swift in Sources */, + 46EB2E00009690 /* PreCompositionLayer.swift in Sources */, + 46EB2E00009BD0 /* Rectangle.swift in Sources */, + 46EB2E000090A0 /* RectangleAnimation.swift in Sources */, + 46EB2E000098B0 /* RectNode.swift in Sources */, + 46EB2E00009F30 /* ReducedMotionOption.swift in Sources */, + 46EB2E00009F40 /* RenderingEngineOption.swift in Sources */, + 46EB2E00009960 /* RenderNode.swift in Sources */, + 46EB2E00009BE0 /* Repeater.swift in Sources */, + 46EB2E00009200 /* RepeaterLayer.swift in Sources */, + 46EB2E00009CA0 /* RootAnimationLayer.swift in Sources */, + 46EB2E00009BF0 /* RoundedCorners.swift in Sources */, + 46EB2E000097F0 /* RoundedCornersNode.swift in Sources */, + 46EB2E000092B0 /* SectionedChangeset.swift in Sources */, + 46EB2E000093B0 /* SetBehaviorsProviding.swift in Sources */, + 46EB2E000093C0 /* SetContentProviding.swift in Sources */, + 46EB2E00009C00 /* Shape.swift in Sources */, + 46EB2E000090B0 /* ShapeAnimation.swift in Sources */, + 46EB2E000096A0 /* ShapeCompositionLayer.swift in Sources */, + 46EB2E00009970 /* ShapeContainerLayer.swift in Sources */, + 46EB2E00009C10 /* ShapeItem.swift in Sources */, + 46EB2E00009210 /* ShapeItemLayer.swift in Sources */, + 46EB2E00009220 /* ShapeLayer.swift in Sources */, + 46EB2E00009AE0 /* ShapeLayerModel.swift in Sources */, + 46EB2E000098C0 /* ShapeNode.swift in Sources */, + 46EB2E00009980 /* ShapeRenderLayer.swift in Sources */, + 46EB2E00009C20 /* ShapeTransform.swift in Sources */, + 46EB2E000097E0 /* SingleValueProvider.swift in Sources */, + 46EB2E0000A060 /* SizeValueProvider.swift in Sources */, + 46EB2E000096B0 /* SolidCompositionLayer.swift in Sources */, + 46EB2E00009230 /* SolidLayer.swift in Sources */, + 46EB2E00009AF0 /* SolidLayerModel.swift in Sources */, + 46EB2E00009C30 /* Star.swift in Sources */, + 46EB2E000090C0 /* StarAnimation.swift in Sources */, + 46EB2E000098D0 /* StarNode.swift in Sources */, + 46EB2E00009D40 /* StringExtensions.swift in Sources */, + 46EB2E00009C40 /* Stroke.swift in Sources */, + 46EB2E000090D0 /* StrokeAnimation.swift in Sources */, + 46EB2E00009920 /* StrokeNode.swift in Sources */, + 46EB2E00009880 /* StrokeRenderer.swift in Sources */, + 46EB2E00009500 /* StyledView.swift in Sources */, + 46EB2E000093D0 /* StyleIDProviding.swift in Sources */, + 46EB2E00009490 /* SwiftUIMeasurementContainer.swift in Sources */, + 46EB2E000094A0 /* SwiftUIView.swift in Sources */, + 46EB2E00009CD0 /* TestHelpers.swift in Sources */, + 46EB2E00009C80 /* TextAnimator.swift in Sources */, + 46EB2E00009930 /* TextAnimatorNode.swift in Sources */, + 46EB2E000096C0 /* TextCompositionLayer.swift in Sources */, + 46EB2E00009C90 /* TextDocument.swift in Sources */, + 46EB2E00009240 /* TextLayer.swift in Sources */, + 46EB2E00009B00 /* TextLayerModel.swift in Sources */, + 46EB2E000093E0 /* TraitCollectionProviding.swift in Sources */, + 46EB2E00009B60 /* Transform.swift in Sources */, + 46EB2E000090E0 /* TransformAnimations.swift in Sources */, + 46EB2E00009250 /* TransformLayer.swift in Sources */, + 46EB2E00009C50 /* Trim.swift in Sources */, + 46EB2E00009800 /* TrimPathNode.swift in Sources */, + 46EB2E0000A0F0 /* UIColorExtension.swift in Sources */, + 46EB2E000094B0 /* UIView+SwiftUIView.swift in Sources */, + 46EB2E000094C0 /* UIViewConfiguringSwiftUIView.swift in Sources */, + 46EB2E00009E40 /* UnitBezier.swift in Sources */, + 46EB2E00009640 /* URL+ZIP.swift in Sources */, + 46EB2E000097C0 /* ValueContainer.swift in Sources */, + 46EB2E00009260 /* ValueProviderStore.swift in Sources */, + 46EB2E00009A90 /* Vector1DEffectValue.swift in Sources */, + 46EB2E0000A150 /* Vectors.swift in Sources */, + 46EB2E00009E50 /* VectorsExtensions.swift in Sources */, + 46EB2E00009D80 /* View+ValueChanged.swift in Sources */, + 46EB2E000093F0 /* ViewDifferentiatorProviding.swift in Sources */, + 46EB2E00009420 /* ViewEpoxyModeled.swift in Sources */, + 46EB2E00009400 /* ViewProviding.swift in Sources */, + 46EB2E00009510 /* ViewType.swift in Sources */, + 46EB2E000090F0 /* VisibilityAnimation.swift in Sources */, + 46EB2E00009410 /* WillDisplayProviding.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E00009010 /* Sources */ = { + 46EB2E00008FB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A2C0 /* Sources */ = { + 46EB2E0000A260 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E0000A350 /* Pods-CLDemo-OC-dummy.m in Sources */, + 46EB2E0000A2F0 /* Pods-CLDemo-OC-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46EB2E0000A3C0 /* Sources */ = { + 46EB2E0000A360 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46EB2E0000A480 /* Pods-CLDemo-Swift-dummy.m in Sources */, + 46EB2E0000A420 /* Pods-CLDemo-Swift-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 46EB2E0000A4A0 /* PBXTargetDependency */ = { + 46EB2E0000A440 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = DateTools; target = 2B1A4F9261E8F421732B6CB1319CCC3E /* DateTools */; - targetProxy = 46EB2E0000A490 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A430 /* PBXContainerItemProxy */; }; - 46EB2E0000A4C0 /* PBXTargetDependency */ = { + 46EB2E0000A460 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MJExtension; target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */; - targetProxy = 46EB2E0000A4B0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A450 /* PBXContainerItemProxy */; }; - 46EB2E0000A4E0 /* PBXTargetDependency */ = { + 46EB2E0000A480 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Masonry; target = 55AF53E6C77A10ED4985E04D74A8878E /* Masonry */; - targetProxy = 46EB2E0000A4D0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A470 /* PBXContainerItemProxy */; }; - 46EB2E0000A500 /* PBXTargetDependency */ = { + 46EB2E0000A4A0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SDWebImage; target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; - targetProxy = 46EB2E0000A4F0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A490 /* PBXContainerItemProxy */; }; - 46EB2E0000A520 /* PBXTargetDependency */ = { + 46EB2E0000A4C0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SDWebImageWebPCoder; target = 1953860EA9853AA2BC8022B242F08512 /* SDWebImageWebPCoder */; - targetProxy = 46EB2E0000A510 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A4B0 /* PBXContainerItemProxy */; }; - 46EB2E0000A540 /* PBXTargetDependency */ = { + 46EB2E0000A4E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = libwebp; target = 47D2E85A78C25869BB13521D8561A638 /* libwebp */; - targetProxy = 46EB2E0000A530 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A4D0 /* PBXContainerItemProxy */; }; - 46EB2E0000A560 /* PBXTargetDependency */ = { + 46EB2E0000A500 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SDWebImage; target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; - targetProxy = 46EB2E0000A550 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A4F0 /* PBXContainerItemProxy */; }; - 46EB2E0000A580 /* PBXTargetDependency */ = { + 46EB2E0000A520 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = CLCamera; target = 7B01858F4318778678571D6E58E2D832 /* CLCamera */; - targetProxy = 46EB2E0000A570 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A510 /* PBXContainerItemProxy */; }; - 46EB2E0000A5A0 /* PBXTargetDependency */ = { + 46EB2E0000A540 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = CLPopoverManager; target = 2808B98A5B29AEEB5B7418EEA8B1B92C /* CLPopoverManager */; - targetProxy = 46EB2E0000A590 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A530 /* PBXContainerItemProxy */; }; - 46EB2E0000A5C0 /* PBXTargetDependency */ = { + 46EB2E0000A560 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = CryptoSwift; target = 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */; - targetProxy = 46EB2E0000A5B0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A550 /* PBXContainerItemProxy */; }; - 46EB2E0000A5E0 /* PBXTargetDependency */ = { + 46EB2E0000A580 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = DateToolsSwift; target = CCB5EA80CC733D89D54DAEB30E93351D /* DateToolsSwift */; - targetProxy = 46EB2E0000A5D0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A570 /* PBXContainerItemProxy */; }; - 46EB2E0000A600 /* PBXTargetDependency */ = { + 46EB2E0000A5A0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Kingfisher; target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; - targetProxy = 46EB2E0000A5F0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A590 /* PBXContainerItemProxy */; }; - 46EB2E0000A620 /* PBXTargetDependency */ = { + 46EB2E0000A5C0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = LookinServer; target = 638FEAAFC575BB76BC6AC055CDDA3506 /* LookinServer */; - targetProxy = 46EB2E0000A610 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A5B0 /* PBXContainerItemProxy */; }; - 46EB2E0000A640 /* PBXTargetDependency */ = { + 46EB2E0000A5E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SnapKit; target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; - targetProxy = 46EB2E0000A630 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A5D0 /* PBXContainerItemProxy */; }; - 46EB2E0000A660 /* PBXTargetDependency */ = { + 46EB2E0000A600 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SwiftFormat; target = 1CD0618C486973D5588EF20D2E8C0AEA /* SwiftFormat */; - targetProxy = 46EB2E0000A650 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A5F0 /* PBXContainerItemProxy */; }; - 46EB2E0000A680 /* PBXTargetDependency */ = { + 46EB2E0000A620 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SwiftyJSON; target = D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */; - targetProxy = 46EB2E0000A670 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A610 /* PBXContainerItemProxy */; }; - 46EB2E0000A6A0 /* PBXTargetDependency */ = { + 46EB2E0000A640 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = TZImagePickerController; target = A96BBB982D62BB807B5BD10774BE2D07 /* TZImagePickerController */; - targetProxy = 46EB2E0000A690 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A630 /* PBXContainerItemProxy */; }; - 46EB2E0000A6C0 /* PBXTargetDependency */ = { + 46EB2E0000A660 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "lottie-ios"; target = 0B967D7F8561D42493EE289EC8D450D1 /* lottie-ios */; - targetProxy = 46EB2E0000A6B0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A650 /* PBXContainerItemProxy */; }; - 46EB2E0000A6E0 /* PBXTargetDependency */ = { + 46EB2E0000A680 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SnapKit; target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; - targetProxy = 46EB2E0000A6D0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A670 /* PBXContainerItemProxy */; }; - 46EB2E0000A700 /* PBXTargetDependency */ = { + 46EB2E0000A6A0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "CryptoSwift-CryptoSwift"; target = EBC10B6451F5FE5244D138B5176C2A02 /* CryptoSwift-CryptoSwift */; - targetProxy = 46EB2E0000A6F0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A690 /* PBXContainerItemProxy */; }; - 46EB2E0000A720 /* PBXTargetDependency */ = { + 46EB2E0000A6C0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "Kingfisher-Kingfisher"; target = 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */; - targetProxy = 46EB2E0000A710 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A6B0 /* PBXContainerItemProxy */; }; - 46EB2E0000A740 /* PBXTargetDependency */ = { + 46EB2E0000A6E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "MJExtension-MJExtension"; target = B32AF3F43989CBA171BB1FB3957A4509 /* MJExtension-MJExtension */; - targetProxy = 46EB2E0000A730 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A6D0 /* PBXContainerItemProxy */; }; - 46EB2E0000A760 /* PBXTargetDependency */ = { + 46EB2E0000A700 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "SDWebImage-SDWebImage"; target = 94CFBA7D633ECA58DF85C327B035E6A3 /* SDWebImage-SDWebImage */; - targetProxy = 46EB2E0000A750 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A6F0 /* PBXContainerItemProxy */; }; - 46EB2E0000A780 /* PBXTargetDependency */ = { + 46EB2E0000A720 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SDWebImage; target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; - targetProxy = 46EB2E0000A770 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A710 /* PBXContainerItemProxy */; }; - 46EB2E0000A7A0 /* PBXTargetDependency */ = { + 46EB2E0000A740 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = libwebp; target = 47D2E85A78C25869BB13521D8561A638 /* libwebp */; - targetProxy = 46EB2E0000A790 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A730 /* PBXContainerItemProxy */; }; - 46EB2E0000A7C0 /* PBXTargetDependency */ = { + 46EB2E0000A760 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "SnapKit-SnapKit_Privacy"; target = 8A8DB685241263AFDF5E6B20FE67B93A /* SnapKit-SnapKit_Privacy */; - targetProxy = 46EB2E0000A7B0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A750 /* PBXContainerItemProxy */; }; - 46EB2E0000A7E0 /* PBXTargetDependency */ = { + 46EB2E0000A780 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "SwiftyJSON-SwiftyJSON"; target = 677650A76A720691B88A6959EFED6418 /* SwiftyJSON-SwiftyJSON */; - targetProxy = 46EB2E0000A7D0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A770 /* PBXContainerItemProxy */; }; - 46EB2E0000A800 /* PBXTargetDependency */ = { + 46EB2E0000A7A0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "lottie-ios-LottiePrivacyInfo"; target = BF2A15FEC3F3424BBC4B9AD5F86F2D54 /* lottie-ios-LottiePrivacyInfo */; - targetProxy = 46EB2E0000A7F0 /* PBXContainerItemProxy */; + targetProxy = 46EB2E0000A790 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -7048,18 +7024,15 @@ }; name = Release; }; - 46EB2E00004810 /* Release */ = { + 46EB2E000047D0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000049C0 /* CLCamera.release.xcconfig */; + baseConfigurationReference = 46EB2E00004980 /* CLCamera.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CLCamera/CLCamera-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CLCamera/CLCamera.modulemap; OTHER_LDFLAGS = ""; @@ -7071,25 +7044,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00004820 /* Debug */ = { + 46EB2E000047E0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000049B0 /* CLCamera.debug.xcconfig */; + baseConfigurationReference = 46EB2E00004970 /* CLCamera.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CLCamera/CLCamera-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CLCamera/CLCamera.modulemap; OTHER_LDFLAGS = ""; @@ -7101,24 +7070,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00004A60 /* Release */ = { + 46EB2E00004A20 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00004B30 /* CLPopoverManager.release.xcconfig */; + baseConfigurationReference = 46EB2E00004AF0 /* CLPopoverManager.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CLPopoverManager/CLPopoverManager-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CLPopoverManager/CLPopoverManager.modulemap; OTHER_LDFLAGS = ""; @@ -7130,25 +7095,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00004A70 /* Debug */ = { + 46EB2E00004A30 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00004B20 /* CLPopoverManager.debug.xcconfig */; + baseConfigurationReference = 46EB2E00004AE0 /* CLPopoverManager.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CLPopoverManager/CLPopoverManager-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CLPopoverManager/CLPopoverManager.modulemap; OTHER_LDFLAGS = ""; @@ -7160,24 +7121,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00004BD0 /* Release */ = { + 46EB2E00004B90 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005400 /* CryptoSwift.release.xcconfig */; + baseConfigurationReference = 46EB2E000053C0 /* CryptoSwift.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CryptoSwift/CryptoSwift.modulemap; OTHER_LDFLAGS = ""; @@ -7189,25 +7146,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.6; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00004BE0 /* Debug */ = { + 46EB2E00004BA0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000053F0 /* CryptoSwift.debug.xcconfig */; + baseConfigurationReference = 46EB2E000053B0 /* CryptoSwift.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/CryptoSwift/CryptoSwift.modulemap; OTHER_LDFLAGS = ""; @@ -7219,15 +7172,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.6; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00004C50 /* Release */ = { + 46EB2E00004C10 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005400 /* CryptoSwift.release.xcconfig */; + baseConfigurationReference = 46EB2E000053C0 /* CryptoSwift.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/CryptoSwift"; @@ -7242,9 +7194,9 @@ }; name = Release; }; - 46EB2E00004C60 /* Debug */ = { + 46EB2E00004C20 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000053F0 /* CryptoSwift.debug.xcconfig */; + baseConfigurationReference = 46EB2E000053B0 /* CryptoSwift.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/CryptoSwift"; @@ -7259,17 +7211,14 @@ }; name = Debug; }; - 46EB2E000054A0 /* Release */ = { + 46EB2E00005460 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005610 /* DateTools.release.xcconfig */; + baseConfigurationReference = 46EB2E000055D0 /* DateTools.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/DateTools/DateTools-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/DateTools/DateTools.modulemap; OTHER_LDFLAGS = ""; @@ -7281,24 +7230,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E000054B0 /* Debug */ = { + 46EB2E00005470 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005600 /* DateTools.debug.xcconfig */; + baseConfigurationReference = 46EB2E000055C0 /* DateTools.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/DateTools/DateTools-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/DateTools/DateTools.modulemap; OTHER_LDFLAGS = ""; @@ -7310,23 +7255,19 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E000056A0 /* Release */ = { + 46EB2E00005660 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005810 /* DateToolsSwift.release.xcconfig */; + baseConfigurationReference = 46EB2E000057D0 /* DateToolsSwift.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/DateToolsSwift/DateToolsSwift-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/DateToolsSwift/DateToolsSwift.modulemap; OTHER_LDFLAGS = ""; @@ -7338,24 +7279,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E000056B0 /* Debug */ = { + 46EB2E00005670 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005800 /* DateToolsSwift.debug.xcconfig */; + baseConfigurationReference = 46EB2E000057C0 /* DateToolsSwift.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/DateToolsSwift/DateToolsSwift-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/DateToolsSwift/DateToolsSwift.modulemap; OTHER_LDFLAGS = ""; @@ -7367,24 +7304,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E000058B0 /* Release */ = { + 46EB2E00005870 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005DC0 /* Kingfisher.release.xcconfig */; + baseConfigurationReference = 46EB2E00005D80 /* Kingfisher.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/Kingfisher/Kingfisher.modulemap; OTHER_LDFLAGS = ""; @@ -7396,25 +7329,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E000058C0 /* Debug */ = { + 46EB2E00005880 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005DB0 /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = 46EB2E00005D70 /* Kingfisher.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/Kingfisher/Kingfisher.modulemap; OTHER_LDFLAGS = ""; @@ -7426,15 +7355,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00005930 /* Release */ = { + 46EB2E000058F0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005DC0 /* Kingfisher.release.xcconfig */; + baseConfigurationReference = 46EB2E00005D80 /* Kingfisher.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; @@ -7449,9 +7377,9 @@ }; name = Release; }; - 46EB2E00005940 /* Debug */ = { + 46EB2E00005900 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00005DB0 /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = 46EB2E00005D70 /* Kingfisher.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; @@ -7466,17 +7394,14 @@ }; name = Debug; }; - 46EB2E00005E60 /* Release */ = { + 46EB2E00005E20 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006750 /* LookinServer.release.xcconfig */; + baseConfigurationReference = 46EB2E00006710 /* LookinServer.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/LookinServer/LookinServer-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/LookinServer/LookinServer.modulemap; OTHER_LDFLAGS = ""; @@ -7487,24 +7412,20 @@ PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00005E70 /* Debug */ = { + 46EB2E00005E30 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006740 /* LookinServer.debug.xcconfig */; + baseConfigurationReference = 46EB2E00006700 /* LookinServer.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/LookinServer/LookinServer-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/LookinServer/LookinServer.modulemap; OTHER_LDFLAGS = ""; @@ -7515,24 +7436,20 @@ PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E000067E0 /* Release */ = { + 46EB2E000067A0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006A50 /* MJExtension.release.xcconfig */; + baseConfigurationReference = 46EB2E00006A00 /* MJExtension.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/MJExtension/MJExtension-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/MJExtension/MJExtension.modulemap; OTHER_LDFLAGS = ""; @@ -7544,25 +7461,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E000067F0 /* Debug */ = { + 46EB2E000067B0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006A40 /* MJExtension.debug.xcconfig */; + baseConfigurationReference = 46EB2E000069F0 /* MJExtension.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/MJExtension/MJExtension-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/MJExtension/MJExtension.modulemap; OTHER_LDFLAGS = ""; @@ -7574,15 +7487,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00006860 /* Release */ = { + 46EB2E00006820 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006A50 /* MJExtension.release.xcconfig */; + baseConfigurationReference = 46EB2E00006A00 /* MJExtension.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MJExtension"; @@ -7597,9 +7509,9 @@ }; name = Release; }; - 46EB2E00006870 /* Debug */ = { + 46EB2E00006830 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006A40 /* MJExtension.debug.xcconfig */; + baseConfigurationReference = 46EB2E000069F0 /* MJExtension.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MJExtension"; @@ -7614,17 +7526,14 @@ }; name = Debug; }; - 46EB2E00006AE0 /* Release */ = { + 46EB2E00006A90 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006CF0 /* Masonry.release.xcconfig */; + baseConfigurationReference = 46EB2E00006CA0 /* Masonry.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/Masonry/Masonry-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/Masonry/Masonry.modulemap; OTHER_LDFLAGS = ""; @@ -7636,24 +7545,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00006AF0 /* Debug */ = { + 46EB2E00006AA0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00006CE0 /* Masonry.debug.xcconfig */; + baseConfigurationReference = 46EB2E00006C90 /* Masonry.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/Masonry/Masonry-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/Masonry/Masonry.modulemap; OTHER_LDFLAGS = ""; @@ -7665,23 +7570,19 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00006D80 /* Release */ = { + 46EB2E00006D30 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000077E0 /* SDWebImage.release.xcconfig */; + baseConfigurationReference = 46EB2E00007790 /* SDWebImage.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SDWebImage/SDWebImage.modulemap; OTHER_LDFLAGS = ""; @@ -7693,24 +7594,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00006D90 /* Debug */ = { + 46EB2E00006D40 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000077D0 /* SDWebImage.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007780 /* SDWebImage.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SDWebImage/SDWebImage.modulemap; OTHER_LDFLAGS = ""; @@ -7722,15 +7619,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00006E00 /* Release */ = { + 46EB2E00006DB0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000077E0 /* SDWebImage.release.xcconfig */; + baseConfigurationReference = 46EB2E00007790 /* SDWebImage.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SDWebImage"; @@ -7745,9 +7641,9 @@ }; name = Release; }; - 46EB2E00006E10 /* Debug */ = { + 46EB2E00006DC0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000077D0 /* SDWebImage.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007780 /* SDWebImage.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SDWebImage"; @@ -7762,17 +7658,14 @@ }; name = Debug; }; - 46EB2E00007870 /* Release */ = { + 46EB2E00007820 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007980 /* SDWebImageWebPCoder.release.xcconfig */; + baseConfigurationReference = 46EB2E00007930 /* SDWebImageWebPCoder.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SDWebImageWebPCoder/SDWebImageWebPCoder-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap; OTHER_LDFLAGS = ""; @@ -7784,24 +7677,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00007880 /* Debug */ = { + 46EB2E00007830 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007970 /* SDWebImageWebPCoder.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007920 /* SDWebImageWebPCoder.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SDWebImageWebPCoder/SDWebImageWebPCoder-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap; OTHER_LDFLAGS = ""; @@ -7813,24 +7702,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E000079F0 /* Release */ = { + 46EB2E000079A0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007D60 /* SnapKit.release.xcconfig */; + baseConfigurationReference = 46EB2E00007D00 /* SnapKit.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SnapKit/SnapKit.modulemap; OTHER_LDFLAGS = ""; @@ -7842,25 +7727,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00007A00 /* Debug */ = { + 46EB2E000079B0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007D50 /* SnapKit.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007CF0 /* SnapKit.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SnapKit/SnapKit.modulemap; OTHER_LDFLAGS = ""; @@ -7872,15 +7753,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00007A70 /* Release */ = { + 46EB2E00007A20 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007D60 /* SnapKit.release.xcconfig */; + baseConfigurationReference = 46EB2E00007D00 /* SnapKit.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SnapKit"; @@ -7895,9 +7775,9 @@ }; name = Release; }; - 46EB2E00007A80 /* Debug */ = { + 46EB2E00007A30 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007D50 /* SnapKit.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007CF0 /* SnapKit.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SnapKit"; @@ -7912,14 +7792,13 @@ }; name = Debug; }; - 46EB2E00007E00 /* Release */ = { + 46EB2E00007DA0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007E40 /* SwiftFormat.release.xcconfig */; + baseConfigurationReference = 46EB2E00007DE0 /* SwiftFormat.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_OBJC_WEAK = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -7931,14 +7810,13 @@ }; name = Release; }; - 46EB2E00007E10 /* Debug */ = { + 46EB2E00007DB0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007E30 /* SwiftFormat.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007DD0 /* SwiftFormat.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_OBJC_WEAK = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -7949,18 +7827,15 @@ }; name = Debug; }; - 46EB2E00007E70 /* Release */ = { + 46EB2E00007E10 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007FA0 /* SwiftyJSON.release.xcconfig */; + baseConfigurationReference = 46EB2E00007F40 /* SwiftyJSON.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SwiftyJSON/SwiftyJSON.modulemap; OTHER_LDFLAGS = ""; @@ -7972,25 +7847,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00007E80 /* Debug */ = { + 46EB2E00007E20 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007F90 /* SwiftyJSON.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007F30 /* SwiftyJSON.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/SwiftyJSON/SwiftyJSON.modulemap; OTHER_LDFLAGS = ""; @@ -8002,15 +7873,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00007EF0 /* Release */ = { + 46EB2E00007E90 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007FA0 /* SwiftyJSON.release.xcconfig */; + baseConfigurationReference = 46EB2E00007F40 /* SwiftyJSON.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SwiftyJSON"; @@ -8025,9 +7895,9 @@ }; name = Release; }; - 46EB2E00007F00 /* Debug */ = { + 46EB2E00007EA0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00007F90 /* SwiftyJSON.debug.xcconfig */; + baseConfigurationReference = 46EB2E00007F30 /* SwiftyJSON.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SwiftyJSON"; @@ -8042,18 +7912,15 @@ }; name = Debug; }; - 46EB2E00008040 /* Release */ = { + 46EB2E00007FE0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00008300 /* TZImagePickerController.release.xcconfig */; + baseConfigurationReference = 46EB2E000082A0 /* TZImagePickerController.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/TZImagePickerController/TZImagePickerController-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/TZImagePickerController/TZImagePickerController.modulemap; OTHER_LDFLAGS = ""; @@ -8065,25 +7932,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00008050 /* Debug */ = { + 46EB2E00007FF0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E000082F0 /* TZImagePickerController.debug.xcconfig */; + baseConfigurationReference = 46EB2E00008290 /* TZImagePickerController.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/TZImagePickerController/TZImagePickerController-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/TZImagePickerController/TZImagePickerController.modulemap; OTHER_LDFLAGS = ""; @@ -8095,23 +7958,19 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00008390 /* Release */ = { + 46EB2E00008330 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00008ED0 /* libwebp.release.xcconfig */; + baseConfigurationReference = 46EB2E00008E70 /* libwebp.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/libwebp/libwebp-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/libwebp/libwebp.modulemap; OTHER_LDFLAGS = ""; @@ -8123,24 +7982,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E000083A0 /* Debug */ = { + 46EB2E00008340 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E00008EC0 /* libwebp.debug.xcconfig */; + baseConfigurationReference = 46EB2E00008E60 /* libwebp.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/libwebp/libwebp-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = Headers/Public/libwebp/libwebp.modulemap; OTHER_LDFLAGS = ""; @@ -8152,24 +8007,20 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00008F60 /* Release */ = { + 46EB2E00008F00 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A1E0 /* lottie-ios.release.xcconfig */; + baseConfigurationReference = 46EB2E0000A180 /* lottie-ios.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/lottie-ios/lottie-ios-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = "Headers/Public/Lottie/lottie-ios.modulemap"; OTHER_LDFLAGS = ""; @@ -8181,25 +8032,21 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.7; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 46EB2E00008F70 /* Debug */ = { + 46EB2E00008F10 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A1D0 /* lottie-ios.debug.xcconfig */; + baseConfigurationReference = 46EB2E0000A170 /* lottie-ios.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PREFIX_HEADER = "Target Support Files/lottie-ios/lottie-ios-prefix.pch"; - GENERATE_INFOPLIST_FILE = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MODULEMAP_FILE = "Headers/Public/Lottie/lottie-ios.modulemap"; OTHER_LDFLAGS = ""; @@ -8211,15 +8058,14 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 5.7; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 46EB2E00008FE0 /* Release */ = { + 46EB2E00008F80 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A1E0 /* lottie-ios.release.xcconfig */; + baseConfigurationReference = 46EB2E0000A180 /* lottie-ios.release.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lottie-ios"; @@ -8234,9 +8080,9 @@ }; name = Release; }; - 46EB2E00008FF0 /* Debug */ = { + 46EB2E00008F90 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A1D0 /* lottie-ios.debug.xcconfig */; + baseConfigurationReference = 46EB2E0000A170 /* lottie-ios.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lottie-ios"; @@ -8251,17 +8097,15 @@ }; name = Debug; }; - 46EB2E0000A280 /* Release */ = { + 46EB2E0000A220 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A2F0 /* Pods-CLDemo-OC.release.xcconfig */; + baseConfigurationReference = 46EB2E0000A290 /* Pods-CLDemo-OC.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; @@ -8275,17 +8119,15 @@ }; name = Release; }; - 46EB2E0000A290 /* Debug */ = { + 46EB2E0000A230 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A300 /* Pods-CLDemo-OC.debug.xcconfig */; + baseConfigurationReference = 46EB2E0000A2A0 /* Pods-CLDemo-OC.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; @@ -8298,17 +8140,15 @@ }; name = Debug; }; - 46EB2E0000A380 /* Release */ = { + 46EB2E0000A320 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A3F0 /* Pods-CLDemo-Swift.release.xcconfig */; + baseConfigurationReference = 46EB2E0000A390 /* Pods-CLDemo-Swift.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.modulemap"; @@ -8323,17 +8163,15 @@ }; name = Release; }; - 46EB2E0000A390 /* Debug */ = { + 46EB2E0000A330 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46EB2E0000A400 /* Pods-CLDemo-Swift.debug.xcconfig */; + baseConfigurationReference = 46EB2E0000A3A0 /* Pods-CLDemo-Swift.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.modulemap"; @@ -8359,236 +8197,236 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00004800 /* Build configuration list for PBXNativeTarget "CLCamera" */ = { + 46EB2E000047C0 /* Build configuration list for PBXNativeTarget "CLCamera" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00004820 /* Debug */, - 46EB2E00004810 /* Release */, + 46EB2E000047E0 /* Debug */, + 46EB2E000047D0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00004A50 /* Build configuration list for PBXNativeTarget "CLPopoverManager" */ = { + 46EB2E00004A10 /* Build configuration list for PBXNativeTarget "CLPopoverManager" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00004A70 /* Debug */, - 46EB2E00004A60 /* Release */, + 46EB2E00004A30 /* Debug */, + 46EB2E00004A20 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00004BC0 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { + 46EB2E00004B80 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00004BE0 /* Debug */, - 46EB2E00004BD0 /* Release */, + 46EB2E00004BA0 /* Debug */, + 46EB2E00004B90 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00004C40 /* Build configuration list for PBXNativeTarget "CryptoSwift-CryptoSwift" */ = { + 46EB2E00004C00 /* Build configuration list for PBXNativeTarget "CryptoSwift-CryptoSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00004C60 /* Debug */, - 46EB2E00004C50 /* Release */, + 46EB2E00004C20 /* Debug */, + 46EB2E00004C10 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00005490 /* Build configuration list for PBXNativeTarget "DateTools" */ = { + 46EB2E00005450 /* Build configuration list for PBXNativeTarget "DateTools" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E000054B0 /* Debug */, - 46EB2E000054A0 /* Release */, + 46EB2E00005470 /* Debug */, + 46EB2E00005460 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00005690 /* Build configuration list for PBXNativeTarget "DateToolsSwift" */ = { + 46EB2E00005650 /* Build configuration list for PBXNativeTarget "DateToolsSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E000056B0 /* Debug */, - 46EB2E000056A0 /* Release */, + 46EB2E00005670 /* Debug */, + 46EB2E00005660 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E000058A0 /* Build configuration list for PBXNativeTarget "Kingfisher" */ = { + 46EB2E00005860 /* Build configuration list for PBXNativeTarget "Kingfisher" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E000058C0 /* Debug */, - 46EB2E000058B0 /* Release */, + 46EB2E00005880 /* Debug */, + 46EB2E00005870 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00005920 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */ = { + 46EB2E000058E0 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00005940 /* Debug */, - 46EB2E00005930 /* Release */, + 46EB2E00005900 /* Debug */, + 46EB2E000058F0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00005E50 /* Build configuration list for PBXNativeTarget "LookinServer" */ = { + 46EB2E00005E10 /* Build configuration list for PBXNativeTarget "LookinServer" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00005E70 /* Debug */, - 46EB2E00005E60 /* Release */, + 46EB2E00005E30 /* Debug */, + 46EB2E00005E20 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E000067D0 /* Build configuration list for PBXNativeTarget "MJExtension" */ = { + 46EB2E00006790 /* Build configuration list for PBXNativeTarget "MJExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E000067F0 /* Debug */, - 46EB2E000067E0 /* Release */, + 46EB2E000067B0 /* Debug */, + 46EB2E000067A0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00006850 /* Build configuration list for PBXNativeTarget "MJExtension-MJExtension" */ = { + 46EB2E00006810 /* Build configuration list for PBXNativeTarget "MJExtension-MJExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00006870 /* Debug */, - 46EB2E00006860 /* Release */, + 46EB2E00006830 /* Debug */, + 46EB2E00006820 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00006AD0 /* Build configuration list for PBXNativeTarget "Masonry" */ = { + 46EB2E00006A80 /* Build configuration list for PBXNativeTarget "Masonry" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00006AF0 /* Debug */, - 46EB2E00006AE0 /* Release */, + 46EB2E00006AA0 /* Debug */, + 46EB2E00006A90 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00006D70 /* Build configuration list for PBXNativeTarget "SDWebImage" */ = { + 46EB2E00006D20 /* Build configuration list for PBXNativeTarget "SDWebImage" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00006D90 /* Debug */, - 46EB2E00006D80 /* Release */, + 46EB2E00006D40 /* Debug */, + 46EB2E00006D30 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00006DF0 /* Build configuration list for PBXNativeTarget "SDWebImage-SDWebImage" */ = { + 46EB2E00006DA0 /* Build configuration list for PBXNativeTarget "SDWebImage-SDWebImage" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00006E10 /* Debug */, - 46EB2E00006E00 /* Release */, + 46EB2E00006DC0 /* Debug */, + 46EB2E00006DB0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00007860 /* Build configuration list for PBXNativeTarget "SDWebImageWebPCoder" */ = { + 46EB2E00007810 /* Build configuration list for PBXNativeTarget "SDWebImageWebPCoder" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007880 /* Debug */, - 46EB2E00007870 /* Release */, + 46EB2E00007830 /* Debug */, + 46EB2E00007820 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E000079E0 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { + 46EB2E00007990 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007A00 /* Debug */, - 46EB2E000079F0 /* Release */, + 46EB2E000079B0 /* Debug */, + 46EB2E000079A0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00007A60 /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */ = { + 46EB2E00007A10 /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007A80 /* Debug */, - 46EB2E00007A70 /* Release */, + 46EB2E00007A30 /* Debug */, + 46EB2E00007A20 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00007DF0 /* Build configuration list for PBXAggregateTarget "SwiftFormat" */ = { + 46EB2E00007D90 /* Build configuration list for PBXAggregateTarget "SwiftFormat" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007E10 /* Debug */, - 46EB2E00007E00 /* Release */, + 46EB2E00007DB0 /* Debug */, + 46EB2E00007DA0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00007E60 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */ = { + 46EB2E00007E00 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007E80 /* Debug */, - 46EB2E00007E70 /* Release */, + 46EB2E00007E20 /* Debug */, + 46EB2E00007E10 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00007EE0 /* Build configuration list for PBXNativeTarget "SwiftyJSON-SwiftyJSON" */ = { + 46EB2E00007E80 /* Build configuration list for PBXNativeTarget "SwiftyJSON-SwiftyJSON" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00007F00 /* Debug */, - 46EB2E00007EF0 /* Release */, + 46EB2E00007EA0 /* Debug */, + 46EB2E00007E90 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00008030 /* Build configuration list for PBXNativeTarget "TZImagePickerController" */ = { + 46EB2E00007FD0 /* Build configuration list for PBXNativeTarget "TZImagePickerController" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00008050 /* Debug */, - 46EB2E00008040 /* Release */, + 46EB2E00007FF0 /* Debug */, + 46EB2E00007FE0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00008380 /* Build configuration list for PBXNativeTarget "libwebp" */ = { + 46EB2E00008320 /* Build configuration list for PBXNativeTarget "libwebp" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E000083A0 /* Debug */, - 46EB2E00008390 /* Release */, + 46EB2E00008340 /* Debug */, + 46EB2E00008330 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00008F50 /* Build configuration list for PBXNativeTarget "lottie-ios" */ = { + 46EB2E00008EF0 /* Build configuration list for PBXNativeTarget "lottie-ios" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00008F70 /* Debug */, - 46EB2E00008F60 /* Release */, + 46EB2E00008F10 /* Debug */, + 46EB2E00008F00 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E00008FD0 /* Build configuration list for PBXNativeTarget "lottie-ios-LottiePrivacyInfo" */ = { + 46EB2E00008F70 /* Build configuration list for PBXNativeTarget "lottie-ios-LottiePrivacyInfo" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E00008FF0 /* Debug */, - 46EB2E00008FE0 /* Release */, + 46EB2E00008F90 /* Debug */, + 46EB2E00008F80 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E0000A270 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-OC" */ = { + 46EB2E0000A210 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-OC" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E0000A290 /* Debug */, - 46EB2E0000A280 /* Release */, + 46EB2E0000A230 /* Debug */, + 46EB2E0000A220 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 46EB2E0000A370 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-Swift" */ = { + 46EB2E0000A310 /* Build configuration list for PBXNativeTarget "Pods-CLDemo-Swift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 46EB2E0000A390 /* Debug */, - 46EB2E0000A380 /* Release */, + 46EB2E0000A330 /* Debug */, + 46EB2E0000A320 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLCamera.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLCamera.xcscheme new file mode 100644 index 00000000..4fc74468 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLCamera.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLPopoverManager.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLPopoverManager.xcscheme new file mode 100644 index 00000000..616d7089 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CLPopoverManager.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift-CryptoSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift-CryptoSwift.xcscheme new file mode 100644 index 00000000..f621f836 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift-CryptoSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift.xcscheme new file mode 100644 index 00000000..f5f77ca1 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/CryptoSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateTools.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateTools.xcscheme new file mode 100644 index 00000000..b26cce04 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateTools.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateToolsSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateToolsSwift.xcscheme new file mode 100644 index 00000000..22ba7ec2 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/DateToolsSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher-Kingfisher.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher-Kingfisher.xcscheme new file mode 100644 index 00000000..dd7f78d6 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher-Kingfisher.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher.xcscheme new file mode 100644 index 00000000..9fb78850 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Kingfisher.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/LookinServer.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/LookinServer.xcscheme new file mode 100644 index 00000000..a6db9190 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/LookinServer.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension-MJExtension.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension-MJExtension.xcscheme new file mode 100644 index 00000000..e9de14f2 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension-MJExtension.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension.xcscheme new file mode 100644 index 00000000..8d0e3a37 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/MJExtension.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Masonry.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Masonry.xcscheme new file mode 100644 index 00000000..0ffd2e11 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Masonry.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-OC.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-OC.xcscheme new file mode 100644 index 00000000..724637c6 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-OC.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-Swift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-Swift.xcscheme new file mode 100644 index 00000000..bd1ea987 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/Pods-CLDemo-Swift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage-SDWebImage.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage-SDWebImage.xcscheme new file mode 100644 index 00000000..ec2596b4 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage-SDWebImage.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage.xcscheme new file mode 100644 index 00000000..88b0a0c7 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImage.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImageWebPCoder.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImageWebPCoder.xcscheme new file mode 100644 index 00000000..0e3d6447 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SDWebImageWebPCoder.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit-SnapKit_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit-SnapKit_Privacy.xcscheme new file mode 100644 index 00000000..db63be7b --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit-SnapKit_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit.xcscheme new file mode 100644 index 00000000..5fc93600 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SnapKit.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftFormat.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftFormat.xcscheme new file mode 100644 index 00000000..f600915a --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftFormat.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON-SwiftyJSON.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON-SwiftyJSON.xcscheme new file mode 100644 index 00000000..ec57b774 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON-SwiftyJSON.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON.xcscheme new file mode 100644 index 00000000..75f50786 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/SwiftyJSON.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/TZImagePickerController.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/TZImagePickerController.xcscheme new file mode 100644 index 00000000..0f2cf006 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/TZImagePickerController.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/libwebp.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/libwebp.xcscheme new file mode 100644 index 00000000..15ad40ab --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/libwebp.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme new file mode 100644 index 00000000..c94c69f3 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios.xcscheme new file mode 100644 index 00000000..31bc05e9 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/liangsen.xcuserdatad/xcschemes/lottie-ios.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.h b/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.h new file mode 100644 index 00000000..faa74eab --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.h @@ -0,0 +1,54 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +#import "SDWebImageCompat.h" + +/// SDCallbackPolicy controls how we execute the block on the queue, like whether to use `dispatch_async/dispatch_sync`, check if current queue match target queue, or just invoke without any context. +typedef NS_ENUM(NSUInteger, SDCallbackPolicy) { + /// When the current queue is equal to callback queue, sync/async will just invoke `block` directly without dispatch. Else it use `dispatch_async`/`dispatch_sync` to dispatch block on queue. This is useful for UIKit rendering to ensure all blocks executed in the same runloop + SDCallbackPolicySafeExecute = 0, + /// Follow async/sync using the correspond `dispatch_async`/`dispatch_sync` to dispatch block on queue + SDCallbackPolicyDispatch = 1, + /// Ignore any async/sync and just directly invoke `block` in current queue (without `dispatch_async`/`dispatch_sync`) + SDCallbackPolicyInvoke = 2 +}; + +/// SDCallbackQueue is a wrapper used to control how the completionBlock should perform on queues, used by our `Cache`/`Manager`/`Loader`. +/// Useful when you call SDWebImage in non-main queue and want to avoid it callback into main queue, which may cause issue. +@interface SDCallbackQueue : NSObject + +/// The shared main queue. This is the default value, has the same effect when passing `nil` to `SDWebImageContextCallbackQueue` +@property (nonnull, class, readonly) SDCallbackQueue *mainQueue; + +/// The caller current queue. Using `dispatch_get_current_queue`. This is not a dynamic value and only keep the first call time queue. +@property (nonnull, class, readonly) SDCallbackQueue *currentQueue; + +/// The global concurrent queue (user-initiated QoS). Using `dispatch_get_global_queue`. +@property (nonnull, class, readonly) SDCallbackQueue *globalQueue; + +/// The current queue's callback policy, defaults to `SDCallbackPolicySafeExecute`, which behaves like the old macro `dispatch_main_async_safe` +@property (assign, readwrite) SDCallbackPolicy policy; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +/// Create the callback queue with a GCD queue +/// - Parameter queue: The GCD queue, should not be NULL +- (nonnull instancetype)initWithDispatchQueue:(nonnull dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER; + +#pragma mark - Execution Entry + +/// Submits a block for execution and returns after that block finishes executing. +/// - Parameter block: The block that contains the work to perform. +- (void)sync:(nonnull dispatch_block_t)block; + +/// Schedules a block asynchronously for execution. +/// - Parameter block: The block that contains the work to perform. +- (void)async:(nonnull dispatch_block_t)block; + +@end diff --git a/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.m b/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.m new file mode 100644 index 00000000..33cf55fc --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Core/SDCallbackQueue.m @@ -0,0 +1,120 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +#import "SDCallbackQueue.h" + +@interface SDCallbackQueue () + +@property (nonatomic, strong, nonnull) dispatch_queue_t queue; + +@end + +static void * SDCallbackQueueKey = &SDCallbackQueueKey; +static void SDReleaseBlock(void *context) { + CFRelease(context); +} + +static void SDSafeExecute(SDCallbackQueue *callbackQueue, dispatch_block_t _Nonnull block, BOOL async) { + // Extendc gcd queue's life cycle + dispatch_queue_t queue = callbackQueue.queue; + // Special handle for main queue label only (custom queue can have the same label) + const char *label = dispatch_queue_get_label(queue); + if (label && label == dispatch_queue_get_label(dispatch_get_main_queue())) { + const char *currentLabel = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); + if (label == currentLabel) { + block(); + return; + } + } + // Check specific to detect queue equal + void *specific = dispatch_queue_get_specific(queue, SDCallbackQueueKey); + if (specific && CFGetTypeID(specific) == CFUUIDGetTypeID()) { + void *currentSpecific = dispatch_get_specific(SDCallbackQueueKey); + if (currentSpecific && CFGetTypeID(currentSpecific) == CFUUIDGetTypeID() && CFEqual(specific, currentSpecific)) { + block(); + return; + } + } + if (async) { + dispatch_async(queue, block); + } else { + dispatch_sync(queue, block); + } +} + +@implementation SDCallbackQueue + +- (instancetype)initWithDispatchQueue:(dispatch_queue_t)queue { + self = [super init]; + if (self) { + NSCParameterAssert(queue); + CFUUIDRef UUID = CFUUIDCreate(kCFAllocatorDefault); + dispatch_queue_set_specific(queue, SDCallbackQueueKey, (void *)UUID, SDReleaseBlock); + _queue = queue; + } + return self; +} + ++ (SDCallbackQueue *)mainQueue { + static dispatch_once_t onceToken; + static SDCallbackQueue *queue; + dispatch_once(&onceToken, ^{ + queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_main_queue()]; + }); + return queue; +} + ++ (SDCallbackQueue *)currentQueue { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + SDCallbackQueue *queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_current_queue()]; +#pragma clang diagnostic pop + return queue; +} + ++ (SDCallbackQueue *)globalQueue { + SDCallbackQueue *queue = [[SDCallbackQueue alloc] initWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)]; + return queue; +} + +- (void)sync:(nonnull dispatch_block_t)block { + switch (self.policy) { + case SDCallbackPolicySafeExecute: + SDSafeExecute(self, block, NO); + break; + case SDCallbackPolicyDispatch: + dispatch_sync(self.queue, block); + break; + case SDCallbackPolicyInvoke: + block(); + break; + default: + SDSafeExecute(self, block, NO); + break; + } +} + +- (void)async:(nonnull dispatch_block_t)block { + switch (self.policy) { + case SDCallbackPolicySafeExecute: + SDSafeExecute(self, block, YES); + break; + case SDCallbackPolicyDispatch: + dispatch_async(self.queue, block); + break; + case SDCallbackPolicyInvoke: + block(); + break; + default: + SDSafeExecute(self, block, YES); + break; + } +} + +@end diff --git a/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.h b/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.h new file mode 100644 index 00000000..f3801c28 --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.h @@ -0,0 +1,62 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/** + A loading state to manage View Category which contains multiple states. Like UIImgeView.image && UIImageView.highlightedImage + @code + SDWebImageLoadState *loadState = [self sd_imageLoadStateForKey:@keypath(self, highlitedImage)]; + NSProgress *highlitedImageProgress = loadState.progress; + @endcode + */ +@interface SDWebImageLoadState : NSObject + +/** + Image loading URL + */ +@property (nonatomic, strong, nullable) NSURL *url; +/** + Image loading progress. The unit count is the received size and excepted size of download. + */ +@property (nonatomic, strong, nullable) NSProgress *progress; + +@end + +/** + These methods are used for WebCache view which have multiple states for image loading, for example, `UIButton` or `UIImageView.highlightedImage` + It maitain the state container for per-operation, make it possible for control and check each image loading operation's state. + @note For developer who want to add SDWebImage View Category support for their own stateful class, learn more on Wiki. + */ +@interface UIView (WebCacheState) + +/** + Get the image loading state container for specify operation key + + @param key key for identifying the operations + @return The image loading state container + */ +- (nullable SDWebImageLoadState *)sd_imageLoadStateForKey:(nullable NSString *)key; + +/** + Set the image loading state container for specify operation key + + @param state The image loading state container + @param key key for identifying the operations + */ +- (void)sd_setImageLoadState:(nullable SDWebImageLoadState *)state forKey:(nullable NSString *)key; + +/** + Rmove the image loading state container for specify operation key + + @param key key for identifying the operations + */ +- (void)sd_removeImageLoadStateForKey:(nullable NSString *)key; + +@end diff --git a/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.m b/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.m new file mode 100644 index 00000000..7312b985 --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheState.m @@ -0,0 +1,56 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIView+WebCacheState.h" +#import "objc/runtime.h" + +typedef NSMutableDictionary SDStatesDictionary; + +@implementation SDWebImageLoadState + +@end + +@implementation UIView (WebCacheState) + +- (SDStatesDictionary *)sd_imageLoadStateDictionary { + SDStatesDictionary *states = objc_getAssociatedObject(self, @selector(sd_imageLoadStateDictionary)); + if (!states) { + states = [NSMutableDictionary dictionary]; + objc_setAssociatedObject(self, @selector(sd_imageLoadStateDictionary), states, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return states; +} + +- (SDWebImageLoadState *)sd_imageLoadStateForKey:(NSString *)key { + if (!key) { + key = NSStringFromClass(self.class); + } + @synchronized(self) { + return [self.sd_imageLoadStateDictionary objectForKey:key]; + } +} + +- (void)sd_setImageLoadState:(SDWebImageLoadState *)state forKey:(NSString *)key { + if (!key) { + key = NSStringFromClass(self.class); + } + @synchronized(self) { + self.sd_imageLoadStateDictionary[key] = state; + } +} + +- (void)sd_removeImageLoadStateForKey:(NSString *)key { + if (!key) { + key = NSStringFromClass(self.class); + } + @synchronized(self) { + self.sd_imageLoadStateDictionary[key] = nil; + } +} + +@end diff --git a/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.h b/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.h new file mode 100644 index 00000000..6fedc83f --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.h @@ -0,0 +1,40 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" +#import "SDImageCoder.h" + +NS_ASSUME_NONNULL_BEGIN + +/// A per-provider (provider means, AnimatedImage object) based frame pool, each player who use the same provider share the same frame buffer +@interface SDImageFramePool : NSObject + +/// Register and return back a frame pool, also increase reference count ++ (instancetype)registerProvider:(id)provider; +/// Unregister a frame pool, also decrease reference count, if zero dealloc the frame pool ++ (void)unregisterProvider:(id)provider; + +/// Prefetch the current frame, query using `frameAtIndex:` by caller to check whether finished. +- (void)prefetchFrameAtIndex:(NSUInteger)index; + +/// Control the max buffer count for current frame pool, used for RAM/CPU balance, default unlimited +@property (nonatomic, assign) NSUInteger maxBufferCount; +/// Control the max concurrent fetch queue operation count, used for CPU balance, default 1 +@property (nonatomic, assign) NSUInteger maxConcurrentCount; + +// Frame Operations +@property (nonatomic, readonly) NSUInteger currentFrameCount; +- (nullable UIImage *)frameAtIndex:(NSUInteger)index; +- (void)setFrame:(nullable UIImage *)frame atIndex:(NSUInteger)index; +- (void)removeFrameAtIndex:(NSUInteger)index; +- (void)removeAllFrames; + +NS_ASSUME_NONNULL_END + +@end diff --git a/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.m b/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.m new file mode 100644 index 00000000..8e133d22 --- /dev/null +++ b/Pods/SDWebImage/SDWebImage/Private/SDImageFramePool.m @@ -0,0 +1,165 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDImageFramePool.h" +#import "SDInternalMacros.h" +#import "objc/runtime.h" + +@interface SDImageFramePool () + +@property (class, readonly) NSMapTable *providerFramePoolMap; + +@property (weak) id provider; +@property (atomic) NSUInteger registerCount; + +@property (nonatomic, strong) NSMutableDictionary *frameBuffer; +@property (nonatomic, strong) NSOperationQueue *fetchQueue; + +@end + +// Lock to ensure atomic behavior +SD_LOCK_DECLARE_STATIC(_providerFramePoolMapLock); + +@implementation SDImageFramePool + ++ (NSMapTable *)providerFramePoolMap { + static NSMapTable *providerFramePoolMap; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Key use `hash` && `isEqual:` + providerFramePoolMap = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality valueOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPointerPersonality]; + }); + return providerFramePoolMap; +} + +#pragma mark - Life Cycle +- (instancetype)init { + self = [super init]; + if (self) { + _frameBuffer = [NSMutableDictionary dictionary]; + _fetchQueue = [[NSOperationQueue alloc] init]; + _fetchQueue.maxConcurrentOperationCount = 1; + _fetchQueue.name = @"com.hackemist.SDImageFramePool.fetchQueue"; +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (void)dealloc { +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification { + [self removeAllFrames]; +} + ++ (void)initialize { + // Lock to ensure atomic behavior + SD_LOCK_INIT(_providerFramePoolMapLock); +} + ++ (instancetype)registerProvider:(id)provider { + // Lock to ensure atomic behavior + SD_LOCK(_providerFramePoolMapLock); + SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider]; + if (!framePool) { + framePool = [[SDImageFramePool alloc] init]; + framePool.provider = provider; + [self.providerFramePoolMap setObject:framePool forKey:provider]; + } + framePool.registerCount += 1; + SD_UNLOCK(_providerFramePoolMapLock); + return framePool; +} + ++ (void)unregisterProvider:(id)provider { + // Lock to ensure atomic behavior + SD_LOCK(_providerFramePoolMapLock); + SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider]; + if (!framePool) { + SD_UNLOCK(_providerFramePoolMapLock); + return; + } + framePool.registerCount -= 1; + if (framePool.registerCount == 0) { + [self.providerFramePoolMap removeObjectForKey:provider]; + } + SD_UNLOCK(_providerFramePoolMapLock); +} + +- (void)prefetchFrameAtIndex:(NSUInteger)index { + @synchronized (self) { + NSUInteger frameCount = self.frameBuffer.count; + if (frameCount > self.maxBufferCount) { + // Remove the frame buffer if need + // TODO, use LRU or better algorithm to detect which frames to clear + self.frameBuffer[@(index - 1)] = nil; + self.frameBuffer[@(index + 1)] = nil; + } + } + + if (self.fetchQueue.operationCount == 0) { + // Prefetch next frame in background queue + id animatedProvider = self.provider; + @weakify(self); + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + @strongify(self); + if (!self) { + return; + } + UIImage *frame = [animatedProvider animatedImageFrameAtIndex:index]; + + [self setFrame:frame atIndex:index]; + }]; + [self.fetchQueue addOperation:operation]; + } +} + +- (void)setMaxConcurrentCount:(NSUInteger)maxConcurrentCount { + self.fetchQueue.maxConcurrentOperationCount = maxConcurrentCount; +} + +- (NSUInteger)currentFrameCount { + NSUInteger frameCount = 0; + @synchronized (self) { + frameCount = self.frameBuffer.count; + } + return frameCount; +} + +- (void)setFrame:(UIImage *)frame atIndex:(NSUInteger)index { + @synchronized (self) { + self.frameBuffer[@(index)] = frame; + } +} + +- (UIImage *)frameAtIndex:(NSUInteger)index { + UIImage *frame; + @synchronized (self) { + frame = self.frameBuffer[@(index)]; + } + return frame; +} + +- (void)removeFrameAtIndex:(NSUInteger)index { + @synchronized (self) { + self.frameBuffer[@(index)] = nil; + } +} + +- (void)removeAllFrames { + @synchronized (self) { + [self.frameBuffer removeAllObjects]; + } +} + +@end diff --git a/Pods/SDWebImage/WebImage/PrivacyInfo.xcprivacy b/Pods/SDWebImage/WebImage/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..276f7610 --- /dev/null +++ b/Pods/SDWebImage/WebImage/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h b/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h new file mode 100644 index 00000000..0b84c68a --- /dev/null +++ b/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h @@ -0,0 +1,187 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import +#import +#import "SDmetamacros.h" + +#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\ + (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\ + (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\ + (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\ + (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) + +#ifndef SD_LOCK_DECLARE +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock +#else +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ +OSSpinLock lock##_deprecated; +#endif +#endif + +#ifndef SD_LOCK_DECLARE_STATIC +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock +#else +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ +static OSSpinLock lock##_deprecated; +#endif +#endif + +#ifndef SD_LOCK_INIT +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT +#else +#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \ +else lock##_deprecated = OS_SPINLOCK_INIT; +#endif +#endif + +#ifndef SD_LOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK(lock) os_unfair_lock_lock(&lock) +#else +#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \ +else OSSpinLockLock(&lock##_deprecated); +#endif +#endif + +#ifndef SD_UNLOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock) +#else +#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \ +else OSSpinLockUnlock(&lock##_deprecated); +#endif +#endif + +#ifndef SD_OPTIONS_CONTAINS +#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value)) +#endif + +#ifndef SD_CSTRING +#define SD_CSTRING(str) #str +#endif + +#ifndef SD_NSSTRING +#define SD_NSSTRING(str) @(SD_CSTRING(str)) +#endif + +#ifndef SD_SEL_SPI +#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(name)]) +#endif + +#ifndef weakify +#define weakify(...) \ +sd_keywordify \ +metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__) +#endif + +#ifndef strongify +#define strongify(...) \ +sd_keywordify \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Wshadow\"") \ +metamacro_foreach(sd_strongify_,, __VA_ARGS__) \ +_Pragma("clang diagnostic pop") +#endif + +#define sd_weakify_(INDEX, CONTEXT, VAR) \ +CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); + +#define sd_strongify_(INDEX, VAR) \ +__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_); + +#if DEBUG +#define sd_keywordify autoreleasepool {} +#else +#define sd_keywordify try {} @catch (...) {} +#endif + +#ifndef onExit +#define onExit \ +sd_keywordify \ +__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^ +#endif + +typedef void (^sd_cleanupBlock_t)(void); + +#if defined(__cplusplus) +extern "C" { +#endif + void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block); +#if defined(__cplusplus) +} +#endif + +/** + * \@keypath allows compile-time verification of key paths. Given a real object + * receiver and key path: + * + * @code + +NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String); +// => @"lowercaseString.UTF8String" + +NSString *versionPath = @keypath(NSObject, version); +// => @"version" + +NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString); +// => @"lowercaseString" + + * @endcode + * + * ... the macro returns an \c NSString containing all but the first path + * component or argument (e.g., @"lowercaseString.UTF8String", @"version"). + * + * In addition to simply creating a key path, this macro ensures that the key + * path is valid at compile-time (causing a syntax error if not), and supports + * refactoring, such that changing the name of the property will also update any + * uses of \@keypath. + */ +#define keypath(...) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Warc-repeated-use-of-weak\"") \ + (NO).boolValue ? ((NSString * _Nonnull)nil) : ((NSString * _Nonnull)@(cStringKeypath(__VA_ARGS__))) \ + _Pragma("clang diagnostic pop") \ + +#define cStringKeypath(...) \ + metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__)) + +#define keypath1(PATH) \ + (((void)(NO && ((void)PATH, NO)), \ + ({ char *__extobjckeypath__ = strchr(# PATH, '.'); NSCAssert(__extobjckeypath__, @"Provided key path is invalid."); __extobjckeypath__ + 1; }))) + +#define keypath2(OBJ, PATH) \ + (((void)(NO && ((void)OBJ.PATH, NO)), # PATH)) + +/** + * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object + * receiver, collection object receiver and related keypaths: + * + * @code + + NSString *employeesFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName) + // => @"employees.firstName" + + NSString *employeesFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName) + // => @"employees.firstName" + + * @endcode + * + */ +#define collectionKeypath(...) \ + metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__)) + +#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) \ + (YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil + +#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) \ + (YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(OBJ, PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil diff --git a/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h b/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h new file mode 100644 index 00000000..dd90d99b --- /dev/null +++ b/Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h @@ -0,0 +1,667 @@ +/** + * Macros for metaprogramming + * ExtendedC + * + * Copyright (C) 2012 Justin Spahr-Summers + * Released under the MIT license + */ + +#ifndef EXTC_METAMACROS_H +#define EXTC_METAMACROS_H + + +/** + * Executes one or more expressions (which may have a void type, such as a call + * to a function that returns no value) and always returns true. + */ +#define metamacro_exprify(...) \ + ((__VA_ARGS__), true) + +/** + * Returns a string representation of VALUE after full macro expansion. + */ +#define metamacro_stringify(VALUE) \ + metamacro_stringify_(VALUE) + +/** + * Returns A and B concatenated after full macro expansion. + */ +#define metamacro_concat(A, B) \ + metamacro_concat_(A, B) + +/** + * Returns the Nth variadic argument (starting from zero). At least + * N + 1 variadic arguments must be given. N must be between zero and twenty, + * inclusive. + */ +#define metamacro_at(N, ...) \ + metamacro_concat(metamacro_at, N)(__VA_ARGS__) + +/** + * Returns the number of arguments (up to twenty) provided to the macro. At + * least one argument must be provided. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_argcount(...) \ + metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +/** + * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is + * given. Only the index and current argument will thus be passed to MACRO. + */ +#define metamacro_foreach(MACRO, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) + +/** + * For each consecutive variadic argument (up to twenty), MACRO is passed the + * zero-based index of the current argument, CONTEXT, and then the argument + * itself. The results of adjoining invocations of MACRO are then separated by + * SEP. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * Identical to #metamacro_foreach_cxt. This can be used when the former would + * fail due to recursive macro expansion. + */ +#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * In consecutive order, appends each variadic argument (up to twenty) onto + * BASE. The resulting concatenations are then separated by SEP. + * + * This is primarily useful to manipulate a list of macro invocations into instead + * invoking a different, possibly related macro. + */ +#define metamacro_foreach_concat(BASE, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) + +/** + * Iterates COUNT times, each time invoking MACRO with the current index + * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO + * are then separated by SEP. + * + * COUNT must be an integer between zero and twenty, inclusive. + */ +#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ + metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) + +/** + * Returns the first argument given. At least one argument must be provided. + * + * This is useful when implementing a variadic macro, where you may have only + * one variadic argument, but no way to retrieve it (for example, because \c ... + * always needs to match at least one argument). + * + * @code + +#define varmacro(...) \ + metamacro_head(__VA_ARGS__) + + * @endcode + */ +#define metamacro_head(...) \ + metamacro_head_(__VA_ARGS__, 0) + +/** + * Returns every argument except the first. At least two arguments must be + * provided. + */ +#define metamacro_tail(...) \ + metamacro_tail_(__VA_ARGS__) + +/** + * Returns the first N (up to twenty) variadic arguments as a new argument list. + * At least N variadic arguments must be provided. + */ +#define metamacro_take(N, ...) \ + metamacro_concat(metamacro_take, N)(__VA_ARGS__) + +/** + * Removes the first N (up to twenty) variadic arguments from the given argument + * list. At least N variadic arguments must be provided. + */ +#define metamacro_drop(N, ...) \ + metamacro_concat(metamacro_drop, N)(__VA_ARGS__) + +/** + * Decrements VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_dec(VAL) \ + metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) + +/** + * Increments VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_inc(VAL) \ + metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + +/** + * If A is equal to B, the next argument list is expanded; otherwise, the + * argument list after that is expanded. A and B must be numbers between zero + * and twenty, inclusive. Additionally, B must be greater than or equal to A. + * + * @code + +// expands to true +metamacro_if_eq(0, 0)(true)(false) + +// expands to false +metamacro_if_eq(0, 1)(true)(false) + + * @endcode + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_if_eq(A, B) \ + metamacro_concat(metamacro_if_eq, A)(B) + +/** + * Identical to #metamacro_if_eq. This can be used when the former would fail + * due to recursive macro expansion. + */ +#define metamacro_if_eq_recursive(A, B) \ + metamacro_concat(metamacro_if_eq_recursive, A)(B) + +/** + * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and + * twenty, inclusive. + * + * For the purposes of this test, zero is considered even. + */ +#define metamacro_is_even(N) \ + metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) + +/** + * Returns the logical NOT of B, which must be the number zero or one. + */ +#define metamacro_not(B) \ + metamacro_at(B, 1, 0) + +// IMPLEMENTATION DETAILS FOLLOW! +// Do not write code that depends on anything below this line. +#define metamacro_stringify_(VALUE) # VALUE +#define metamacro_concat_(A, B) A ## B +#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) +#define metamacro_head_(FIRST, ...) FIRST +#define metamacro_tail_(FIRST, ...) __VA_ARGS__ +#define metamacro_consume_(...) +#define metamacro_expand_(...) __VA_ARGS__ + +// implemented from scratch so that metamacro_concat() doesn't end up nesting +#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) +#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG + +// metamacro_at expansions +#define metamacro_at0(...) metamacro_head(__VA_ARGS__) +#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) + +// metamacro_foreach_cxt expansions +#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_foreach_cxt_recursive expansions +#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_for_cxt expansions +#define metamacro_for_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) + +#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(1, CONTEXT) + +#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(2, CONTEXT) + +#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(3, CONTEXT) + +#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(4, CONTEXT) + +#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(5, CONTEXT) + +#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(6, CONTEXT) + +#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(7, CONTEXT) + +#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(8, CONTEXT) + +#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(9, CONTEXT) + +#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(10, CONTEXT) + +#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(11, CONTEXT) + +#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(12, CONTEXT) + +#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(13, CONTEXT) + +#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(14, CONTEXT) + +#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(15, CONTEXT) + +#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(16, CONTEXT) + +#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(17, CONTEXT) + +#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(18, CONTEXT) + +#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(19, CONTEXT) + +// metamacro_if_eq expansions +#define metamacro_if_eq0(VALUE) \ + metamacro_concat(metamacro_if_eq0_, VALUE) + +#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq0_1(...) metamacro_expand_ +#define metamacro_if_eq0_2(...) metamacro_expand_ +#define metamacro_if_eq0_3(...) metamacro_expand_ +#define metamacro_if_eq0_4(...) metamacro_expand_ +#define metamacro_if_eq0_5(...) metamacro_expand_ +#define metamacro_if_eq0_6(...) metamacro_expand_ +#define metamacro_if_eq0_7(...) metamacro_expand_ +#define metamacro_if_eq0_8(...) metamacro_expand_ +#define metamacro_if_eq0_9(...) metamacro_expand_ +#define metamacro_if_eq0_10(...) metamacro_expand_ +#define metamacro_if_eq0_11(...) metamacro_expand_ +#define metamacro_if_eq0_12(...) metamacro_expand_ +#define metamacro_if_eq0_13(...) metamacro_expand_ +#define metamacro_if_eq0_14(...) metamacro_expand_ +#define metamacro_if_eq0_15(...) metamacro_expand_ +#define metamacro_if_eq0_16(...) metamacro_expand_ +#define metamacro_if_eq0_17(...) metamacro_expand_ +#define metamacro_if_eq0_18(...) metamacro_expand_ +#define metamacro_if_eq0_19(...) metamacro_expand_ +#define metamacro_if_eq0_20(...) metamacro_expand_ + +#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) +#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) +#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) +#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) +#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) +#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) +#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) +#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) +#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) +#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) +#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) +#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) +#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) +#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) +#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) +#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) +#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) +#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) +#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) +#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) + +// metamacro_if_eq_recursive expansions +#define metamacro_if_eq_recursive0(VALUE) \ + metamacro_concat(metamacro_if_eq_recursive0_, VALUE) + +#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq_recursive0_1(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_2(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_3(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_4(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_5(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_6(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_7(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_8(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_9(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_10(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_11(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_12(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_13(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_14(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_15(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_16(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_17(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_18(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_19(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_20(...) metamacro_expand_ + +#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) + +// metamacro_take expansions +#define metamacro_take0(...) +#define metamacro_take1(...) metamacro_head(__VA_ARGS__) +#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) +#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) +#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) +#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) +#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) +#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) +#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) +#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) +#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) +#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) +#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) +#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) +#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) +#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) +#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) +#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) +#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) +#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) +#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) + +// metamacro_drop expansions +#define metamacro_drop0(...) __VA_ARGS__ +#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) +#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) + +#endif diff --git a/Pods/SwiftFormat/CommandLineTool/swiftformat b/Pods/SwiftFormat/CommandLineTool/swiftformat new file mode 100755 index 00000000..0e12ea1b Binary files /dev/null and b/Pods/SwiftFormat/CommandLineTool/swiftformat differ diff --git a/Pods/SwiftFormat/LICENSE.md b/Pods/SwiftFormat/LICENSE.md new file mode 100755 index 00000000..6fc7a2ce --- /dev/null +++ b/Pods/SwiftFormat/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Nick Lockwood + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/SwiftFormat/README.md b/Pods/SwiftFormat/README.md new file mode 100644 index 00000000..fd0e140f --- /dev/null +++ b/Pods/SwiftFormat/README.md @@ -0,0 +1,1012 @@ +![](EditorExtension/Application/Assets.xcassets/AppIcon.appiconset/icon_256x256.png) + +[![PayPal](https://img.shields.io/badge/paypal-donate-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9ZGWNK5FEZFF6&source=url) +[![Build](https://github.com/nicklockwood/SwiftFormat/actions/workflows/build.yml/badge.svg)](https://github.com/nicklockwood/SwiftFormat/actions/workflows/build.yml) +[![Codecov](https://codecov.io/gh/nicklockwood/SwiftFormat/graphs/badge.svg)](https://codecov.io/gh/nicklockwood/SwiftFormat) +[![Swift 5.3](https://img.shields.io/badge/swift-5.1-red.svg?style=flat)](https://developer.apple.com/swift) +[![License](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://opensource.org/licenses/MIT) +[![Mastodon](https://img.shields.io/badge/mastodon-@nicklockwood@mastodon.social-636dff.svg)](https://mastodon.social/@nicklockwood) + +Table of Contents +----------------- + +- [What?](#what-is-this) +- [Why?](#why-would-i-want-to-do-that) +- [How?](#how-do-i-install-it) + - [Command-line tool](#command-line-tool) + - [Xcode source editor extension](#xcode-source-editor-extension) + - [Xcode build phase](#xcode-build-phase) + - [Swift Package Manager plugin](#swift-package-manager-plugin) + - [Via Applescript](#via-applescript) + - [VSCode plugin](#vscode-plugin) + - [Sublime Text plugin](#sublime-text-plugin) + - [Nova plugin](nova-plugin) + - [Git pre-commit hook](#git-pre-commit-hook) + - [GitHub Actions](#github-actions) + - [On CI using Danger](#on-ci-using-danger) + - [Bazel build](#bazel-build) + - [Docker](#docker) +- [Configuration](#configuration) + - [Options](#options) + - [Rules](#rules) + - [Swift version](#swift-version) + - [Config file](#config-file) + - [Globs](#globs) + - [Linting](#linting) + - [Error codes](#error-codes) + - [Cache](#cache) + - [File headers](#file-headers) +- [FAQ](#faq) +- [Known issues](#known-issues) +- [Tip Jar](#tip-jar) +- [Credits](#credits) + + +What is this? +---------------- + +SwiftFormat is a code library and command-line tool for reformatting Swift code on macOS, Linux or Windows. + +SwiftFormat goes above and beyond what you might expect from a code formatter. In addition to adjusting white space it can insert or remove implicit `self`, remove redundant parentheses, and correct many other deviations from the standard Swift idioms. + + +Why would I want to do that? +----------------------------- + +Many programmers have a preferred style for formatting their code, and others seem entirely blind to the existing formatting conventions of a project (to the enragement of their colleagues). + +When collaborating on a project, it can be helpful to agree on a common coding style, but enforcing that manually is tedious and error-prone, and can lead to arguments if some participants take it more seriously than others. + +Having a tool to automatically enforce a common style eliminates those issues, and lets you focus on the behavior of the code, not its presentation. + + +How do I install it? +--------------------- + +That depends - There are several ways you can use SwiftFormat: + +1. As a command-line tool that you run manually, or as part of some other toolchain +2. As a Source Editor Extension that you can invoke via the Editor > SwiftFormat menu within Xcode +3. As a build phase in your Xcode project, so that it runs every time you press Cmd-R or Cmd-B, or +4. As a Git pre-commit hook, so that it runs on any files you've changed before you check them in + + +Command-line tool +------------------- + +**NOTE:** if you are using any of the following methods to install SwiftFormat on macOS 10.14.3 or earlier and are experiencing a crash on launch, you may need to install the [Swift 5 Runtime Support for Command Line Tools](https://support.apple.com/kb/DL1998). See [known issues](#known-issues) for details. + +**Installation:** + +You can install the `swiftformat` command-line tool on macOS or Linux using [Homebrew](http://brew.sh/). Assuming you already have Homebrew installed, just type: + +```bash +$ brew install swiftformat +``` + +To update to the latest version once installed: + +```bash +$ brew upgrade swiftformat +``` + +Alternatively, you can install the tool on macOS or Linux by using [Mint](https://github.com/yonaskolb/Mint) as follows: + +```bash +$ mint install nicklockwood/SwiftFormat +``` + +Or if you prefer, you can check out and build SwiftFormat manually on macOS, Linux or Windows as follows: + +```bash +$ git clone https://github.com/nicklockwood/SwiftFormat +$ cd SwiftFormat +$ swift build -c release +``` + +If you are installing SwiftFormat into your project directory, you can use [CocoaPods](https://cocoapods.org/) on macOS to automatically install the swiftformat binary along with your other pods - see the Xcode build phase instructions below for details. + +Another option is to include the binary artifactbundle in your `Package.swift`: + +```swift +.binaryTarget( + name: "swiftformat", + url: "https://github.com/nicklockwood/SwiftFormat/releases/download/0.55.0/swiftformat-macos.artifactbundle.zip", + checksum: "CHECKSUM" +), +``` + +If you would prefer not to use a package manager, you can build the command-line app manually: + +1. open `SwiftFormat.xcodeproj` and build the `SwiftFormat (Application)` scheme. + +2. Drag the `swiftformat` binary into `/usr/local/bin/` (this is a hidden folder, but you can use the Finder's `Go > Go to Folder...` menu to open it). + +3. Open `~/.bash_profile` in your favorite text editor (this is a hidden file, but you can type `open ~/.bash_profile` in the terminal to open it). + +4. Add the following line to the file: `alias swiftformat="/usr/local/bin/swiftformat --indent 4"` (you can omit the `--indent 4`, or replace it with something else. Run `swiftformat --help` to see the available options). + +5. Save the `.bash_profile` file and run the command `source ~/.bash_profile` for the changes to take effect. + +**Usage:** + +If you followed the installation instructions above, you can now just type + +```bash +$ swiftformat . +``` + +(that's a space and then a period after the command) in the terminal to format any Swift files in the current directory. In place of the `.`, you can instead type an absolute or relative path to the file or directory that you want to format. + +**WARNING:** `swiftformat .` will overwrite any Swift files it finds in the current directory, and any subfolders therein. If you run it in your home directory, it will probably reformat every Swift file on your hard drive. + +To use it safely, do the following: + +1. Choose a file or directory that you want to apply the changes to. + +2. Make sure that you have committed all your changes to that code safely in git (or whatever source control system you use). + +3. (Optional) In Terminal, type `swiftformat --inferoptions "/path/to/your/code/"`. This will suggest a set of formatting options to use that match your existing project style (but you are free to ignore these and use the defaults, or your own settings if you prefer). + + The path can point to either a single Swift file or a directory of files. It can be either be absolute, or relative to the current directory. The `""` quotes around the path are optional, but if the path contains spaces then you either need to use quotes, or escape each space with `\`. You may include multiple paths separated by spaces. + +4. In Terminal, type `swiftformat "/path/to/your/code/"`. The same rules apply as above with respect to paths, and multiple space-delimited paths are allowed. + + If you used `--inferoptions` to generate a suggested set of options in step 3, you should copy and paste them into the command, either before or after the path(s) to your source files. + + If you have created a [config file](#config-file), you can specify its path using `--config "/path/to/your/config-file/"`. Alternatively, if you name the file `.swiftformat` and place it inside the project you are formatting, it will be picked up automatically. + +5. Press enter to begin formatting. Once the formatting is complete, use your source control system to check the changes, and verify that no undesirable changes have been introduced. If they have, revert the changes, tweak the options and try again. + +6. (Optional) commit the changes. + +Following these instructions *should* ensure that you avoid catastrophic data loss, but in the unlikely event that it wipes your hard drive, **please note that I accept no responsibility**. + +**Using Standard Input/Output:** + +If you prefer, you can use unix pipes to include SwiftFormat as part of a command chain. For example, this is an alternative way to format a file: + +```bash +$ cat /path/to/file.swift | swiftformat --output /path/to/file.swift +``` + +Omitting the `--output /path/to/file.swift` will print the formatted file to Standard Output (stdout). You can also pass "stdout" explicitly as the output path: + +```bash +$ cat /path/to/file.swift | swiftformat --output stdout +``` + +Or you can use `>` to specify the output path as follows: + +```bash +$ cat /path/to/file.swift | swiftformat > /path/to/file.swift +``` + +If you do not supply an input file, SwiftFormat will automatically take its input from Standard Input (stdin), but will time-out if no input is received immediately and display the help screen. To make it explicit, pass "stdin" as the input path: + +```bash +$ cat /path/to/file.swift | swiftformat stdin +``` + +When using stdin, SwiftFormat does not have access to the file path of the input, so features that rely on the file location (such as inserting the creation date into header comments, or detecting `.swiftformat` configuration files in the file path) will not work. To solve this, you can provide the file path using the `--stdinpath` argument: + +```bash +$ cat /path/to/file.swift | swiftformat stdin --stdinpath /path/to/file.swift +``` + + +Xcode source editor extension +----------------------------- + +**Installation:** + +Like the command-line tool, you can install the SwiftFormat for Xcode extension application via [Homebrew](http://brew.sh/). Assuming you already have Homebrew installed, type: + +```bash +$ brew install --cask swiftformat-for-xcode +``` + +This will install SwiftFormat for Xcode in your Applications folder. Double-click the app to launch it, and then follow the on-screen instructions. + +**NOTE:** The app should be correctly signed, but if you get a Gatekeeper warning when trying to open it you can bypass this by right-clicking (or control-clicking) the app and selecting `Open`. + +To update to the latest version once installed use: + +```bash +$ brew upgrade --cask swiftformat-for-xcode +``` + +Alternatively, if you prefer not to use Homebrew, you'll find the latest version of the SwiftFormat for Xcode application on the [GitHub Releases](https://github.com/nicklockwood/SwiftFormat/releases) page. Download and unpack the zip archive, then drag `SwiftFormat for Xcode.app` into your `Applications` folder. + +**Usage:** + +Once you have launched the app and restarted Xcode, you'll find a SwiftFormat option under Xcode's Editor menu. If the SwiftFormat menu does not appear [this thread](https://github.com/nicklockwood/SwiftFormat/issues/494) may help. + +You can configure the formatting [rules](#rules) and [options](#options) using the SwiftFormat for Xcode host application. There is currently no way to override these per-project, however, you can import and export different configurations using the File menu. You will need to do this again each time you switch projects. + +The format of the configuration file is described in the [Config section](#config-file) below. + +**Note:** SwiftFormat for Xcode cannot automatically detect changes to an imported configuration file. If you update the `.swiftformat` file for your project, you will need to manually re-import that file into SwiftFormat for Xcode in order for the Xcode source editor extension to use the new configuration. + + +Xcode build phase +------------------- + +**NOTE:** Adding this script will overwrite your source files as you work on them, which has the annoying side-effect of clearing the undo history. You may wish to add the script to your test target rather than your main target, so that it is invoked only when you run the unit tests, and not every time you build the app. + +Alternatively, you might want to consider running SwiftFormat in [lint](#linting) mode as part of your normal build, and then running a formatting pass manually, or as part of a less-frequent build target (such as the tests). + +### Using Swift Package Manager + +To set up SwiftFormat as an Xcode build phase, do the following: + +#### 1) Create a BuildTools folder and Package.swift + +1. Create a folder called `BuildTools` in the same folder as your xcodeproj file +2. In this folder, create a file called `Package.swift`, with the following contents: +```swift +// swift-tools-version:5.1 +import PackageDescription + +let package = Package( + name: "BuildTools", + platforms: [.macOS(.v10_11)], + dependencies: [ + .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.55.0"), + ], + targets: [.target(name: "BuildTools", path: "")] +) +``` +3. If you are running Xcode 11.4 or later, in the `BuildTools` folder create a file called `Empty.swift` with nothing in it. This is to satisfy a change in Swift Package Manager. + +#### 2) Add a Build phase to your app target + +1. Click on your project in the file list, choose your target under `TARGETS`, click the `Build Phases` tab +2. Add a `New Run Script Phase` by clicking the little plus icon in the top left +3. Uncheck the `Based on dependency analysis` checkbox +4. Drag the new `Run Script` phase **above** the `Compile Sources` phase, expand it and paste the following script: + + ```bash + cd BuildTools + SDKROOT=(xcrun --sdk macosx --show-sdk-path) + #swift package update #Uncomment this line temporarily to update the version used to the latest matching your BuildTools/Package.swift file + swift run -c release swiftformat "$SRCROOT" + ``` + +You can also use `swift run -c release --package-path BuildTools swiftformat "$SRCROOT"` if you need a more complex script and `cd BuildTools` breaks stuff. + +**NOTE:** You may wish to check BuildTools/Package.swift into your source control so that the version used by your run-script phase is kept in version control. It is recommended to add the following to your .gitignore file: `BuildTools/.build` and `BuildTools/.swiftpm`. + +**NOTE (2):** If you are using Xcode 15 or later, make sure that the `ENABLE_USER_SCRIPT_SANDBOXING` (aka "User Script Sandboxing") option is set to NO, otherwise SwiftFormat won't be able to run correctly. + +### Using CocoaPods + +#### 1) Add the SwiftFormat CLI to your Podfile + +1. Add the `swiftformat` binary to your project directory via [CocoaPods](https://cocoapods.org/), by adding the following line to your Podfile then running `pod install`: + + ```ruby + pod 'SwiftFormat/CLI', '~> 0.55' + ``` + +**NOTE:** This will only install the pre-built command-line app, not the source code for the SwiftFormat framework. + +**NOTE (2):** When installing this way, GateKeeper may block swiftformat from running until you open it manually the first time by right-clicking in the Finder and selecting "Open". + +#### 2) Add a Build phase to your app target + +1. Click on your project in the file list, choose your target under `TARGETS`, click the `Build Phases` tab +2. Add a `New Run Script Phase` by clicking the little plus icon in the top left +3. Uncheck the `Based on dependency analysis` checkbox +4. Drag the new `Run Script` phase **above** the `Compile Sources` phase, expand it and paste the following script: + + ```bash + "${PODS_ROOT}/SwiftFormat/CommandLineTool/swiftformat" "$SRCROOT" + ``` + +### Alternative: Locally installed SwiftFormat + +Alternatively, you could use a locally installed swiftformat command-line tool instead by putting the following in your Run Script build phase: + +```bash +if which swiftformat >/dev/null; then + swiftformat . +else + echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat" +fi +``` + +This is not recommended for shared projects however, as different team members using different versions of SwiftFormat may result in noise in the commit history as code gets reformatted inconsistently. + +If you installed SwiftFormat via Homebrew on Apple Silicon, you might experience this warning: + +> warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat + +That is because Homebrew on Apple Silicon installs the binaries into the `/opt/homebrew/bin` +folder by default. To instruct Xcode where to find SwiftFormat, you can either add +`/opt/homebrew/bin` to the `PATH` environment variable in your build phase + +```bash +if [[ "$(uname -m)" == arm64 ]]; then + export PATH="/opt/homebrew/bin:$PATH" +fi + +if which swiftformat > /dev/null; then + swiftformat . +else + echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat" +fi +``` + +or you can create a symbolic link in `/usr/local/bin` pointing to the actual binary: + +```bash +ln -s /opt/homebrew/bin/swiftformat /usr/local/bin/swiftformat +``` + +Swift Package Manager plugin +----------------------------- + +You can use `SwiftFormat` as a SwiftPM command plugin. + +**NOTE:** Swift 5.6 or higher is required. Add the package to your dependencies in your `Package.swift` file. + +```swift +dependencies: [ + // ... + .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.55.0"), +] +``` + +The plugin will find an existing `.swiftformat` in your package root folder and honor it automatically. + +### Trigger Plugin From Command-Line + +```bash +swift package plugin --allow-writing-to-package-directory swiftformat +``` + +You can limit the formatting to a particular target with `--target` option. + +You can also specify `SwiftFormat` arguments, e.g. `--swiftversion`. + +Example + +```bash +swift package plugin --allow-writing-to-package-directory swiftformat --target MyLibrary --swiftversion 5.6 --verbose +``` + +### Trigger Plugin From Xcode + +In Xcode 14 you can trigger the command plugin execution for a Swift package or an Xcode project. + +For an Xcode project the project's main directory will be processed and the `--target` option will be ignored. + +You can also specify `SwiftFormat` arguments, e.g. `--swiftversion`. + +![Run plugin in Xcode 14](https://user-images.githubusercontent.com/4176826/179352584-db7f7f42-452c-4a42-a329-01b115a237a7.gif) + +Via AppleScript +---------------- + +To run SwiftFormat on the frontmost Xcode document (project or workspace) you can use the following AppleScript: + +```applescript +tell application "Xcode" + set frontWindow to the first window + set myPath to path of document of frontWindow + do shell script "cd " & myPath & ";cd ..; /usr/local/bin/swiftformat ." +end tell +``` + +Some Apps you can trigger this from are [BetterTouchTool](https://folivora.ai), [Alfred](https://www.alfredapp.com) or [Keyboard Maestro](https://www.keyboardmaestro.com/main/). Another option is to define a QuickAction for Xcode via Automator and then assign a keyboard shortcut for it in the System Preferences. + + +VSCode plugin +-------------- + +If you prefer to use Microsoft's [VSCode](https://code.visualstudio.com) editor for writing Swift, [Valentin Knabel](https://github.com/vknabel) has created a [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swiftformat) for SwiftFormat. + + +Sublime Text plugin +-------------------- + +If you prefer to use the [Sublime Text](https://www.sublimetext.com) editor, try the [Sublime-Swift-Format plugin](https://github.com/aerobounce/Sublime-Swift-Format) by [Aerobounce](https://github.com/aerobounce). + + +Nova plugin +----------- + +If you prefer to use the [Nova](https://panic.com/nova) editor, try the [SwiftFormat extension](https://extensions.panic.com/extensions/org.padraig/org.padraig.SwiftFormat/) by [Pádraig Ó Cinnéide](https://mastodon.social/@PadraigOCinneide). + + +Git pre-commit hook +--------------------- + +1. Follow the instructions for installing the SwiftFormat command-line tool. + +2. Install [git-format-staged](https://github.com/hallettj/git-format-staged). + +3. Edit or create a `.git/hooks/pre-commit` file in your project folder. The .git folder is hidden but should already exist if you are using Git with your project, so open it with the terminal, or the Finder's `Go > Go to Folder...` menu. + +4. Add the following line in the pre-commit file. The `{}` will be replaced automatically by the path to the Swift file being formatted: + + ```bash + #!/bin/bash + git-format-staged --formatter "swiftformat stdin --stdinpath '{}'" "*.swift" + ``` + + (Note that this example uses your locally installed version of SwiftFormat, not a separate copy in your project repository. You can replace `swiftformat` with the path to a copy inside your project if you prefer.) + +5. enable the hook by typing `chmod +x .git/hooks/pre-commit` in the terminal. + +The pre-commit hook will now run whenever you run `git commit`. Running `git commit --no-verify` will skip the pre-commit hook. + +**NOTE:** If you are using Git via a GUI client such as [Tower](https://www.git-tower.com), [additional steps](https://www.git-tower.com/help/mac/faq-and-tips/faq/hook-scripts) may be needed. + +**NOTE (2):** Unlike the Xcode build phase approach, git pre-commit hook won't be checked in to source control, and there's no way to guarantee that all users of the project are using the same version of SwiftFormat. For a collaborative project, you might want to consider a *post*-commit hook instead, which would run on your continuous integration server. + +GitHub Actions +--------------------- + +1. SwiftFormat comes preinstalled on all macOS GitHub-hosted runners. If you are self hosting you will need to ensure SwiftFormat is installed on your runner. +2. Create a GitHub Actions workflow using SwiftFormat, passing the `--reporter github-actions-log` command line option. The following example action lints pull requests using SwiftFormat, reporting warnings using the GitHub Actions log. +```yaml +# Lint.yml +name: Lint +on: pull_request + +jobs: + Lint: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: SwiftFormat + run: swiftformat --lint . --reporter github-actions-log +``` + +On CI using Danger +------------------- + +To setup SwiftFormat to be used by your continuous integration system using [Danger](http://danger.systems/ruby/), do the following: + +1. Follow the [`instructions`](http://danger.systems/guides/getting_started.html) to setup Danger. +2. Add the [`danger-swiftformat`](https://github.com/garriguv/danger-ruby-swiftformat) plugin to your `Gemfile`. +3. Add the following to your `Dangerfile`: + + ```ruby + swiftformat.binary_path = "/path/to/swiftformat" # optional + swiftformat.additional_args = "--indent tab --self insert" # optional + swiftformat.check_format(fail_on_error: true) + ``` + + **NOTE:** It is recommended to add the `swiftformat` binary to your project directory to ensure the same version is used each time (see the [Xcode build phase](#xcode-build-phase) instructions above). + + +Bazel Build +----------- + +If you use [Bazel](https://bazel.build/) to build your Swift projects and want to ensure that only properly formatted code is merged to your main branch, try [rules_swiftformat](https://github.com/cgrindel/rules_swiftformat). The repository contains Bazel rules and macros that format Swift source files using SwiftFormat, test that the formatted files exist in the workspace directory, and copy the formatted files to the workspace directory. + + +Docker +----------- + +SwiftFormat publishes releases into [GitHub Packages](https://github.com/features/packages) Docker registry. To pull the image call: + +```bash +$ docker pull ghcr.io/nicklockwood/swiftformat:latest +``` + +By default, the container runs `swiftformat .` Therefore, you need to provide a path either via an argument: + +```bash +docker run --rm -v /local/source/path:/work ghcr.io/nicklockwood/swiftformat:latest /work +``` + +or by changing the working dir: + +```bash +docker run --rm -v /local/source/path:/work -w /work ghcr.io/nicklockwood/swiftformat:latest +``` + +To check the installed SwiftFormat version: + +```bash +docker run --rm ghcr.io/nicklockwood/swiftformat:latest --version +``` + +Linting example: + +```bash +docker run --rm -v /local/source/path:/work ghcr.io/nicklockwood/swiftformat:latest /work --lint +``` + +Configuration +------------- + +SwiftFormat's configuration is split between **rules** and **options**. Rules are functions in the SwiftFormat library that apply changes to the code. Options are settings that control the behavior of the rules. + + +Options +------- + +The options available in SwiftFormat can be displayed using the `--options` command-line argument. The default value for each option is indicated in the help text. + +Rules are configured by adding `--[option_name] [value]` to your command-line arguments, or by creating a `.swiftformat` [config file](#config-file) and placing it in your project directory. + +A given option may affect multiple rules. Use `--ruleinfo [rule_name]` command for details about which options affect a given rule, or see the [Rules.md](https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md) file. + +You can configure options for specific files or code ranges by using `swiftformat:options` directive in comments inside your Swift file. To temporarily set one or more options inside a source file, use: + +```swift +// swiftformat:options --indent 2 --allman true +``` + +To apply an options override only to a particular line, use the `:next` modifier: + +```swift +// swiftformat:options:next --semicolons inline +doTheThing(); print("Did the thing") +``` + + +Rules +----- + +SwiftFormat includes over 50 rules, and new ones are added all the time. An up-to-date list can be found in [Rules.md](https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md) along with documentation for how they are used. + +The list of available rules can be displayed within the command-line app using the `--rules` argument. Rules can be either enabled or disabled. Most are enabled by default. Disabled rules are marked with "(disabled)" when displayed using `--rules`. + +You can use the `--ruleinfo [rule_name]` command to get information about a specific rule. Pass a comma-delimited list of rule names to get information for multiple rules at once, or use `--ruleinfo` with no argument for info on all rules. + +You can disable rules individually using `--disable` followed by a list of one or more comma-delimited rule names, or enable opt-in rules using `--enable` followed by the rule names: + +```bash +--disable redundantSelf,trailingClosures +--enable isEmpty +``` + +If you prefer, you can use multiple `--enable`/`--disable` arguments instead of using commas: + +```bash +--disable indent +--disable linebreaks +--disable redundantSelf +``` + +Alternatively, you can use the line continuation character `\` to wrap a single argument over multiple line: + +```bash +--disable \ + indent, \ + linebreaks, \ + redundantSelf +``` + +To avoid automatically opting-in to new rules when SwiftFormat is updated, you can disable all rules using: + +```bash +--disable all +``` + +And then individually enable just the rules you want. Alternatively, use the`--rules` argument to *only* enable the rules you specify: + +```bash +--rules indent,linebreaks +``` + +As above, you may include multiple `--rules` arguments, or use the line continuation character `\` to wrap the rules onto separate lines: + +```bash +--rules redundantSelf +--rules \ + indent, \ + linebreaks +``` + +To see exactly which rules were applied to a given file, you can use the `--verbose` command-line option to force SwiftFormat to print a more detailed log as it applies the formatting. **NOTE:** running in verbose mode is slower than the default mode. + +You can disable rules for specific files or code ranges by using `swiftformat:` directives in comments inside your Swift file. To temporarily disable one or more rules inside a source file, use: + +```swift +// swiftformat:disable [ [rule<3> ...]] +``` + +To enable the rule(s) again, use: + +```swift +// swiftformat:enable [ [rule<3> ...]] +``` + +To disable all rules use: + +```swift +// swiftformat:disable all +``` + +And to enable them all again, use: + +```swift +// swiftformat:enable all +``` + +To temporarily prevent one or more rules being applied to just the next line, use: + +```swift +// swiftformat:disable:next [ [rule<3> ...]] +let foo = bar // rule(s) will be disabled for this line +let bar = baz // rule(s) will be re-enabled for this line +``` + +There is no need to manually re-enable a rule after using the `next` directive. + +**NOTE:** The `swiftformat:enable` directive only serves to counter a previous `swiftformat:disable` directive in the same file. It is not possible to use `swiftformat:enable` to enable a rule that was not already enabled when formatting started. + + +Swift version +------------- + +Most SwiftFormat rules are version-agnostic, but some are applicable only to newer Swift versions. These rules will be disabled automatically if the Swift version is not specified, so to make sure that the full functionality is available you should specify the version of Swift that is used by your project. + +You can specify the Swift compiler version in one of two ways: + +You can specify your project's Swift compiler version using the `--swiftversion` command line argument. You can also add the `--swiftversion` option to your `.swiftformat` file. + +Another option is to add a `.swift-version` file to your project directory. This is a text file that should contain the minimum Swift version supported by your project, and is also supported by some other tools. The `--swiftversion` argument takes precedence over any `.swift-version` files. + +Both the `.swift-version` file and the `--swiftversion` option in a `.swiftformat` file are applied hierarchically; If you have submodules in your project that use a different Swift version, you can add separate swift version configurations for those directories. + +Swift language mode +------------------- + +SwiftFormat also allows you to specify the Swift _language mode_ used by your project. This is distinct from the Swift compiler version. For example, you can use the Swift 6.0 compiler with either the Swift 5 language mode or the Swift 6 language mode. Some SwiftFormat rules will behave differently under different Swift language modes. + +You can specify your project's Swift language mode using the `--languagemode` command line argument. You can also add the `--languagemode` option to your `.swiftformat` file. + +If not specified, SwiftFormat uses the default language mode of the specified Swift compiler version. The default language mode in Swift 5.x and Swift 6.x is the Swift 5 language mode. If your project uses the Swift 6 language mode, you should specify `--languagemode 6`. + + +Config file +----------- + +Although it is possible to configure SwiftFormat directly by using the command-line [options](#options) and [rules](#rules) detailed above, it is sometimes more convenient to create a configuration file, which can be added to your project and shared with other developers. + +A SwiftFormat configuration file consists of one or more command-line options, split onto separate lines, e.g: + +``` +--allman true +--indent tab +--disable elseOnSameLine,semicolons +``` + +While formatting, SwiftFormat will automatically check inside each subdirectory for the presence of a `.swiftformat` file and will apply any options that it finds there to the files in that directory. + +This allows you to override certain rules or formatting options just for a particular directory of files. You can also specify excluded files relative to that directory using `--exclude`, which may be more convenient than specifying them at the top-level: + +``` +--exclude Pods,Generated +``` + +The `--exclude` option takes a comma-delimited list of file or directory paths to exclude from formatting. Excluded paths are relative to the config file containing the `--exclude` command. The excluded paths can include wildcards, specified using Unix "Glob" syntax, as [documented below](#globs). + +Config files named ".swiftformat" will be processed automatically, however, you can select an additional configuration file to use for formatting using the `--config "path/to/config/file"` command-line argument. A configuration file selected using `--config` does not need to be named ".swiftformat", and can be located outside of the project directory. + +The config file format is designed to be edited by hand. You may include blank lines for readability, and can also add comments using a hash prefix (#), e.g. + +``` +# format options +--allman true +--indent tab # tabs FTW! + +# file options +--exclude Pods + +# rules +--disable elseOnSameLine,semicolons +``` + +If you would prefer not to edit the configuration file by hand, you can use the [SwiftFormat for Xcode](#xcode-source-editor-extension) app to edit the configuration and export a configuration file. You can also use the swiftformat command-line-tool's `--inferoptions` command to generate a config file from your existing project, like this: + +```bash +$ cd /path/to/project +$ swiftformat --inferoptions . --output .swiftformat +``` + +Globs +----- + +When excluding files from formatting using the `--exclude` option, you may wish to make use of wildcard paths (aka "Globs") to match all files that match a particular naming convention without having to manually list them all. + +SwiftFormat's glob syntax is based on Ruby's implementation, which varies slightly from the Unix standard. The following patterns are supported: + +* `*` - A single star matches zero or more characters in a filename, but *not* a `/`. + +* `**` - A double star will match anything, including one or more `/`. + +* `?` - A question mark will match any single character except `/`. + +* `[abc]` - Matches any single character inside the brackets. + +* `[a-z]` - Matches a single character in the specified range in the brackets. + +* `{foo,bar}` - Matches any one of the comma-delimited strings inside the braces. + +Examples: + +* `foo.swift` - Matches the file "foo.swift" in the same directory as the config file. + +* `*.swift` - Matches any Swift file in the same directory as the config file. + +* `foo/bar.swift` - Matches the file "bar.swift" in the directory "foo". + +* `**/foo.swift` - Matches any file named "foo.swift" in the project. + +* `**/*.swift` - Matches any Swift file in the project. + +* `**/Generated` - Matches any folder called `Generated` in the project. + +* `**/*_generated.swift` - Matches any Swift file with the suffix "_generated" in the project. + + +Linting +------- + +SwiftFormat is primarily designed as a formatter rather than a linter, i.e. it is designed to fix your code rather than tell you what's wrong with it. However, sometimes it can be useful to verify that code has been formatted in a context where it is not desirable to actually change it. + +A typical example would be as part of a CI (Continuous Integration) process, where you may wish to have an automated script that checks committed code for style violations. While you can use a separate tool such as [SwiftLint](https://github.com/realm/SwiftLint) for this, it makes sense to be able to validate the formatting against the exact same rules as you are using to apply it. + +In order to run SwiftFormat as a linter, you can use the `--lint` command-line option: + +```bash +$ swiftformat --lint path/to/project +``` + +This runs the same rules as format mode, and all the same configuration options apply, however, no files will be modified. Instead, SwiftFormat will format each file in memory and then compare the result against the input and report the lines that required changes. + +The `--lint` option is similar to `--dryrun`, but `--lint` returns warnings for every line that required changes, and will return a nonzero error code (see [Error codes](#error-codes) below) if any changes are detected, which is useful if you want it to fail a build step on your CI server. + +If you would prefer `--lint` not to fail your build, you can use the `--lenient` option to force SwiftFormat to return success in `--lint` mode even when formatting issues were detected. + +```bash +$ swiftformat --lint --lenient path/to/project +``` + +By default, `--lint` will only report lines that require formatting, but you can use the additional `--verbose` flag to display additional info about which files were checked, even if there were no changes needed. + +If you would prefer not to see a warning for each and every formatting change, you can use the `--quiet` flag to suppress all output except errors. + +Sometimes you may wish to autoformat some rules, but only lint others. To do that, use the `--lintonly` option in your config file to specify rules that should only be applied in `--lint` mode: + +``` +--rules braces,indent +--lintonly trailingClosures,unusedArguments +``` + + +Error codes +----------- + +The swiftformat command-line tool will always exit with one of the following codes: + +* 0 - Success. This code will be returned in the event of a successful formatting run or if `--lint` detects no violations. +* 1 - Lint failure. This code will be returned when running in `--lint` mode, or when autocorrecting in `--strict` mode, if the input requires formatting. +* 70 - Program error. This code will be returned if there is a problem with the input or configuration arguments. + + +Cache +------ + +SwiftFormat uses a cache file to avoid reformatting files that haven't changed. For a large project, this can significantly reduce processing time. + +By default, the cache is stored in `~/Library/Caches/com.charcoaldesign.swiftformat` on macOS, or `/var/tmp/com.charcoaldesign.swiftformat` on Linux. Use the command-line option `--cache ignore` to ignore the cached version and re-apply formatting to all files. Alternatively, you can use `--cache clear` to delete the cache (or you can just manually delete the cache file). + +The cache is shared between all projects. The file is fairly small, as it only stores the path and size for each file, not the contents. If you do start experiencing slowdown due to the cache growing too large, you might want to consider using a separate cache file for each project. + +You can specify a custom cache file location by passing a path as the `--cache` option value. For example, you might want to store the cache file inside your project directory. It is fine to check in the cache file if you want to share it between different users of your project, as the paths stored in the cache are relative to the location of the formatted files. + + +File headers +------------- + +SwiftFormat can be configured to strip or replace the header comments in every file with a template. The "header comment" is defined as a comment block that begins on the first nonblank line in the file, and is followed by at least one blank line. This may consist of a single comment body, or multiple comments on consecutive lines: + +```swift +// This is a header comment +``` + +```swift +// This is a regular comment +func foo(bar: Int) -> Void { ... } +``` + +The header template is a string that you provide using the `--header` command-line option. Passing a value of `ignore` (the default) will leave the header comments unmodified. Passing `strip` or an empty string `""` will remove them. If you wish to provide a custom header template, the format is as follows: + +For a single-line template: `--header "Copyright (c) 2017 Foobar Industries"` + +For a multiline comment, mark linebreaks with `\n`: `--header "First line\nSecond line"` + +You can optionally include Swift comment markup in the template if you wish: `--header "/*--- Header comment ---*/"` + +If you do not include comment markup, each line in the template will be prepended with `//` and a single space. + +It is common practice to include the file name, creation date and/or the current year in a comment header copyright notice. To do that, you can use the following placeholders: + +* `{file}` - the name of the file +* `{year}` - the current year +* `{created}` - the date on which the file was created +* `{created.year}` - the year in which the file was created +* `{author.name}` - the name of the user who first committed the file +* `{author.email}` - the email of the user who first committed the file + +For example, a header template of: + +```bash +--header "{file}\nCopyright (c) {year} Foobar Industries\nCreated by John Smith on {created}." +``` + +Will be formatted as: + +```swift +// SomeFile.swift +// Copyright (c) 2019 Foobar Industries +// Created by John Smith on 01/02/2016. +``` + +**NOTE:** the `{year}` value and `{created}` date format are determined from the current locale and timezone of the machine running the script. `{author.name}` and `{author.email}` requires the project to be version controlled by git. + + +FAQ +----- + +*Q. How is this different from SwiftLint?* + +> A. SwiftLint is primarily designed to find and report code smells and style violations in your code. SwiftFormat is designed to fix them. While SwiftLint can autocorrect some issues, and SwiftFormat has some support for [linting](#linting), their primary functions are different. + + +*Q. Can SwiftFormat and SwiftLint be used together?* + +> A. Absolutely! The style rules encouraged by both tools are quite similar, and SwiftFormat even fixes some style violations that SwiftLint warns about but can't currently autocorrect. + + +*Q. What platforms does SwiftFormat support?* + +> A. SwiftFormat works on macOS 10.13 (High Sierra) and above, and also runs on Ubuntu Linux and Windows. + + +*Q. What versions of Swift are supported?* + +> A. The SwiftFormat framework and command-line tool can be compiled using Swift 5.3 and above, and can format programs written in Swift 4.x or 5. Swift 3.x is no longer actively supported. If you are still using Swift 3.x or earlier and find that SwiftFormat breaks your code, the best solution is probably to revert to an earlier SwiftFormat release, or enable only a small subset of rules. Use the `--swiftversion` argument to enable additional rules specific to later Swift versions. + + +*Q. SwiftFormat made changes I didn't want it to. How can I find out which rules to disable?* + +> A. If you run SwiftFormat using the `--verbose` option, it will tell you which rules were applied to each file. You can then selectively disable certain rules using the `--disable` argument (see below). + + +*Q. People on my team have different SwiftFormat versions installed. How can we ensure consistent formatting? + +> A. You can specify a `--minversion` argument in your project's .swiftformat` file to fail the build if developers attempt to use an older SwiftFormat version. + + +*Q. How can I modify the formatting rules?* + +> A. Many configuration options are exposed in the command-line interface or `.swiftformat` configuration file. You can either set these manually, or use the `--inferoptions` argument to automatically generate the configuration from your existing project. + +> If there is a rule that you don't like, and which cannot be configured to your liking via the command-line options, you can disable one or more rules by using the `--disable` argument, followed by the name of the rules, separated by commas. You can display a list of all supported rules using the `--rules` argument, and their behaviors are documented above this section in the README. + +> If you are using the Xcode source editor extension, rules and options can be configured using the [SwiftFormat for Xcode](#xcode-source-editor-extension) host application. Unfortunately, due to limitation of the Extensions API, there is no way to configure these on a per-project basis. + +> If the options you want aren't exposed, and disabling the rule doesn't solve the problem, the rules are implemented in the file `Rules.swift`, so you can modify them and build a new version of the command-line tool. If you think your changes might be generally useful, make a pull request. + + +Q. I don't want to be surprised by new rules added when I upgrade SwiftFormat. How can I prevent this? + +> A. You can use the `--rules` argument to specify an exclusive list of rules to run. If new rules are added, they won't be enabled if you have specified a `--rules` list in your SwiftFormat configuration. + + +*Q. Why can't I set the indent width or choose between tabs/spaces in the [SwiftFormat for Xcode](#xcode-source-editor-extension) options?* + +> Indent width and tabs/spaces can be configured in Xcode on a per project-basis. You'll find the option under "Text Settings" in the Files inspector of the right-hand sidebar. + + +*Q. After applying SwiftFormat, my code won't compile. Is that a bug?* + +> A. SwiftFormat should ideally never break your code. Check the [known issues](#known-issues), and if it's not already listed there, or the suggested workaround doesn't solve your problem, please [open an issue on GitHub](https://github.com/nicklockwood/SwiftFormat/issues). + + +*Q. Can I use SwiftFormat to lint my code without changing it?* + +> A. Yes, see the [linting](#linting) section above for details. + + +*Q. Can I use the `SwiftFormat.framework` inside another app?* + +> A. Yes, the SwiftFormat framework can be included in an app or test target, and used for many kinds of parsing and processing of Swift source code besides formatting. The SwiftFormat framework is available as a [CocoaPod](https://cocoapods.org/pods/SwiftFormat) for easy integration. + + +Known issues +--------------- + +* When using the Xcode Source Editor Extension, the SwiftFormat menu sometimes disappears from Xcode. If this happens, try moving or renaming Xcode temporarily and then changing it back. Failing that, the suggestions in [this thread](https://github.com/nicklockwood/SwiftFormat/issues/494) may help. + +* The `enumNamespaces` rule replaces classes that have only static members with an `enum`. If the class is subclassed, or if there is code that depends on the class exposing certain runtime behaviors, this may break the program. To solve this you can either fix it on a per-case basis by adding a `// swiftformat:disable:next enumNamespaces` comment directive above the class declaration, or you can add `--enumnamespaces structs-only` to prevent the rule being applied to classes, or you can just disable the `enumNamespaces` rule completely. + +* The `redundantVoidReturnType` rule can inadvertently alter the type signature for closures, for example in cases where the closure calls a `@discardableResult` function. To solve this you can either fix it on a per-case basis by adding a `// swiftformat:disable:next redundantVoidReturnType` comment directive to disable the rule for a specific call site, or you can add `--closurevoid preserve` to your [configuration](#configuration) to disable the rule completely for closures (regular functions or methods aren't affected). + +* The `redundantType` rule can introduce ambiguous code in certain cases when using the default mode of `--redundanttype inferred`. This can be worked around by by using `--redundanttype explicit`, or by manually removing the redundant type reference on the affected line, or by using the `// swiftformat:disable:next redundantType` comment directive to disable the rule at the call site (or just disable the `redundantType` rule completely). + +* If a type initializer or factory method returns an implicitly unwrapped optional value then the `redundantType` rule may remove the explicit type in a situation where it's actually required. To work around this you can either use `--redundanttype explicit`, or use the `// swiftformat:disable:next redundantType` comment directive to disable the rule at the call site (or just disable the `redundantType` rule completely). + +* When using the `initCoderUnavailable` rule, if an `init` that is marked as unavailable is overridden elsewhere in the program then it will cause a compilation error. The recommended workaround is to remove the override (which shouldn't affect the program behavior if the init was really unused) or use the `// swiftformat:disable:next initCoderUnavailable` comment directive to disable the rule for the overridden init (or just disable the `initCoderUnavailable` rule completely). + +* When using the `extensionAccessControl` rule with the `--extensionacl on-extension` option, if you have public methods defined on an internal type defined in another file, the resultant public extension will no longer compile. The recommended solution is to manually remove the `public` modifier (this won't change the program behavior) or disable the `extensionAccessControl` rule. + +* When using the `preferKeyPath` rule, conversion of `compactMap { $0.foo }` to `compactMap(\.foo)` or `flatMap { $0.foo }` to `flatMap(\.foo)` will result in code that fails to compile if `foo` is not an `Optional` property. This is due to a difference in the way that Swift handles type inference for closures vs keyPaths, as discussed [here](https://bugs.swift.org/browse/SR-13347). The recommended workaround is to replace `compactMap()` or `flatMap()` with `map()` in these cases, which will not change the behavior of the code. + +* When using the `--self remove` option, the `redundantSelf` rule will remove references to `self` in autoclosure arguments, which may change the meaning of the code, or cause it not to compile. To work around this issue, use the `--selfrequired` option to provide a comma-delimited list of methods to be excluded from the rule. The `expect()` function from the popular [Nimble](https://github.com/Quick/Nimble) unit testing framework is already excluded by default. If you are using the `--self insert` option then this is not an issue. + +* If you assign `SomeClass.self` to a variable and then instantiate an instance of the class using that variable, Swift requires that you use an explicit `.init()`, however, the `redundantInit` rule is not currently capable of detecting this situation in all cases, and may remove the `.init`. To work around this issue, use the `// swiftformat:disable:next redundantInit` comment directive to disable the rule for any affected lines of code (or just disable the `redundantInit` rule completely). + +* The `--self insert` option can only recognize locally declared member variables, not ones inherited from superclasses or extensions in other files, so it cannot insert missing `self` references for those. Note that the reverse is not true: `--self remove` should remove *all* redundant `self` references. + +* The `trailingClosures` rule can generate ambiguous code if a function has multiple optional closure arguments, or if multiple functions have signatures differing only by the name of the closure argument. For this reason, the rule is limited to anonymous closure arguments by default. You can use the `--trailingclosures` and `--nevertrailing` arguments to explicitly opt in or out of trailing closure support for specific functions. + +* The `isEmpty` rule will convert `count == 0` to `isEmpty` even for types that do not have an `isEmpty` method, such as `NSArray`/`NSDictionary`/etc. Use of Foundation collections in Swift code is pretty rare, but just in case, the rule is disabled by default. + +* The `preferForLoop` rule will convert `foo.forEach` to `for item in foo` even for types that do not conform to the `Sequence` protocol and cannot be used with a `for ... in` loop. There are no such types built in, but custom types may have this issue. + +* If a file begins with a comment, the `stripHeaders` rule will remove it if it is followed by a blank line. To avoid this, make sure that the first comment is directly followed by a line of code. + +* When running a version of SwiftFormat built using Xcode 10.2 on macOS 10.14.3 or earlier, you may experience a crash with the error "dyld: Library not loaded: @rpath/libswiftCore.dylib". To fix this, you need to install the [Swift 5 Runtime Support for Command Line Tools](https://support.apple.com/kb/DL1998). These tools are included by default in macOS 10.14.4 and later. + +* If you have a generic typealias that defines a closure (e.g. `typealias ResultCompletion = (Result) -> Void`) and use this closure as an argument in a generic function (e.g. `func handle(_ completion: ResultCompletion)`), the `opaqueGenericParameters` rule may update the function definition to use `some` syntax (e.g. `func handle(_ completion: ResultCompletion)`). `some` syntax is not permitted in closure parameters, so this will no longer compile. Workarounds include spelling out the closure explicitly in the generic function (instead of using a `typealias`) or disabling the `opaqueGenericParameters` rule (e.g. with `// swiftformat:disable:next opaqueGenericParameters`). + +* If compiling for macOS with Xcode 14.0 and configuring SwiftFormat with `--swift-version 5.7`, the `genericExtensions` rule may cause a build failure by updating extensions of the format `extension Collection where Element == Foo` to `extension Collection`. This fails to compile for macOS in Xcode 14.0, because the macOS SDK in that version of Xcode [does not include](https://forums.swift.org/t/xcode-14-rc-cannot-specialize-protocol-type/60171) the Swift 5.7 standard library. Workarounds include using `--swift-version 5.6` instead, updating to Xcode 14.1+, or disabling the `genericExtensions` rule (e.g. with `// swiftformat:disable:next genericExtensions`). + +* The `propertyTypes` rule can cause a build failure in cases where there are multiple static overloads with the same name but different return types. As a workaround you can rename the overloads to no longer conflict, or exclude the property name with `--preservesymbols propertyName,otherPropertyName,etc`. + +* The `propertyTypes` rule can cause a build failure in cases where the property's type is a protocol / existential like `let shapeStyle: ShapeStyle = .myShapeStyle`, and the value used on the right-hand side is defined in an extension like `extension ShapeStyle where Self == MyShapeStyle { static var myShapeStyle: MyShapeStyle { ... } }`. As a workaround you can use the existential `any` syntax (`let shapeStyle: any ShapeStyle = .myShapeStyle`), which the rule will preserve as-is, or exclude the type name and/or property name with `--preservesymbols ShapeStyle,myShapeStyle,etc`. + +* The `propertyTypes` rule can cause a build failure in cases like `let foo = Foo.bar` where the value is a static member that doesn't return the same time. For example, `let foo: Foo = .bar` would be invalid if the `bar` property was defined as `static var bar: Bar`. As a workaround you can write the name of the type explicitly, like `let foo: Bar = Foo.bar`, or exclude the type name and/or property name with `--preservesymbols Bar,bar,etc`. + + +Tip Jar +----------- + +SwiftFormat is not a commercially-funded product, it's a labor of love given freely to the community. If you find it useful, please consider making a donation. + +[![Donate via PayPal](https://www.paypalobjects.com/en_GB/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9ZGWNK5FEZFF6&source=url) + + +Credits +------------ + +* [Cal Stephens](https://github.com/calda) - Numerous new formatting rules, options and bug fixes +* [Tony Arnold](https://github.com/tonyarnold) - SwiftFormat for Xcode +* [Vincent Bernier](https://github.com/vinceburn) - SwiftFormat for Xcode settings UI +* [Vikram Kriplaney](https://github.com/markiv) - SwiftFormat for Xcode icon and search feature +* [Hyperphonic](https://github.com/hyperphonic0) - Xcode 12 compatibility for SwiftFormat +* [Maxime Marinel](https://github.com/bourvill) - Git pre-commit hook script +* [Romain Pouclet](https://github.com/palleas) - Homebrew formula +* [Aerobounce](https://github.com/aerobounce) - Homebrew cask and Sublime Text plugin +* [Facundo Menzella](https://github.com/facumenzella) - Several new formatting rules and options +* [Ali Akhtarzada](https://github.com/aliak00) - Several path-related CLI enhancements +* [Yonas Kolb](https://github.com/yonaskolb) - Swift Package Manager integration +* [Wolfgang Lutz](https://github.com/Lutzifer) - AppleScript integration instructions +* [Balázs Kilvády](https://github.com/balitm) - Xcode lint warning integration +* [Anthony Miller](https://github.com/AnthonyMDev) - Improvements to wrap/indent logic +* [Shingo Takagi](https://github.com/zizi4n5) - Several brace-related bug fixes +* [Benedek Kozma](https://github.com/cyberbeni) - Lint-only rules option +* [Juri Pakaste](https://github.com/juri) - Filelist feature +* [Jim Puls](https://github.com/puls) - Big Sur icon update +* [Daniele Formichelli](https://github.com/danyf90) - JSON reporter +* [Jonas Boberg](https://github.com/bobergj) - Github actions log reporter +* [Mahdi Bchatnia](https://github.com/inket) - Linux build workflow +* [Saleem Abdulrasool](https://github.com/compnerd) - Windows build workflow +* [Arthur Semenyutin](https://github.com/vox-humana) - Docker image +* [Marco Eidinger](https://github.com/MarcoEidinger) - Swift Package Manager plugin +* [Hampus Tågerud](https://github.com/hampustagerud) - Git integration for fileHeader rule +* [Nick Lockwood](https://github.com/nicklockwood) - Everything else + +([Full list of contributors](https://github.com/nicklockwood/SwiftFormat/graphs/contributors)) diff --git a/Pods/SwiftyJSON/Source/SwiftyJSON/PrivacyInfo.xcprivacy b/Pods/SwiftyJSON/Source/SwiftyJSON/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..d37d6275 --- /dev/null +++ b/Pods/SwiftyJSON/Source/SwiftyJSON/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + NSPrivacyTrackingDomains + + NSPrivacyTracking + + + diff --git a/Pods/Target Support Files/CLCamera/CLCamera-dummy.m b/Pods/Target Support Files/CLCamera/CLCamera-dummy.m new file mode 100644 index 00000000..c29b7388 --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CLCamera : NSObject +@end +@implementation PodsDummy_CLCamera +@end diff --git a/Pods/Target Support Files/CLCamera/CLCamera-prefix.pch b/Pods/Target Support Files/CLCamera/CLCamera-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/CLCamera/CLCamera-umbrella.h b/Pods/Target Support Files/CLCamera/CLCamera-umbrella.h new file mode 100644 index 00000000..966e5779 --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double CLCameraVersionNumber; +FOUNDATION_EXPORT const unsigned char CLCameraVersionString[]; + diff --git a/Pods/Target Support Files/CLCamera/CLCamera.debug.xcconfig b/Pods/Target Support Files/CLCamera/CLCamera.debug.xcconfig new file mode 100644 index 00000000..b5b6883e --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CLCamera +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CLCamera +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/CLCamera/CLCamera.modulemap b/Pods/Target Support Files/CLCamera/CLCamera.modulemap new file mode 100644 index 00000000..99c2f0c0 --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera.modulemap @@ -0,0 +1,6 @@ +module CLCamera { + umbrella header "CLCamera-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/CLCamera/CLCamera.release.xcconfig b/Pods/Target Support Files/CLCamera/CLCamera.release.xcconfig new file mode 100644 index 00000000..b5b6883e --- /dev/null +++ b/Pods/Target Support Files/CLCamera/CLCamera.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CLCamera +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CLCamera +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-dummy.m b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-dummy.m new file mode 100644 index 00000000..0824a4d3 --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CLPopoverManager : NSObject +@end +@implementation PodsDummy_CLPopoverManager +@end diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-prefix.pch b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-umbrella.h b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-umbrella.h new file mode 100644 index 00000000..e3d78097 --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double CLPopoverManagerVersionNumber; +FOUNDATION_EXPORT const unsigned char CLPopoverManagerVersionString[]; + diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.debug.xcconfig b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.debug.xcconfig new file mode 100644 index 00000000..1971ad3a --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CLPopoverManager +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.modulemap b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.modulemap new file mode 100644 index 00000000..dfac429c --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.modulemap @@ -0,0 +1,6 @@ +module CLPopoverManager { + umbrella header "CLPopoverManager-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.release.xcconfig b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.release.xcconfig new file mode 100644 index 00000000..1971ad3a --- /dev/null +++ b/Pods/Target Support Files/CLPopoverManager/CLPopoverManager.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CLPopoverManager +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/CryptoSwift/ResourceBundle-CryptoSwift-CryptoSwift-Info.plist b/Pods/Target Support Files/CryptoSwift/ResourceBundle-CryptoSwift-CryptoSwift-Info.plist new file mode 100644 index 00000000..3d250e36 --- /dev/null +++ b/Pods/Target Support Files/CryptoSwift/ResourceBundle-CryptoSwift-CryptoSwift-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.8.4 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist b/Pods/Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist new file mode 100644 index 00000000..09099493 --- /dev/null +++ b/Pods/Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 7.12.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/LookinServer/LookinServer-dummy.m b/Pods/Target Support Files/LookinServer/LookinServer-dummy.m new file mode 100644 index 00000000..f86bacfb --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_LookinServer : NSObject +@end +@implementation PodsDummy_LookinServer +@end diff --git a/Pods/Target Support Files/LookinServer/LookinServer-prefix.pch b/Pods/Target Support Files/LookinServer/LookinServer-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/LookinServer/LookinServer-umbrella.h b/Pods/Target Support Files/LookinServer/LookinServer-umbrella.h new file mode 100644 index 00000000..a3dddb03 --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer-umbrella.h @@ -0,0 +1,87 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CALayer+LookinServer.h" +#import "NSObject+LookinServer.h" +#import "UIBlurEffect+LookinServer.h" +#import "UIColor+LookinServer.h" +#import "UIImage+LookinServer.h" +#import "UIImageView+LookinServer.h" +#import "UILabel+LookinServer.h" +#import "UITableView+LookinServer.h" +#import "UITextField+LookinServer.h" +#import "UITextView+LookinServer.h" +#import "UIView+LookinServer.h" +#import "UIViewController+LookinServer.h" +#import "UIVisualEffectView+LookinServer.h" +#import "LKS_ConnectionManager.h" +#import "LKS_RequestHandler.h" +#import "LKS_AttrModificationPatchHandler.h" +#import "LKS_CustomAttrModificationHandler.h" +#import "LKS_HierarchyDetailsHandler.h" +#import "LKS_InbuiltAttrModificationHandler.h" +#import "LookinServer.h" +#import "LKSConfigManager.h" +#import "LKS_AttrGroupsMaker.h" +#import "LKS_CustomAttrGroupsMaker.h" +#import "LKS_CustomAttrSetterManager.h" +#import "LKS_CustomDisplayItemsMaker.h" +#import "LKS_EventHandlerMaker.h" +#import "LKS_ExportManager.h" +#import "LKS_GestureTargetActionsSearcher.h" +#import "LKS_Helper.h" +#import "LKS_HierarchyDisplayItemsMaker.h" +#import "LKS_MultiplatformAdapter.h" +#import "LKS_ObjectRegistry.h" +#import "LKS_TraceManager.h" +#import "LookinServerDefines.h" +#import "CALayer+Lookin.h" +#import "Color+Lookin.h" +#import "Image+Lookin.h" +#import "NSArray+Lookin.h" +#import "NSObject+Lookin.h" +#import "NSSet+Lookin.h" +#import "NSString+Lookin.h" +#import "LookinAppInfo.h" +#import "LookinAttribute.h" +#import "LookinAttributeModification.h" +#import "LookinAttributesGroup.h" +#import "LookinAttributesSection.h" +#import "LookinAttrIdentifiers.h" +#import "LookinAttrType.h" +#import "LookinAutoLayoutConstraint.h" +#import "LookinCodingValueType.h" +#import "LookinConnectionAttachment.h" +#import "LookinConnectionResponseAttachment.h" +#import "LookinCustomAttrModification.h" +#import "LookinCustomDisplayItemInfo.h" +#import "LookinDashboardBlueprint.h" +#import "LookinDefines.h" +#import "LookinDisplayItem.h" +#import "LookinDisplayItemDetail.h" +#import "LookinEventHandler.h" +#import "LookinHierarchyFile.h" +#import "LookinHierarchyInfo.h" +#import "LookinObject.h" +#import "LookinStaticAsyncUpdateTask.h" +#import "LookinTuple.h" +#import "LookinWeakContainer.h" +#import "Lookin_PTChannel.h" +#import "Lookin_PTPrivate.h" +#import "Lookin_PTProtocol.h" +#import "Lookin_PTUSBHub.h" +#import "Peertalk.h" +#import "LookinIvarTrace.h" + +FOUNDATION_EXPORT double LookinServerVersionNumber; +FOUNDATION_EXPORT const unsigned char LookinServerVersionString[]; + diff --git a/Pods/Target Support Files/LookinServer/LookinServer.debug.xcconfig b/Pods/Target Support Files/LookinServer/LookinServer.debug.xcconfig new file mode 100644 index 00000000..601d5d52 --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/LookinServer +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SHOULD_COMPILE_LOOKIN_SERVER=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/LookinServer" "${PODS_ROOT}/Headers/Public" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/LookinServer +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) SHOULD_COMPILE_LOOKIN_SERVER +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/LookinServer/LookinServer.modulemap b/Pods/Target Support Files/LookinServer/LookinServer.modulemap new file mode 100644 index 00000000..5e29f4fa --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer.modulemap @@ -0,0 +1,6 @@ +module LookinServer { + umbrella header "LookinServer-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/LookinServer/LookinServer.release.xcconfig b/Pods/Target Support Files/LookinServer/LookinServer.release.xcconfig new file mode 100644 index 00000000..601d5d52 --- /dev/null +++ b/Pods/Target Support Files/LookinServer/LookinServer.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/LookinServer +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SHOULD_COMPILE_LOOKIN_SERVER=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/LookinServer" "${PODS_ROOT}/Headers/Public" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/LookinServer +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) SHOULD_COMPILE_LOOKIN_SERVER +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/MJExtension/ResourceBundle-MJExtension-MJExtension-Info.plist b/Pods/Target Support Files/MJExtension/ResourceBundle-MJExtension-MJExtension-Info.plist new file mode 100644 index 00000000..649dffa7 --- /dev/null +++ b/Pods/Target Support Files/MJExtension/ResourceBundle-MJExtension-MJExtension-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 3.4.2 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.debug.xcconfig b/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.debug.xcconfig index 3e89e7f6..0da45446 100644 --- a/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.debug.xcconfig +++ b/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.debug.xcconfig @@ -4,7 +4,6 @@ HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/H LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DateTools" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_ROOT}/Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/DateTools/DateTools.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/MJExtension/MJExtension.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/Masonry/Masonry.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/libwebp/libwebp.modulemap" -isystem "${PODS_ROOT}/Headers/Public" OTHER_LDFLAGS = $(inherited) -ObjC -l"DateTools" -l"MJExtension" -l"Masonry" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"libwebp" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "UIKit" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DateTools" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/DateTools/DateTools.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/MJExtension/MJExtension.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/Masonry/Masonry.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/libwebp/libwebp.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.release.xcconfig b/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.release.xcconfig index 3e89e7f6..0da45446 100644 --- a/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.release.xcconfig +++ b/Pods/Target Support Files/Pods-CLDemo-OC/Pods-CLDemo-OC.release.xcconfig @@ -4,7 +4,6 @@ HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/H LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DateTools" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_ROOT}/Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/DateTools/DateTools.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/MJExtension/MJExtension.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/Masonry/Masonry.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/libwebp/libwebp.modulemap" -isystem "${PODS_ROOT}/Headers/Public" OTHER_LDFLAGS = $(inherited) -ObjC -l"DateTools" -l"MJExtension" -l"Masonry" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"libwebp" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "UIKit" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DateTools" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Private/SDWebImageWebPCoder/SDWebImageWebPCoder.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/DateTools/DateTools.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/MJExtension/MJExtension.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/Masonry/Masonry.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/libwebp/libwebp.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.debug.xcconfig b/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.debug.xcconfig index 0acc7264..1bf32d2a 100644 --- a/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.debug.xcconfig +++ b/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.debug.xcconfig @@ -5,7 +5,6 @@ HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/H LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CLCamera" "${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLCamera/CLCamera.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager/CLPopoverManager.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift/DateToolsSwift.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/LookinServer/LookinServer.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/TZImagePickerController/TZImagePickerController.modulemap" -isystem "${PODS_ROOT}/Headers/Public" OTHER_LDFLAGS = $(inherited) -ObjC -l"CLCamera" -l"CLPopoverManager" -l"CryptoSwift" -l"DateToolsSwift" -l"Kingfisher" -l"LookinServer" -l"SDWebImage" -l"SnapKit" -l"SwiftyJSON" -l"TZImagePickerController" -l"lottie-ios" -l"swiftCoreGraphics" -framework "Accelerate" -framework "CFNetwork" -framework "CoreGraphics" -framework "ImageIO" -framework "Photos" -framework "PhotosUI" -framework "QuartzCore" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/CLCamera" "-F${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "-F${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift" "-F${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "-F${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftFormat" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLCamera/CLCamera.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager/CLPopoverManager.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift/DateToolsSwift.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/LookinServer/LookinServer.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/TZImagePickerController/TZImagePickerController.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.release.xcconfig b/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.release.xcconfig index 0acc7264..1bf32d2a 100644 --- a/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.release.xcconfig +++ b/Pods/Target Support Files/Pods-CLDemo-Swift/Pods-CLDemo-Swift.release.xcconfig @@ -5,7 +5,6 @@ HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/H LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CLCamera" "${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLCamera/CLCamera.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager/CLPopoverManager.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift/DateToolsSwift.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.modulemap" -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/LookinServer/LookinServer.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -fmodule-map-file="${PODS_ROOT}/Headers/Public/TZImagePickerController/TZImagePickerController.modulemap" -isystem "${PODS_ROOT}/Headers/Public" OTHER_LDFLAGS = $(inherited) -ObjC -l"CLCamera" -l"CLPopoverManager" -l"CryptoSwift" -l"DateToolsSwift" -l"Kingfisher" -l"LookinServer" -l"SDWebImage" -l"SnapKit" -l"SwiftyJSON" -l"TZImagePickerController" -l"lottie-ios" -l"swiftCoreGraphics" -framework "Accelerate" -framework "CFNetwork" -framework "CoreGraphics" -framework "ImageIO" -framework "Photos" -framework "PhotosUI" -framework "QuartzCore" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/CLCamera" "-F${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "-F${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift" "-F${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "-F${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftFormat" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLCamera/CLCamera.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CLPopoverManager/CLPopoverManager.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/DateToolsSwift/DateToolsSwift.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.modulemap" -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/LookinServer/LookinServer.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/SDWebImage/SDWebImage.modulemap" -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/TZImagePickerController/TZImagePickerController.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/SDWebImage/ResourceBundle-SDWebImage-SDWebImage-Info.plist b/Pods/Target Support Files/SDWebImage/ResourceBundle-SDWebImage-SDWebImage-Info.plist new file mode 100644 index 00000000..181cedde --- /dev/null +++ b/Pods/Target Support Files/SDWebImage/ResourceBundle-SDWebImage-SDWebImage-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.20.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist b/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist new file mode 100644 index 00000000..d6be5716 --- /dev/null +++ b/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.7.1 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/SwiftFormat/SwiftFormat.debug.xcconfig b/Pods/Target Support Files/SwiftFormat/SwiftFormat.debug.xcconfig new file mode 100644 index 00000000..0a25a19c --- /dev/null +++ b/Pods/Target Support Files/SwiftFormat/SwiftFormat.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftFormat +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftFormat +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SwiftFormat/SwiftFormat.release.xcconfig b/Pods/Target Support Files/SwiftFormat/SwiftFormat.release.xcconfig new file mode 100644 index 00000000..0a25a19c --- /dev/null +++ b/Pods/Target Support Files/SwiftFormat/SwiftFormat.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftFormat +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftFormat +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SwiftyJSON/ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist b/Pods/Target Support Files/SwiftyJSON/ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist new file mode 100644 index 00000000..4db707fc --- /dev/null +++ b/Pods/Target Support Files/SwiftyJSON/ResourceBundle-SwiftyJSON-SwiftyJSON-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.0.2 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/lottie-ios/ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist b/Pods/Target Support Files/lottie-ios/ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist new file mode 100644 index 00000000..4db83600 --- /dev/null +++ b/Pods/Target Support Files/lottie-ios/ResourceBundle-LottiePrivacyInfo-lottie-ios-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 4.4.1 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/libwebp/sharpyuv/libsharpyuv.pc.in b/Pods/libwebp/sharpyuv/libsharpyuv.pc.in new file mode 100644 index 00000000..0fb565a6 --- /dev/null +++ b/Pods/libwebp/sharpyuv/libsharpyuv.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/webp + +Name: libsharpyuv +Description: Library for sharp RGB to YUV conversion +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -l@webp_libname_prefix@sharpyuv +Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ diff --git a/Pods/libwebp/sharpyuv/libsharpyuv.rc b/Pods/libwebp/sharpyuv/libsharpyuv.rc new file mode 100644 index 00000000..49c338a3 --- /dev/null +++ b/Pods/libwebp/sharpyuv/libsharpyuv.rc @@ -0,0 +1,41 @@ +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,2,1 + PRODUCTVERSION 0,0,2,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Google, Inc." + VALUE "FileDescription", "libsharpyuv DLL" + VALUE "FileVersion", "0.2.1" + VALUE "InternalName", "libsharpyuv.dll" + VALUE "LegalCopyright", "Copyright (C) 2023" + VALUE "OriginalFilename", "libsharpyuv.dll" + VALUE "ProductName", "SharpYuv Library" + VALUE "ProductVersion", "0.2.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources diff --git a/Pods/libwebp/sharpyuv/sharpyuv_cpu.c b/Pods/libwebp/sharpyuv/sharpyuv_cpu.c new file mode 100644 index 00000000..29425a0c --- /dev/null +++ b/Pods/libwebp/sharpyuv/sharpyuv_cpu.c @@ -0,0 +1,14 @@ +// Copyright 2022 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +#include "sharpyuv/sharpyuv_cpu.h" + +// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The +// function pointer is renamed in sharpyuv_cpu.h. +#include "src/dsp/cpu.c" diff --git a/Pods/libwebp/sharpyuv/sharpyuv_cpu.h b/Pods/libwebp/sharpyuv/sharpyuv_cpu.h new file mode 100644 index 00000000..176ca3eb --- /dev/null +++ b/Pods/libwebp/sharpyuv/sharpyuv_cpu.h @@ -0,0 +1,22 @@ +// Copyright 2022 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_ +#define WEBP_SHARPYUV_SHARPYUV_CPU_H_ + +#include "sharpyuv/sharpyuv.h" + +// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds. +// SharpYuvInit() replaces the use of the function pointer. +#undef WEBP_EXTERN +#define WEBP_EXTERN extern +#define VP8GetCPUInfo SharpYuvGetCPUInfo +#include "src/dsp/cpu.h" + +#endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_ diff --git a/Pods/lottie-ios/Sources/PrivacyInfo.xcprivacy b/Pods/lottie-ios/Sources/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..187c151d --- /dev/null +++ b/Pods/lottie-ios/Sources/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + 3B52.1 + + + + + diff --git a/Pods/lottie-ios/Sources/Private/CoreAnimation/Animations/DropShadowAnimation.swift b/Pods/lottie-ios/Sources/Private/CoreAnimation/Animations/DropShadowAnimation.swift new file mode 100644 index 00000000..92296390 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/CoreAnimation/Animations/DropShadowAnimation.swift @@ -0,0 +1,160 @@ +// Created by Cal Stephens on 8/15/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +import QuartzCore + +// MARK: - DropShadowModel + +protocol DropShadowModel { + /// The opacity of the drop shadow, from 0 to 100. + var _opacity: KeyframeGroup? { get } + + /// The shadow radius of the blur + var _radius: KeyframeGroup? { get } + + /// The color of the drop shadow + var _color: KeyframeGroup? { get } + + /// The angle of the drop shadow, in degrees, + /// with "90" resulting in a shadow directly beneath the layer. + /// Combines with the `distance` to form the `shadowOffset`. + var _angle: KeyframeGroup? { get } + + /// The distance of the drop shadow offset. + /// Combines with the `angle` to form the `shadowOffset`. + var _distance: KeyframeGroup? { get } +} + +// MARK: - DropShadowStyle + DropShadowModel + +extension DropShadowStyle: DropShadowModel { + var _opacity: KeyframeGroup? { opacity } + var _color: KeyframeGroup? { color } + var _angle: KeyframeGroup? { angle } + var _distance: KeyframeGroup? { distance } + + var _radius: KeyframeGroup? { + size.map { sizeValue in + // After Effects shadow softness uses a different range of values than CALayer.shadowRadius, + // so shadows render too softly if we directly use the value from After Effects. We find that + // dividing this value from After Effects by 2 produces results that are visually similar. + LottieVector1D(sizeValue.cgFloatValue / 2) + } + } +} + +// MARK: - DropShadowEffect + DropShadowModel + +extension DropShadowEffect: DropShadowModel { + var _color: KeyframeGroup? { color?.value } + var _distance: KeyframeGroup? { distance?.value } + + var _radius: KeyframeGroup? { + softness?.value?.map { softnessValue in + // After Effects shadow softness uses a different range of values than CALayer.shadowRadius, + // so shadows render too softly if we directly use the value from After Effects. We find that + // dividing this value from After Effects by 5 produces results that are visually similar. + LottieVector1D(softnessValue.cgFloatValue / 5) + } + } + + var _opacity: KeyframeGroup? { + opacity?.value?.map { originalOpacityValue in + // `DropShadowEffect.opacity` is a value between 0 and 255, + // but `DropShadowModel._opacity` expects a value between 0 and 100. + LottieVector1D((originalOpacityValue.value / 255.0) * 100) + } + } + + var _angle: KeyframeGroup? { + direction?.value?.map { originalAngleValue in + // `DropShadowEffect.distance` is rotated 90º from the + // angle value representation expected by `DropShadowModel._angle` + LottieVector1D(originalAngleValue.value - 90) + } + } +} + +// MARK: - CALayer + DropShadowModel + +extension CALayer { + + // MARK: Internal + + /// Adds drop shadow animations from the given `DropShadowModel` to this layer + @nonobjc + func addDropShadowAnimations( + for dropShadowModel: DropShadowModel, + context: LayerAnimationContext) + throws + { + try addShadowOpacityAnimation(from: dropShadowModel, context: context) + try addShadowColorAnimation(from: dropShadowModel, context: context) + try addShadowRadiusAnimation(from: dropShadowModel, context: context) + try addShadowOffsetAnimation(from: dropShadowModel, context: context) + } + + // MARK: Private + + private func addShadowOpacityAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws { + guard let opacityKeyframes = model._opacity else { return } + + try addAnimation( + for: .shadowOpacity, + keyframes: opacityKeyframes, + value: { + // Lottie animation files express opacity as a numerical percentage value + // (e.g. 0%, 50%, 100%) so we divide by 100 to get the decimal values + // expected by Core Animation (e.g. 0.0, 0.5, 1.0). + $0.cgFloatValue / 100 + }, + context: context) + } + + private func addShadowColorAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws { + guard let shadowColorKeyframes = model._color else { return } + + try addAnimation( + for: .shadowColor, + keyframes: shadowColorKeyframes, + value: \.cgColorValue, + context: context) + } + + private func addShadowRadiusAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws { + guard let shadowSizeKeyframes = model._radius else { return } + + try addAnimation( + for: .shadowRadius, + keyframes: shadowSizeKeyframes, + value: \.cgFloatValue, + context: context) + } + + private func addShadowOffsetAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws { + guard + let angleKeyframes = model._angle, + let distanceKeyframes = model._distance + else { return } + + let offsetKeyframes = Keyframes.combined(angleKeyframes, distanceKeyframes) { angleDegrees, distance -> CGSize in + // Lottie animation files express rotation in degrees + // (e.g. 90º, 180º, 360º) so we convert to radians to get the + // values expected by Core Animation (e.g. π/2, π, 2π) + let angleRadians = (angleDegrees.cgFloatValue * .pi) / 180 + + // Lottie animation files express the `shadowOffset` as (angle, distance) pair, + // which we convert to the expected x / y offset values: + let offsetX = distance.cgFloatValue * cos(angleRadians) + let offsetY = distance.cgFloatValue * sin(angleRadians) + return CGSize(width: offsetX, height: offsetY) + } + + try addAnimation( + for: .shadowOffset, + keyframes: offsetKeyframes, + value: { $0 }, + context: context) + } + +} diff --git a/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift b/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift new file mode 100644 index 00000000..ceaefd74 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift @@ -0,0 +1,328 @@ +// Created by Cal Stephens on 1/28/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +// MARK: - Keyframes + +enum Keyframes { + + // MARK: Internal + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ allGroups: [KeyframeGroup], + requiresManualInterpolation: Bool = false) + -> KeyframeGroup<[T]> + where T: AnyInterpolatable + { + Keyframes.combined( + allGroups, + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + untypedValues.compactMap { $0 as? T } + }) + } + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ k1: KeyframeGroup, + _ k2: KeyframeGroup, + requiresManualInterpolation: Bool = false, + makeCombinedResult: (T1, T2) throws -> CombinedResult) + rethrows + -> KeyframeGroup + where T1: AnyInterpolatable, T2: AnyInterpolatable + { + try Keyframes.combined( + [k1, k2], + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + guard + let t1 = untypedValues[0] as? T1, + let t2 = untypedValues[1] as? T2 + else { return nil } + + return try makeCombinedResult(t1, t2) + }) + } + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ k1: KeyframeGroup, + _ k2: KeyframeGroup, + _ k3: KeyframeGroup, + requiresManualInterpolation: Bool = false, + makeCombinedResult: (T1, T2, T3) -> CombinedResult) + -> KeyframeGroup + where T1: AnyInterpolatable, T2: AnyInterpolatable, T3: AnyInterpolatable + { + Keyframes.combined( + [k1, k2, k3], + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + guard + let t1 = untypedValues[0] as? T1, + let t2 = untypedValues[1] as? T2, + let t3 = untypedValues[2] as? T3 + else { return nil } + + return makeCombinedResult(t1, t2, t3) + }) + } + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ k1: KeyframeGroup, + _ k2: KeyframeGroup, + _ k3: KeyframeGroup, + _ k4: KeyframeGroup, + _ k5: KeyframeGroup, + _ k6: KeyframeGroup, + _ k7: KeyframeGroup, + requiresManualInterpolation: Bool = false, + makeCombinedResult: (T1, T2, T3, T4, T5, T6, T7) -> CombinedResult) + -> KeyframeGroup + where T1: AnyInterpolatable, T2: AnyInterpolatable, T3: AnyInterpolatable, T4: AnyInterpolatable, + T5: AnyInterpolatable, T6: AnyInterpolatable, T7: AnyInterpolatable + { + Keyframes.combined( + [k1, k2, k3, k4, k5, k6, k7], + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + guard + let t1 = untypedValues[0] as? T1, + let t2 = untypedValues[1] as? T2, + let t3 = untypedValues[2] as? T3, + let t4 = untypedValues[3] as? T4, + let t5 = untypedValues[4] as? T5, + let t6 = untypedValues[5] as? T6, + let t7 = untypedValues[6] as? T7 + else { return nil } + + return makeCombinedResult(t1, t2, t3, t4, t5, t6, t7) + }) + } + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ k1: KeyframeGroup, + _ k2: KeyframeGroup, + _ k3: KeyframeGroup, + _ k4: KeyframeGroup, + _ k5: KeyframeGroup, + _ k6: KeyframeGroup, + _ k7: KeyframeGroup, + _ k8: KeyframeGroup, + requiresManualInterpolation: Bool = false, + makeCombinedResult: (T1, T2, T3, T4, T5, T6, T7, T8) -> CombinedResult) + -> KeyframeGroup + where T1: AnyInterpolatable, T2: AnyInterpolatable, T3: AnyInterpolatable, T4: AnyInterpolatable, + T5: AnyInterpolatable, T6: AnyInterpolatable, T7: AnyInterpolatable, T8: AnyInterpolatable + { + Keyframes.combined( + [k1, k2, k3, k4, k5, k6, k7, k8], + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + guard + let t1 = untypedValues[0] as? T1, + let t2 = untypedValues[1] as? T2, + let t3 = untypedValues[2] as? T3, + let t4 = untypedValues[3] as? T4, + let t5 = untypedValues[4] as? T5, + let t6 = untypedValues[5] as? T6, + let t7 = untypedValues[6] as? T7, + let t8 = untypedValues[7] as? T8 + else { return nil } + + return makeCombinedResult(t1, t2, t3, t4, t5, t6, t7, t8) + }) + } + + /// Combines the given keyframe groups of `Keyframe`s into a single keyframe group of of `Keyframe<[T]>`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + static func combined( + _ k1: KeyframeGroup, + _ k2: KeyframeGroup, + _ k3: KeyframeGroup, + _ k4: KeyframeGroup, + _ k5: KeyframeGroup, + _ k6: KeyframeGroup, + _ k7: KeyframeGroup, + _ k8: KeyframeGroup, + _ k9: KeyframeGroup, + _ k10: KeyframeGroup, + requiresManualInterpolation: Bool = false, + makeCombinedResult: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> CombinedResult) + -> KeyframeGroup + where T1: AnyInterpolatable, T2: AnyInterpolatable, T3: AnyInterpolatable, T4: AnyInterpolatable, + T5: AnyInterpolatable, T6: AnyInterpolatable, T7: AnyInterpolatable, T8: AnyInterpolatable, + T9: AnyInterpolatable, T10: AnyInterpolatable + { + Keyframes.combined( + [k1, k2, k3, k4, k5, k6, k7, k8, k9, k10], + requiresManualInterpolation: requiresManualInterpolation, + makeCombinedResult: { untypedValues in + guard + let t1 = untypedValues[0] as? T1, + let t2 = untypedValues[1] as? T2, + let t3 = untypedValues[2] as? T3, + let t4 = untypedValues[3] as? T4, + let t5 = untypedValues[4] as? T5, + let t6 = untypedValues[5] as? T6, + let t7 = untypedValues[6] as? T7, + let t8 = untypedValues[7] as? T8, + let t9 = untypedValues[8] as? T9, + let t10 = untypedValues[9] as? T10 + else { return nil } + + return makeCombinedResult(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) + }) + } + + // MARK: Private + + /// Combines the given `[KeyframeGroup]` of `Keyframe`s into a single `KeyframeGroup` of `Keyframe`s + /// - If all of the `KeyframeGroup`s have the exact same animation timing, the keyframes are merged + /// - Otherwise, the keyframes are manually interpolated at each frame in the animation + /// + /// `makeCombinedResult` is a closure that takes an array of keyframe values (with the exact same length as `AnyKeyframeGroup`), + /// casts them to the expected type, and combined them into the final resulting keyframe. + /// + /// `requiresManualInterpolation` determines whether the keyframes must be computed using `Keyframes.manuallyInterpolated`, + /// which interpolates the value at each frame, or if the keyframes can simply be combined. + private static func combined( + _ allGroups: [AnyKeyframeGroup], + requiresManualInterpolation: Bool, + makeCombinedResult: ([Any]) throws -> CombinedResult?) + rethrows + -> KeyframeGroup + { + let untypedGroups = allGroups.map { $0.untyped } + + // Animations with no timing information (e.g. with just a single keyframe) + // can be trivially combined with any other set of keyframes, so we don't need + // to check those. + let animatingKeyframes = untypedGroups.filter { $0.keyframes.count > 1 } + + guard + !requiresManualInterpolation, + !allGroups.isEmpty, + animatingKeyframes.allSatisfy({ $0.hasSameTimingParameters(as: animatingKeyframes[0]) }) + else { + // If the keyframes don't all share the same timing information, + // we have to interpolate the value at each individual frame + return try Keyframes.manuallyInterpolated(allGroups, makeCombinedResult: makeCombinedResult) + } + + var combinedKeyframes = ContiguousArray>() + let baseKeyframes = (animatingKeyframes.first ?? untypedGroups[0]).keyframes + + for index in baseKeyframes.indices { + let baseKeyframe = baseKeyframes[index] + let untypedValues = untypedGroups.map { $0.valueForCombinedKeyframes(at: index) } + + if let combinedValue = try makeCombinedResult(untypedValues) { + combinedKeyframes.append(baseKeyframe.withValue(combinedValue)) + } else { + LottieLogger.shared.assertionFailure(""" + Failed to cast untyped keyframe values to expected type. This is an internal error. + """) + } + } + + return KeyframeGroup(keyframes: combinedKeyframes) + } + + private static func manuallyInterpolated( + _ allGroups: [AnyKeyframeGroup], + makeCombinedResult: ([Any]) throws -> CombinedResult?) + rethrows + -> KeyframeGroup + { + let untypedGroups = allGroups.map { $0.untyped } + let untypedInterpolators = allGroups.map { $0.interpolator } + + let times = untypedGroups.flatMap { $0.keyframes.map { $0.time } } + + let minimumTime = times.min() ?? 0 + let maximumTime = times.max() ?? 0 + + // We disable Core Animation interpolation when using manually interpolated keyframes, + // so we don't animate between these values. To prevent the animation from being choppy + // even at low playback speed, we have to interpolate at a very high fidelity. + let animationLocalTimeRange = stride(from: minimumTime, to: maximumTime, by: 0.1) + + let interpolatedKeyframes = try animationLocalTimeRange.compactMap { localTime -> Keyframe? in + let interpolatedValues = untypedInterpolators.map { interpolator in + interpolator.value(frame: AnimationFrameTime(localTime)) + } + + guard let combinedResult = try makeCombinedResult(interpolatedValues) else { + LottieLogger.shared.assertionFailure(""" + Failed to cast untyped keyframe values to expected type. This is an internal error. + """) + return nil + } + + return Keyframe( + value: combinedResult, + time: AnimationFrameTime(localTime), + // Since we already manually interpolated the keyframes, have Core Animation display + // each value as a static keyframe rather than trying to interpolate between them. + isHold: true) + } + + return KeyframeGroup(keyframes: ContiguousArray(interpolatedKeyframes)) + } + +} + +extension KeyframeGroup { + /// Whether or not all of the keyframes in this `KeyframeGroup` have the same + /// timing parameters as the corresponding keyframe in the other given `KeyframeGroup` + func hasSameTimingParameters(as other: KeyframeGroup) -> Bool { + guard keyframes.count == other.keyframes.count else { + return false + } + + return zip(keyframes, other.keyframes).allSatisfy { + $0.hasSameTimingParameters(as: $1) + } + } +} + +extension Keyframe { + /// Whether or not this keyframe has the same timing parameters as the given keyframe, + /// excluding `spatialInTangent` and `spatialOutTangent`. + fileprivate func hasSameTimingParameters(as other: Keyframe) -> Bool { + time == other.time + && isHold == other.isHold + && inTangent == other.inTangent + && outTangent == other.outTangent + // We intentionally don't compare spatial in/out tangents, + // since those values are only used in very specific cases + // (animating the x/y position of a layer), which aren't ever + // combined in this way. + } +} + +extension KeyframeGroup { + /// The value to use for a combined set of keyframes, for the given index + fileprivate func valueForCombinedKeyframes(at index: Int) -> T { + if keyframes.count == 1 { + return keyframes[0].value + } else { + return keyframes[index].value + } + } +} diff --git a/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+timeRemapping.swift b/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+timeRemapping.swift new file mode 100644 index 00000000..217e38dd --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/CoreAnimation/Extensions/Keyframes+timeRemapping.swift @@ -0,0 +1,46 @@ +// Created by Cal Stephens on 1/8/24. +// Copyright © 2024 Airbnb Inc. All rights reserved. + +extension Keyframes { + /// Manually interpolates the given keyframes, and applies `context.complexTimeRemapping`. + /// - Since `complexTimeRemapping` is a mapping from "global time" to "local time", + /// we have to manually interpolate the keyframes at every frame in the animation. + static func manuallyInterpolatedWithTimeRemapping( + _ keyframes: KeyframeGroup, + context: LayerAnimationContext) + -> KeyframeGroup + { + let minimumTime = context.animation.startFrame + let maximumTime = context.animation.endFrame + let animationLocalTimeRange = stride(from: minimumTime, to: maximumTime, by: 1.0) + + let interpolator = keyframes.interpolator + + // Since potentially many global times can refer to the same local time, + // we can cache and reused these local-time values. + var localTimeCache = [AnimationFrameTime: T]() + + let interpolatedRemappedKeyframes = animationLocalTimeRange.compactMap { globalTime -> Keyframe? in + let remappedLocalTime = context.complexTimeRemapping(globalTime) + + let valueAtRemappedTime: T + if let cachedValue = localTimeCache[remappedLocalTime] { + valueAtRemappedTime = cachedValue + } else if let interpolatedValue = interpolator.value(frame: remappedLocalTime) as? T { + valueAtRemappedTime = interpolatedValue + localTimeCache[remappedLocalTime] = interpolatedValue + } else { + LottieLogger.shared.assertionFailure(""" + Failed to cast untyped keyframe values to expected type. This is an internal error. + """) + return nil + } + + return Keyframe( + value: valueAtRemappedTime, + time: AnimationFrameTime(globalTime)) + } + + return KeyframeGroup(keyframes: ContiguousArray(interpolatedRemappedKeyframes)) + } +} diff --git a/Pods/lottie-ios/Sources/Private/CoreAnimation/Layers/InfiniteOpaqueAnimationLayer.swift b/Pods/lottie-ios/Sources/Private/CoreAnimation/Layers/InfiniteOpaqueAnimationLayer.swift new file mode 100644 index 00000000..4549fea6 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/CoreAnimation/Layers/InfiniteOpaqueAnimationLayer.swift @@ -0,0 +1,56 @@ +// Created by Cal Stephens on 10/10/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +import QuartzCore + +// MARK: - ExpandedAnimationLayer + +/// A `BaseAnimationLayer` subclass that renders its background color +/// as if the layer is infinitely large, without affecting its bounds +/// or the bounds of its sublayers +final class InfiniteOpaqueAnimationLayer: BaseAnimationLayer { + + // MARK: Lifecycle + + override init() { + super.init() + addSublayer(additionalPaddingLayer) + } + + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + /// Called by CoreAnimation to create a shadow copy of this layer + /// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init + override init(layer: Any) { + super.init(layer: layer) + } + + // MARK: Internal + + override func layoutSublayers() { + super.layoutSublayers() + + masksToBounds = false + additionalPaddingLayer.backgroundColor = backgroundColor + + // Scale `additionalPaddingLayer` to be larger than this layer + // by `additionalPadding` at each size, and centered at the center + // of this layer. Since `additionalPadding` is very large, this has + // the affect of making `additionalPaddingLayer` appear infinite. + let scaleRatioX = (bounds.width + (CALayer.veryLargeLayerPadding * 2)) / bounds.width + let scaleRatioY = (bounds.height + (CALayer.veryLargeLayerPadding * 2)) / bounds.height + + additionalPaddingLayer.transform = CATransform3DScale( + CATransform3DMakeTranslation(-CALayer.veryLargeLayerPadding, -CALayer.veryLargeLayerPadding, 0), + scaleRatioX, + scaleRatioY, + 1) + } + + // MARK: Private + + private let additionalPaddingLayer = CALayer() + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift new file mode 100644 index 00000000..572e2a28 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift @@ -0,0 +1,263 @@ +// Created by Laura Skelton on 11/25/16. +// Copyright © 2016 Airbnb. All rights reserved. + +// MARK: - Collection + +extension Collection where Element: Diffable, Index == Int { + + /// Diffs two collections (e.g. `Array`s) of `Diffable` items, returning an `IndexChangeset` + /// representing the minimal set of changes to get from the other collection to this collection. + /// + /// - Parameters: + /// - from other: The collection of old data. + func makeChangeset(from other: Self) -> IndexChangeset { + // Arranging the elements contiguously prior to diffing improves performance by ~40%. + let new = ContiguousArray(self) + let old = ContiguousArray(other) + + /// The entries in both this and the other collection, keyed by their `dataID`s. + var entries = [AnyHashable: EpoxyEntry](minimumCapacity: new.count) + var duplicates = [EpoxyEntry]() + + var newResults = ContiguousArray() + newResults.reserveCapacity(new.count) + + for index in new.indices { + let id = new[index].diffIdentifier + let entry = entries[id, default: EpoxyEntry()] + if entry.trackNewIndex(index) { + duplicates.append(entry) + } + entries[id] = entry + newResults.append(NewRecord(entry: entry)) + } + + var oldResults = ContiguousArray() + oldResults.reserveCapacity(old.count) + + for index in old.indices { + let id = old[index].diffIdentifier + let entry = entries[id] + entry?.pushOldIndex(index) + oldResults.append(OldRecord(entry: entry)) + } + + for newIndex in new.indices { + let entry = newResults[newIndex].entry + if let oldIndex = entry.popOldIndex() { + let newItem = new[newIndex] + let oldItem = other[oldIndex] + + if !oldItem.isDiffableItemEqual(to: newItem) { + entry.isUpdated = true + } + + newResults[newIndex].correspondingOldIndex = oldIndex + oldResults[oldIndex].correspondingNewIndex = newIndex + } + } + + var deletes = [Int]() + var deleteOffsets = [Int]() + deleteOffsets.reserveCapacity(old.count) + var runningDeleteOffset = 0 + + for index in old.indices { + deleteOffsets.append(runningDeleteOffset) + + let record = oldResults[index] + + if record.correspondingNewIndex == nil { + deletes.append(index) + runningDeleteOffset += 1 + } + } + + var inserts = [Int]() + var updates = [(Int, Int)]() + var moves = [(Int, Int)]() + var insertOffsets = [Int]() + insertOffsets.reserveCapacity(new.count) + var runningInsertOffset = 0 + + for index in new.indices { + insertOffsets.append(runningInsertOffset) + + let record = newResults[index] + + if let oldArrayIndex = record.correspondingOldIndex { + if record.entry.isUpdated { + updates.append((oldArrayIndex, index)) + } + + let insertOffset = insertOffsets[index] + let deleteOffset = deleteOffsets[oldArrayIndex] + if (oldArrayIndex - deleteOffset + insertOffset) != index { + moves.append((oldArrayIndex, index)) + } + + } else { + inserts.append(index) + runningInsertOffset += 1 + } + } + + EpoxyLogger.shared.assert( + old.count + inserts.count - deletes.count == new.count, + "Failed sanity check for old count with changes matching new count.") + + return IndexChangeset( + inserts: inserts, + deletes: deletes, + updates: updates, + moves: moves, + newIndices: oldResults.map { $0.correspondingNewIndex }, + duplicates: duplicates.map { $0.newIndices }) + } + + /// Diffs between two collections (eg. `Array`s) of `Diffable` items, and returns an `IndexPathChangeset` + /// representing the minimal set of changes to get from the other collection to this collection. + /// + /// - Parameters: + /// - from other: The collection of old data. + /// - fromSection: The section the other collection's data exists within. Defaults to `0`. + /// - toSection: The section this collection's data exists within. Defaults to `0`. + func makeIndexPathChangeset( + from other: Self, + fromSection: Int = 0, + toSection: Int = 0) + -> IndexPathChangeset + { + let indexChangeset = makeChangeset(from: other) + + return IndexPathChangeset( + inserts: indexChangeset.inserts.map { index in + [toSection, index] + }, + deletes: indexChangeset.deletes.map { index in + [fromSection, index] + }, + updates: indexChangeset.updates.map { fromIndex, toIndex in + ([fromSection, fromIndex], [toSection, toIndex]) + }, + moves: indexChangeset.moves.map { fromIndex, toIndex in + ([fromSection, fromIndex], [toSection, toIndex]) + }, + duplicates: indexChangeset.duplicates.map { duplicate in + duplicate.map { index in + [toSection, index] + } + }) + } + + /// Diffs between two collections (e.g. `Array`s) of `Diffable` items, returning an + /// `IndexSetChangeset` representing the minimal set of changes to get from the other collection + /// to this collection. + /// + /// - Parameters: + /// - from other: The collection of old data. + func makeIndexSetChangeset(from other: Self) -> IndexSetChangeset { + let indexChangeset = makeChangeset(from: other) + + return IndexSetChangeset( + inserts: .init(indexChangeset.inserts), + deletes: .init(indexChangeset.deletes), + updates: indexChangeset.updates, + moves: indexChangeset.moves, + newIndices: indexChangeset.newIndices, + duplicates: indexChangeset.duplicates.map { .init($0) }) + } + +} + +extension Collection where Element: DiffableSection, Index == Int { + /// Diffs between two collections (e.g. `Array`s) of `DiffableSection` items, returning an + /// `SectionedChangeset` representing the minimal set of changes to get from the other collection + /// to this collection. + /// + /// - Parameters: + /// - from other: The collection of old data. + func makeSectionedChangeset(from other: Self) -> SectionedChangeset { + let sectionChangeset = makeIndexSetChangeset(from: other) + var itemChangeset = IndexPathChangeset() + + for fromSectionIndex in other.indices { + guard let toSectionIndex = sectionChangeset.newIndices[fromSectionIndex] else { + continue + } + + let fromItems = other[fromSectionIndex].diffableItems + let toItems = self[toSectionIndex].diffableItems + + let itemIndexChangeset = toItems.makeIndexPathChangeset( + from: fromItems, + fromSection: fromSectionIndex, + toSection: toSectionIndex) + + itemChangeset += itemIndexChangeset + } + + return SectionedChangeset(sectionChangeset: sectionChangeset, itemChangeset: itemChangeset) + } +} + +// MARK: - EpoxyEntry + +/// A bookkeeping refrence type for the diffing algorithm. +private final class EpoxyEntry { + + // MARK: Internal + + private(set) var oldIndices = [Int]() + private(set) var newIndices = [Int]() + var isUpdated = false + + /// Tracks an index from the new indices, returning `true` if this entry has previously tracked + /// a new index as a means to identify duplicates and `false` otherwise. + func trackNewIndex(_ index: Int) -> Bool { + let previouslyEmpty = newIndices.isEmpty + + newIndices.append(index) + + // We've encountered a duplicate, return true so we can track it. + if !previouslyEmpty, newIndices.count == 2 { + return true + } + + return false + } + + func pushOldIndex(_ index: Int) { + oldIndices.append(index) + } + + func popOldIndex() -> Int? { + guard currentOldIndex < oldIndices.endIndex else { + return nil + } + defer { + currentOldIndex += 1 + } + return oldIndices[currentOldIndex] + } + + // MARK: Private + + private var currentOldIndex = 0 +} + +// MARK: - OldRecord + +/// A bookkeeping type for pairing up an old element with its new index. +private struct OldRecord { + var entry: EpoxyEntry? + var correspondingNewIndex: Int? = nil +} + +// MARK: - NewRecord + +/// A bookkeeping type for pairing up a new element with its old index. +private struct NewRecord { + var entry: EpoxyEntry + var correspondingOldIndex: Int? = nil +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Diffable.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Diffable.swift new file mode 100644 index 00000000..4cb0b2d2 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Diffable.swift @@ -0,0 +1,18 @@ +// Created by Laura Skelton on 5/11/17. +// Copyright © 2017 Airbnb. All rights reserved. + +// MARK: - Diffable + +/// A protocol that allows us to check identity and equality between items for the purposes of +/// diffing. +protocol Diffable { + + /// Checks for equality between items when diffing. + /// + /// - Parameters: + /// - otherDiffableItem: The other item to check equality against while diffing. + func isDiffableItemEqual(to otherDiffableItem: Diffable) -> Bool + + /// The identifier to use when checking identity while diffing. + var diffIdentifier: AnyHashable { get } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/DiffableSection.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/DiffableSection.swift new file mode 100644 index 00000000..acbf93a6 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/DiffableSection.swift @@ -0,0 +1,16 @@ +// Created by eric_horacek on 12/9/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - DiffableSection + +/// A protocol that allows us to check identity and equality between sections of `Diffable` items +/// for the purposes of diffing. +protocol DiffableSection: Diffable { + /// The diffable items in this section. + associatedtype DiffableItems: Collection where + DiffableItems.Index == Int, + DiffableItems.Element: Diffable + + /// The diffable items in this section. + var diffableItems: DiffableItems { get } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift new file mode 100644 index 00000000..2cb8653d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift @@ -0,0 +1,187 @@ +// Created by Laura Skelton on 11/25/16. +// Copyright © 2016 Airbnb. All rights reserved. + +import Foundation + +// MARK: - IndexChangeset + +/// A set of inserts, deletes, updates, and moves that define the changes between two collections. +struct IndexChangeset { + + // MARK: Lifecycle + + init( + inserts: [Int] = [], + deletes: [Int] = [], + updates: [(old: Int, new: Int)] = [], + moves: [(old: Int, new: Int)] = [], + newIndices: [Int?] = [], + duplicates: [[Int]] = []) + { + self.inserts = inserts + self.deletes = deletes + self.updates = updates + self.moves = moves + self.newIndices = newIndices + self.duplicates = duplicates + } + + // MARK: Internal + + /// The inserted indices needed to get from the old collection to the new collection. + var inserts: [Int] + + /// The deleted indices needed to get from the old collection to the new collection. + var deletes: [Int] + + /// The updated indices needed to get from the old collection to the new collection. + var updates: [(old: Int, new: Int)] + + /// The moved indices needed to get from the old collection to the new collection. + var moves: [(old: Int, new: Int)] + + /// A record for each old collection item to its index (if any) is in the new collection. + /// + /// The indexes of this `Array` represent the indexes old collection, with elements of the + /// corresponding index of the same item in the new collection it exists, else `nil`. + var newIndices: [Int?] + + /// A record of each element in the new collection that has an identical `diffIdentifier` with + /// another element in the same collection. + /// + /// Each element in the outer `Array` corresponds to a duplicated identifier, with each inner + /// `[Int]` containing the indexes that share a duplicate identifier in the new collection. + /// + /// While the diffing algorithm makes a best effort to handle duplicates, they can lead to + /// unexpected behavior since identity of elements cannot be established and should be avoided if + /// possible. + var duplicates: [[Int]] + + /// Whether there are any inserts, deletes, moves, or updates in this changeset. + var isEmpty: Bool { + inserts.isEmpty && deletes.isEmpty && updates.isEmpty && moves.isEmpty + } +} + +// MARK: - IndexPathChangeset + +/// A set of inserts, deletes, updates, and moves that define the changes between two collections +/// with indexes stored as `IndexPath`s. +struct IndexPathChangeset { + + // MARK: Lifecycle + + init( + inserts: [IndexPath] = [], + deletes: [IndexPath] = [], + updates: [(old: IndexPath, new: IndexPath)] = [], + moves: [(old: IndexPath, new: IndexPath)] = [], + duplicates: [[IndexPath]] = []) + { + self.inserts = inserts + self.deletes = deletes + self.updates = updates + self.moves = moves + self.duplicates = duplicates + } + + // MARK: Internal + + /// The inserted `IndexPath`s needed to get from the old collection to the new collection. + var inserts: [IndexPath] + + /// The deleted `IndexPath`s needed to get from the old collection to the new collection. + var deletes: [IndexPath] + + /// The updated `IndexPath`s needed to get from the old collection to the new collection. + var updates: [(old: IndexPath, new: IndexPath)] + + /// The moved `IndexPath`s needed to get from the old collection to the new collection. + var moves: [(old: IndexPath, new: IndexPath)] + + /// A record for each element in the new collection that has an identical `diffIdentifier` with + /// another element in the same collection. + /// + /// Each element in the outer `Array` corresponds to a duplicated identifier, with each inner + /// `[IndexPath]` corresponding to the indexes that share a duplicate identifier in the new + /// collection. + /// + /// While the diffing algorithm makes a best effort to handle duplicates, they can lead to + /// unexpected behavior since identity of elements cannot be established and should be avoided if + /// possible. + var duplicates: [[IndexPath]] + + /// Whether there are any inserts, deletes, moves, or updates in this changeset. + var isEmpty: Bool { + inserts.isEmpty && deletes.isEmpty && updates.isEmpty && moves.isEmpty + } + + static func += (left: inout IndexPathChangeset, right: IndexPathChangeset) { + left.inserts += right.inserts + left.deletes += right.deletes + left.updates += right.updates + left.moves += right.moves + left.duplicates += right.duplicates + } +} + +// MARK: - IndexSetChangeset + +/// A set of inserts, deletes, updates, and moves that define the changes between two collections +/// with indexes stored as `IndexSet`. +struct IndexSetChangeset { + + // MARK: Lifecycle + + init( + inserts: IndexSet = [], + deletes: IndexSet = [], + updates: [(old: Int, new: Int)] = [], + moves: [(old: Int, new: Int)] = [], + newIndices: [Int?] = [], + duplicates: [IndexSet] = []) + { + self.inserts = inserts + self.deletes = deletes + self.updates = updates + self.moves = moves + self.newIndices = newIndices + self.duplicates = duplicates + } + + // MARK: Internal + + /// An `IndexSet` of inserts needed to get from the old collection to the new collection. + var inserts: IndexSet + + /// An `IndexSet` of deletes needed to get from the old collection to the new collection. + var deletes: IndexSet + + /// The updated indices needed to get from the old collection to the new collection. + var updates: [(old: Int, new: Int)] + + /// The moved indices needed to get from the old collection to the new collection. + var moves: [(old: Int, new: Int)] + + /// A record for each old collection item of what its index (if any) is in the new collection. + /// + /// The indexes of this `Array` represent the indexes old collection, with elements of the + /// corresponding index of the same item in the new collection it exists, else `nil`. + var newIndices: [Int?] + + /// A record for each element in the new collection that has an identical `diffIdentifier` with + /// another element in the same collection. + /// + /// Each element in the `Array` corresponds to a duplicated identifier, with each `IndexSet` + /// containing the indexes that share a duplicate identifier in the new collection. + /// + /// While the diffing algorithm makes a best effort to handle duplicates, they can lead to + /// unexpected behavior since identity of elements cannot be established and should be avoided if + /// possible. + var duplicates: [IndexSet] + + /// Whether there are any inserts, deletes, moves, or updates in this changeset. + var isEmpty: Bool { + inserts.isEmpty && deletes.isEmpty && updates.isEmpty && moves.isEmpty + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/SectionedChangeset.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/SectionedChangeset.swift new file mode 100644 index 00000000..f18fae57 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/SectionedChangeset.swift @@ -0,0 +1,32 @@ +// Created by Laura Skelton on 5/11/17. +// Copyright © 2017 Airbnb. All rights reserved. + +/// A set of the minimum changes to get from one array of `DiffableSection`s to another, used for +/// diffing. +struct SectionedChangeset { + + // MARK: Lifecycle + + init( + sectionChangeset: IndexSetChangeset, + itemChangeset: IndexPathChangeset) + { + self.sectionChangeset = sectionChangeset + self.itemChangeset = itemChangeset + } + + // MARK: Internal + + /// A set of the minimum changes to get from one set of sections to another. + var sectionChangeset: IndexSetChangeset + + /// A set of the minimum changes to get from one set of items to another, aggregated across all + /// sections. + var itemChangeset: IndexPathChangeset + + /// Whether there are any inserts, deletes, moves, or updates in this changeset. + var isEmpty: Bool { + sectionChangeset.isEmpty && itemChangeset.isEmpty + } + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift new file mode 100644 index 00000000..405c4d7f --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift @@ -0,0 +1,99 @@ +// Created by eric_horacek on 12/9/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +/// A shared logger that allows consumers to intercept Epoxy assertions and warning messages to pipe +/// into their own logging systems. +final class EpoxyLogger { + + // MARK: Lifecycle + + init( + assert: @escaping Assert = { condition, message, file, line in + // If we default to `Swift.assert` directly with `assert: Assert = Swift.assert`, + // the call will unexpectedly not respect the -O flag and will crash in release + // https://github.com/apple/swift/issues/60249 + Swift.assert(condition(), message(), file: file, line: line) + }, + assertionFailure: @escaping AssertionFailure = { message, file, line in + // If we default to `Swift.assertionFailure` directly with + // `assertionFailure: AssertionFailure = Swift.assertionFailure`, + // the call will unexpectedly not respect the -O flag and will crash in release + // https://github.com/apple/swift/issues/60249 + Swift.assertionFailure(message(), file: file, line: line) + }, + warn: @escaping Warn = { message, _, _ in + #if DEBUG + // swiftlint:disable:next no_direct_standard_out_logs + print(message()) + #endif + }) + { + _assert = assert + _assertionFailure = assertionFailure + _warn = warn + } + + // MARK: Internal + + /// Logs that an assertion occurred. + typealias Assert = ( + _ condition: @autoclosure () -> Bool, + _ message: @autoclosure () -> String, + _ fileID: StaticString, + _ line: UInt) + -> Void + + /// Logs that an assertion failure occurred. + typealias AssertionFailure = ( + _ message: @autoclosure () -> String, + _ fileID: StaticString, + _ line: UInt) + -> Void + + /// Logs a warning message. + typealias Warn = ( + _ message: @autoclosure () -> String, + _ fileID: StaticString, + _ line: UInt) + -> Void + + /// The shared instance used to log Epoxy assertions and warnings. + /// + /// Set this to a new logger instance to intercept assertions and warnings logged by Epoxy. + static var shared = EpoxyLogger() + + /// Logs that an assertion occurred. + func assert( + _ condition: @autoclosure () -> Bool, + _ message: @autoclosure () -> String = String(), + fileID: StaticString = #fileID, + line: UInt = #line) + { + _assert(condition(), message(), fileID, line) + } + + /// Logs that an assertion failure occurred. + func assertionFailure( + _ message: @autoclosure () -> String = String(), + fileID: StaticString = #fileID, + line: UInt = #line) + { + _assertionFailure(message(), fileID, line) + } + + /// Logs a warning message. + func warn( + _ message: @autoclosure () -> String = String(), + fileID: StaticString = #fileID, + line: UInt = #line) + { + _warn(message(), fileID, line) + } + + // MARK: Private + + private let _assert: Assert + private let _assertionFailure: AssertionFailure + private let _warn: Warn + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/CallbackContextEpoxyModeled.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/CallbackContextEpoxyModeled.swift new file mode 100644 index 00000000..7a6ecbc0 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/CallbackContextEpoxyModeled.swift @@ -0,0 +1,8 @@ +// Created by eric_horacek on 12/15/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +/// An Epoxy model with an associated context type that's passed into callback closures. +protocol CallbackContextEpoxyModeled: EpoxyModeled { + /// A context type that's passed into callback closures. + associatedtype CallbackContext +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift new file mode 100644 index 00000000..a846ba27 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift @@ -0,0 +1,48 @@ +// Created by eric_horacek on 3/15/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +/// A generic result builder that enables a DSL for building arrays of Epoxy models. +@resultBuilder +enum EpoxyModelArrayBuilder { + typealias Expression = Model + typealias Component = [Model] + + static func buildExpression(_ expression: Expression) -> Component { + [expression] + } + + static func buildExpression(_ expression: Component) -> Component { + expression + } + + static func buildExpression(_ expression: Expression?) -> Component { + if let expression { + return [expression] + } + return [] + } + + static func buildBlock(_ children: Component...) -> Component { + children.flatMap { $0 } + } + + static func buildBlock(_ component: Component) -> Component { + component + } + + static func buildOptional(_ children: Component?) -> Component { + children ?? [] + } + + static func buildEither(first child: Component) -> Component { + child + } + + static func buildEither(second child: Component) -> Component { + child + } + + static func buildArray(_ components: [Component]) -> Component { + components.flatMap { $0 } + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift new file mode 100644 index 00000000..a7905cb5 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift @@ -0,0 +1,158 @@ +// Created by eric_horacek on 11/18/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - EpoxyModelProperty + +/// A property that can be stored in any concrete `EpoxyModeled` type. +/// +/// Custom model properties can be declared in any module. It's recommended that properties are +/// declared as `var`s in extensions to `EpoxyModeled` with a `*Property` suffix. +/// +/// For example, to declare a `EpoxyModelProperty` that fulfills the `TitleProviding` protocol: +/// +/// ```` +/// internal protocol TitleProviding { +/// var title: String? { get } +/// } +/// +/// extension EpoxyModeled where Self: TitleProviding { +/// internal var title: String? { +/// get { self[titleProperty] } +/// set { self[titleProperty] = newValue } +/// } +/// +/// internal func title(_ value: String?) -> Self { +/// copy(updating: titleProperty, to: value) +/// } +/// +/// private var titleProperty: EpoxyModelProperty { +/// .init(keyPath: \TitleProviding.title, defaultValue: nil, updateStrategy: .replace) +/// } +/// } +/// ```` +struct EpoxyModelProperty { + + // MARK: Lifecycle + + /// Creates a property identified by a `KeyPath` to its provided `value` and with its default + /// value if not customized in content by consumers. + /// + /// The `updateStrategy` is used to update the value when updating from an old value to a new + /// value. + init( + keyPath: KeyPath, + defaultValue: @escaping @autoclosure () -> Value, + updateStrategy: UpdateStrategy) + { + self.keyPath = keyPath + self.defaultValue = defaultValue + self.updateStrategy = updateStrategy + } + + // MARK: Internal + + /// The `KeyPath` that uniquely identifies this property. + let keyPath: AnyKeyPath + + /// A closure that produces the default property value when called. + let defaultValue: () -> Value + + /// A closure used to update an `EpoxyModelProperty` from an old value to a new value. + let updateStrategy: UpdateStrategy + +} + +// MARK: EpoxyModelProperty.UpdateStrategy + +extension EpoxyModelProperty { + /// A closure used to update an `EpoxyModelProperty` from an old value to a new value. + struct UpdateStrategy { + + // MARK: Lifecycle + + init(update: @escaping (Value, Value) -> Value) { + self.update = update + } + + // MARK: Public + + /// A closure used to update an `EpoxyModelProperty` from an old value to a new value. + var update: (_ old: Value, _ new: Value) -> Value + } +} + +// MARK: Defaults + +extension EpoxyModelProperty.UpdateStrategy { + /// Replaces the old value with the new value when an update occurs. + static var replace: Self { + .init { _, new in new } + } + + /// Chains the new closure value onto the old closure value, returning a new closure that first + /// calls the old closure and then subsequently calls the new closure. + static func chain() -> EpoxyModelProperty<(() -> Void)?>.UpdateStrategy { + .init { old, new in + guard let new else { return old } + guard let old else { return new } + return { + old() + new() + } + } + } + + /// Chains the new closure value onto the old closure value, returning a new closure that first + /// calls the old closure and then subsequently calls the new closure. + static func chain() -> EpoxyModelProperty<((A) -> Void)?>.UpdateStrategy { + .init { old, new in + guard let new else { return old } + guard let old else { return new } + return { a in + old(a) + new(a) + } + } + } + + /// Chains the new closure value onto the old closure value, returning a new closure that first + /// calls the old closure and then subsequently calls the new closure. + static func chain() -> EpoxyModelProperty<((A, B) -> Void)?>.UpdateStrategy { + .init { old, new in + guard let new else { return old } + guard let old else { return new } + return { a, b in + old(a, b) + new(a, b) + } + } + } + + /// Chains the new closure value onto the old closure value, returning a new closure that first + /// calls the old closure and then subsequently calls the new closure. + static func chain() -> EpoxyModelProperty<((A, B, C) -> Void)?>.UpdateStrategy { + .init { old, new in + guard let new else { return old } + guard let old else { return new } + return { a, b, c in + old(a, b, c) + new(a, b, c) + } + } + } + + /// Chains the new closure value onto the old closure value, returning a new closure that first + /// calls the old closure and then subsequently calls the new closure. + static func chain() -> EpoxyModelProperty<((A, B, C, D) -> Void)?>.UpdateStrategy { + .init { old, new in + guard let new else { return old } + guard let old else { return new } + return { a, b, c, d in + old(a, b, c, d) + new(a, b, c, d) + } + } + } + + // Add more arities as needed +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelStorage.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelStorage.swift new file mode 100644 index 00000000..e6377cba --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelStorage.swift @@ -0,0 +1,88 @@ +// Created by eric_horacek on 11/18/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - EpoxyModelStorage + +/// The underlying storage for an `EpoxyModeled` model that is capable of storing any +/// `EpoxyModelProperty`. +/// +/// Supports being extended with additional storage capabilities in other modules and conditionally +/// based on the provider capabilities that the content containing this storage conforms to. +struct EpoxyModelStorage { + + // MARK: Lifecycle + + init() { } + + // MARK: Internal + + /// Stores or retrieves the value of the specified property. + subscript(property: EpoxyModelProperty) -> Property { + get { + guard let propertyStorage = storage[property.keyPath] else { + return property.defaultValue() + } + + // This cast will never fail as the storage is only settable via this subscript and the + // `KeyPath` key is unique for any provider and value type pair. + // swiftlint:disable:next force_cast + return propertyStorage.value as! Property + } + set { + // We first update the value without using the `updateStrategy` since the likely scenario + // is that there won't be a collision that requires the `updateStrategy`, and we'll be able to + // return without incurring the cost of another write. + let propertyStorage = PropertyStorage(value: newValue, property: property) + + guard var replaced = storage.updateValue(propertyStorage, forKey: property.keyPath) else { + return + } + + // This cast will never fail as the storage is only settable via this subscript and the + // `KeyPath` key is unique for any provider and value type pair. + // swiftlint:disable:next force_cast + replaced.value = property.updateStrategy.update(replaced.value as! Property, newValue) + + storage[property.keyPath] = replaced + } + } + + /// Merges the given storage into this storage. + /// + /// In the case of a collision, the `UpdateStrategy` of the property is used to determine the + /// resulting value in this storage. + mutating func merge(_ other: Self) { + for (key, otherValue) in other.storage { + // We first update the value without using the `updateStrategy` since the likely scenario + // is that there won't be a collision that requires the `updateStrategy`, and we'll be able to + // return without incurring the cost of another write. + guard var replaced = storage.updateValue(otherValue, forKey: key) else { + continue + } + + replaced.value = replaced.property.update(old: replaced.value, new: otherValue.value) + + storage[key] = replaced + } + } + + // MARK: Private + + /// The underlying storage for the properties, with a key of the `EpoxyModelProperty.keyPath` and + /// a value of the property's `PropertyStorage`. + /// + /// Does not include default values. + private var storage = [AnyKeyPath: PropertyStorage]() + +} + +// MARK: - PropertyStorage + +/// A value stored within an `EpoxyModelStorage`. +private struct PropertyStorage { + /// The type-erased value of the `EpoxyModelProperty`. + var value: Any + + /// The property's corresponding `EpoxyModelProperty`, erased to an `AnyEpoxyModelProperty`. + var property: AnyEpoxyModelProperty +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModeled.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModeled.swift new file mode 100644 index 00000000..98e6787d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModeled.swift @@ -0,0 +1,54 @@ +// Created by eric_horacek on 11/18/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - EpoxyModeled + +/// A protocol that all concrete Epoxy declarative UI model types conform to. +/// +/// This protocol should be conditionally extended to fulfill provider protocols and with chainable +/// setters for those providers that concrete model types can receive by declaring conformance to +/// provider protocols. +protocol EpoxyModeled { + /// The underlying storage of this model that stores the current property values. + var storage: EpoxyModelStorage { get set } +} + +// MARK: Extensions + +extension EpoxyModeled { + /// Stores or retrieves a value of the specified property in `storage`. + /// + /// If the value was set previously for the given `property`, the conflict is resolved using the + /// `EpoxyModelProperty.UpdateStrategy` of the `property`. + subscript(property: EpoxyModelProperty) -> Property { + get { storage[property] } + set { storage[property] = newValue } + } + + /// Returns a copy of this model with the given property updated to the provided value. + /// + /// Typically called from within the context of a chainable setter to allow fluent setting of a + /// property, e.g.: + /// + /// ```` + /// internal func title(_ value: String?) -> Self { + /// copy(updating: titleProperty, to: value) + /// } + /// ```` + /// + /// If a `value` was set previously for the given `property`, the conflict is resolved using the + /// `EpoxyModelProperty.UpdateStrategy` of the `property`. + func copy(updating property: EpoxyModelProperty, to value: Value) -> Self { + var copy = self + copy.storage[property] = value + return copy + } + + /// Returns a copy of this model produced by merging the given `other` model's storage into this + /// model's storage. + func merging(_ other: EpoxyModeled) -> Self { + var copy = self + copy.storage.merge(other.storage) + return copy + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/AnyEpoxyModelProperty.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/AnyEpoxyModelProperty.swift new file mode 100644 index 00000000..f5fb10ab --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/AnyEpoxyModelProperty.swift @@ -0,0 +1,29 @@ +// Created by eric_horacek on 12/1/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - AnyEpoxyModelProperty + +/// An erased `EpoxyModelProperty`, with the ability to call the `UpdateStrategy` even when the type +/// has been erased. +protocol AnyEpoxyModelProperty { + /// Returns the updated property from updating from given old to new property. + func update(old: Any, new: Any) -> Any +} + +// MARK: - EpoxyModelProperty + AnyEpoxyModelProperty + +extension EpoxyModelProperty: AnyEpoxyModelProperty { + func update(old: Any, new: Any) -> Any { + guard let typedOld = old as? Value else { + EpoxyLogger.shared.assertionFailure( + "Expected old to be of type \(Value.self), instead found \(old). This is programmer error.") + return defaultValue() + } + guard let typedNew = new as? Value else { + EpoxyLogger.shared.assertionFailure( + "Expected new to be of type \(Value.self), instead found \(old). This is programmer error.") + return defaultValue() + } + return updateStrategy.update(typedOld, typedNew) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/ClassReference.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/ClassReference.swift new file mode 100644 index 00000000..e3edc246 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/ClassReference.swift @@ -0,0 +1,39 @@ +// Created by Cal Stephens on 10/15/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +// MARK: - ClassReference + +/// A `Hashable` value wrapper around an `AnyClass` value +/// - Unlike `ObjectIdentifier(class)`, `ClassReference(class)` +/// preserves the `AnyClass` value and is more human-readable. +struct ClassReference { + init(_ class: AnyClass) { + self.class = `class` + } + + let `class`: AnyClass +} + +// MARK: Equatable + +extension ClassReference: Equatable { + static func ==(_ lhs: Self, _ rhs: Self) -> Bool { + ObjectIdentifier(lhs.class) == ObjectIdentifier(rhs.class) + } +} + +// MARK: Hashable + +extension ClassReference: Hashable { + func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(`class`)) + } +} + +// MARK: CustomStringConvertible + +extension ClassReference: CustomStringConvertible { + var description: String { + String(describing: `class`) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/AnimatedProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/AnimatedProviding.swift new file mode 100644 index 00000000..1862b251 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/AnimatedProviding.swift @@ -0,0 +1,10 @@ +// Created by eric_horacek on 12/16/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +/// The capability of providing a flag indicating whether an operation should be animated. +/// +/// Typically conformed to by the `CallbackContext` of a `CallbackContextEpoxyModeled`. +protocol AnimatedProviding { + /// Whether this operation should be animated. + var animated: Bool { get } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DataIDProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DataIDProviding.swift new file mode 100644 index 00000000..bf82156d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DataIDProviding.swift @@ -0,0 +1,57 @@ +// Created by eric_horacek on 12/1/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - DataIDProviding + +/// The capability of providing a stable data identifier with an erased type. +/// +/// While it has similar semantics, this type cannot inherit from `Identifiable` as this would give +/// it an associated type, which would cause the `keyPath` used in its `EpoxyModelProperty` to not +/// be stable across types if written as `\Self.dataID` since the `KeyPath` `Root` would be +/// different for each type. +/// +/// - SeeAlso: `Identifiable`. +protocol DataIDProviding { + /// A stable identifier that uniquely identifies this instance, with its typed erased. + /// + /// Defaults to `DefaultDataID.noneProvided` if no data ID is provided. + var dataID: AnyHashable { get } +} + +// MARK: - EpoxyModeled + +extension EpoxyModeled where Self: DataIDProviding { + + // MARK: Internal + + /// A stable identifier that uniquely identifies this model, with its typed erased. + var dataID: AnyHashable { + get { self[dataIDProperty] } + set { self[dataIDProperty] = newValue } + } + + /// Returns a copy of this model with the ID replaced with the provided ID. + func dataID(_ value: AnyHashable) -> Self { + copy(updating: dataIDProperty, to: value) + } + + // MARK: Private + + private var dataIDProperty: EpoxyModelProperty { + EpoxyModelProperty( + keyPath: \DataIDProviding.dataID, + defaultValue: DefaultDataID.noneProvided, + updateStrategy: .replace) + } +} + +// MARK: - DefaultDataID + +/// The default data ID when none is provided. +enum DefaultDataID: Hashable, CustomDebugStringConvertible { + case noneProvided + + var debugDescription: String { + "DefaultDataID.noneProvided" + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidDisplayProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidDisplayProviding.swift new file mode 100644 index 00000000..5a2f2cbb --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidDisplayProviding.swift @@ -0,0 +1,41 @@ +// Created by eric_horacek on 1/6/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +// MARK: - DidDisplayProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a `didDisplay` +/// closure property. +/// +/// - SeeAlso: `WillDisplayProviding` +/// - SeeAlso: `DidEndDisplayingProviding` +protocol DidDisplayProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: DidDisplayProviding { + + // MARK: Internal + + /// A closure that's called after a view has been added to the view hierarchy following any + /// appearance animations. + typealias DidDisplay = (_ context: CallbackContext) -> Void + + /// A closure that's called after the view has been added to the view hierarchy following any + /// appearance animations. + var didDisplay: DidDisplay? { + get { self[didDisplayProperty] } + set { self[didDisplayProperty] = newValue } + } + + /// Returns a copy of this model with the given did display closure called after the current did + /// display closure of this model, if there is one. + func didDisplay(_ value: DidDisplay?) -> Self { + copy(updating: didDisplayProperty, to: value) + } + + // MARK: Private + + private var didDisplayProperty: EpoxyModelProperty { + .init(keyPath: \Self.didDisplay, defaultValue: nil, updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidEndDisplayingProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidEndDisplayingProviding.swift new file mode 100644 index 00000000..db71be6d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidEndDisplayingProviding.swift @@ -0,0 +1,41 @@ +// Created by eric_horacek on 12/15/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - DidEndDisplayingProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a +/// `didEndDisplaying` closure property. +protocol DidEndDisplayingProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: DidEndDisplayingProviding { + + // MARK: Internal + + /// A closure that's called when a view is no longer displayed following any disappearance + /// animations and when it has been removed from the view hierarchy. + typealias DidEndDisplaying = (_ context: CallbackContext) -> Void + + /// A closure that's called when the view is no longer displayed following any disappearance + /// animations and when it has been removed from the view hierarchy. + var didEndDisplaying: DidEndDisplaying? { + get { self[didEndDisplayingProperty] } + set { self[didEndDisplayingProperty] = newValue } + } + + /// Returns a copy of this model with the given did end displaying closure called after the + /// current did end displaying closure of this model, if there is one. + func didEndDisplaying(_ value: DidEndDisplaying?) -> Self { + copy(updating: didEndDisplayingProperty, to: value) + } + + // MARK: Private + + private var didEndDisplayingProperty: EpoxyModelProperty { + .init( + keyPath: \Self.didEndDisplaying, + defaultValue: nil, + updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidSelectProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidSelectProviding.swift new file mode 100644 index 00000000..007e0244 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidSelectProviding.swift @@ -0,0 +1,36 @@ +// Created by eric_horacek on 12/2/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - DidSelectProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a `didSelect` +/// closure property. +protocol DidSelectProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: DidSelectProviding { + + // MARK: Internal + + /// A closure that's called to handle this model's view being selected. + typealias DidSelect = (CallbackContext) -> Void + + /// A closure that's called to handle this model's view being selected. + var didSelect: DidSelect? { + get { self[didSelectProperty] } + set { self[didSelectProperty] = newValue } + } + + /// Returns a copy of this model with the given did select closure called after the current did + /// select closure of this model, if there is one. + func didSelect(_ value: DidSelect?) -> Self { + copy(updating: didSelectProperty, to: value) + } + + // MARK: Private + + private var didSelectProperty: EpoxyModelProperty { + .init(keyPath: \Self.didSelect, defaultValue: nil, updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ErasedContentProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ErasedContentProviding.swift new file mode 100644 index 00000000..556c3b8c --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ErasedContentProviding.swift @@ -0,0 +1,49 @@ +// Created by eric_horacek on 12/2/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - ErasedContentProviding + +/// The capability of providing an type-erased `Equatable` content instance. +protocol ErasedContentProviding { + /// The type-erased content instance of this model, else `nil` if there is no content. + /// + /// If there was an `AnyEquatable` type, we could store this property using it. Instead we need + /// need to store `isErasedContentEqual` to determine equality. + var erasedContent: Any? { get } + + /// A closure that can be called to determine whether the given `model`'s `erasedContent` is equal + /// to this model's `erasedContent`, else `nil` if there is no content or the content is always + /// equal. + var isErasedContentEqual: ((Self) -> Bool)? { get } +} + +// MARK: - EpoxyModeled + +extension EpoxyModeled where Self: ErasedContentProviding { + + // MARK: Internal + + /// The type-erased content instance of this model, else `nil` if there is no content. + var erasedContent: Any? { + get { self[contentProperty] } + set { self[contentProperty] = newValue } + } + + /// A closure that can be called to determine whether the given `model`'s `erasedContent` is equal + /// to this model's `erasedContent`, else `nil` if there is no content or the content is always + /// equal. + var isErasedContentEqual: ((Self) -> Bool)? { + get { self[isContentEqualProperty] } + set { self[isContentEqualProperty] = newValue } + } + + // MARK: Private + + private var contentProperty: EpoxyModelProperty { + .init(keyPath: \Self.erasedContent, defaultValue: nil, updateStrategy: .replace) + } + + private var isContentEqualProperty: EpoxyModelProperty<((Self) -> Bool)?> { + .init(keyPath: \Self.isErasedContentEqual, defaultValue: nil, updateStrategy: .replace) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/MakeViewProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/MakeViewProviding.swift new file mode 100644 index 00000000..0b4301f4 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/MakeViewProviding.swift @@ -0,0 +1,60 @@ +// Created by eric_horacek on 12/1/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - MakeViewProviding + +/// The capability of constructing a `UIView`. +protocol MakeViewProviding { + /// The view constructed when the `MakeView` closure is called. + associatedtype View: ViewType + + /// A closure that's called to construct an instance of `View`. + typealias MakeView = () -> View + + /// A closure that's called to construct an instance of `View`. + var makeView: MakeView { get } +} + +// MARK: - ViewEpoxyModeled + +extension ViewEpoxyModeled where Self: MakeViewProviding { + + // MARK: Internal + + /// A closure that's called to construct an instance of `View` represented by this model. + var makeView: MakeView { + get { self[makeViewProperty] } + set { self[makeViewProperty] = newValue } + } + + /// Replaces the default closure to construct the view with the given closure. + func makeView(_ value: @escaping MakeView) -> Self { + copy(updating: makeViewProperty, to: value) + } + + // MARK: Private + + private var makeViewProperty: EpoxyModelProperty { + // If you're getting a `EXC_BAD_INSTRUCTION` crash with this property in your stack trace, you + // probably either: + // - Conformed a view to `EpoxyableView` / `StyledView` with a custom initializer that + // takes parameters, or: + // - Used the `EpoxyModeled.init(dataID:)` initializer on a view has required initializer + // parameters. + // If you have parameters to view initialization, they should either be passed to `init(style:)` + // or you should provide a `makeView` closure when constructing your view's corresponding model, + // e.g: + // ``` + // MyView.itemModel(…) + // .makeView { MyView(customParameter: …) } + // .styleID(…) + // ``` + // Note that with the above approach that you must supply an `styleID` with the same identity as + // your view parameters to ensure that views with different parameters are not reused in place + // of one another. + .init( + keyPath: \Self.makeView, + defaultValue: View.init, + updateStrategy: .replace) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetBehaviorsProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetBehaviorsProviding.swift new file mode 100644 index 00000000..a73de043 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetBehaviorsProviding.swift @@ -0,0 +1,38 @@ +// Created by eric_horacek on 12/2/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - SetBehaviorsProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a `setBehaviors` +/// closure property. +protocol SetBehaviorsProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: SetBehaviorsProviding { + + // MARK: Internal + + /// A closure that's called to set the content on this model's view with behaviors (e.g. tap handler + /// closures) whenever this model is updated. + typealias SetBehaviors = (CallbackContext) -> Void + + /// A closure that's called to set the content on this model's view with behaviors (e.g. tap handler + /// closures) whenever this model is updated. + var setBehaviors: SetBehaviors? { + get { self[setBehaviorsProperty] } + set { self[setBehaviorsProperty] = newValue } + } + + /// Returns a copy of this model with the set behaviors closure called after the current set + /// behaviors closure of this model, if there is one. + func setBehaviors(_ value: SetBehaviors?) -> Self { + copy(updating: setBehaviorsProperty, to: value) + } + + // MARK: Private + + private var setBehaviorsProperty: EpoxyModelProperty { + .init(keyPath: \Self.setBehaviors, defaultValue: nil, updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetContentProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetContentProviding.swift new file mode 100644 index 00000000..e1456dce --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetContentProviding.swift @@ -0,0 +1,38 @@ +// Created by eric_horacek on 12/1/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - SetContentProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a `setContent` +/// closure property. +protocol SetContentProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: SetContentProviding { + + // MARK: Internal + + /// A closure that's called to set the content on this model's view when it is first created and + /// subsequently when the content changes. + typealias SetContent = (CallbackContext) -> Void + + /// A closure that's called to set the content on this model's view when it is first created and + /// subsequently when the content changes. + var setContent: SetContent? { + get { self[setContentProperty] } + set { self[setContentProperty] = newValue } + } + + /// Returns a copy of this model with the given setContent view closure called after the current + /// setContent view closure of this model, if there is one. + func setContent(_ value: SetContent?) -> Self { + copy(updating: setContentProperty, to: value) + } + + // MARK: Private + + private var setContentProperty: EpoxyModelProperty { + .init(keyPath: \Self.setContent, defaultValue: nil, updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/StyleIDProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/StyleIDProviding.swift new file mode 100644 index 00000000..8242de12 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/StyleIDProviding.swift @@ -0,0 +1,37 @@ +// Created by eric_horacek on 12/1/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - StyleIDProviding + +protocol StyleIDProviding { + /// An optional ID for a style type to use for reuse of a view. + /// + /// Use this to differentiate between different styling configurations. + var styleID: AnyHashable? { get } +} + +// MARK: - EpoxyModeled + +extension EpoxyModeled where Self: StyleIDProviding { + + // MARK: Internal + + var styleID: AnyHashable? { + get { self[styleIDProperty] } + set { self[styleIDProperty] = newValue } + } + + /// Returns a copy of this model with the `styleID` replaced with the provided `value`. + func styleID(_ value: AnyHashable?) -> Self { + copy(updating: styleIDProperty, to: value) + } + + // MARK: Private + + private var styleIDProperty: EpoxyModelProperty { + .init( + keyPath: \StyleIDProviding.styleID, + defaultValue: nil, + updateStrategy: .replace) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/TraitCollectionProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/TraitCollectionProviding.swift new file mode 100644 index 00000000..e41ac790 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/TraitCollectionProviding.swift @@ -0,0 +1,14 @@ +// Created by eric_horacek on 12/16/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +#if !os(macOS) +import UIKit + +/// The capability of providing a `UITraitCollection` instance. +/// +/// Typically conformed to by the `CallbackContext` of a `CallbackContextEpoxyModeled`. +protocol TraitCollectionProviding { + /// The `UITraitCollection` instance provided by this type. + var traitCollection: UITraitCollection { get } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewDifferentiatorProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewDifferentiatorProviding.swift new file mode 100644 index 00000000..45c0130e --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewDifferentiatorProviding.swift @@ -0,0 +1,34 @@ +// Created by Bryan Keller on 12/17/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - ViewDifferentiatorProviding + +/// The capability of providing a view differentiator that facilitates generating collection view +/// cell reuse identifiers. +protocol ViewDifferentiatorProviding { + /// The view differentiator for the item model. + var viewDifferentiator: ViewDifferentiator { get } +} + +// MARK: - ViewDifferentiator + +/// Facilitates differentiating between two models' views, based on their view type, optional style +/// identifier, and optional element kind for supplementary view models. If two models have the same +/// view differentiator, then they're compatible with one another for element reuse. If two models +/// have different view differentiators, then they're incompatible with one another for element +/// reuse. +struct ViewDifferentiator: Hashable { + + // MARK: Lifecycle + + init(viewType: AnyClass, styleID: AnyHashable?) { + viewTypeDescription = "\(type(of: viewType.self))" + self.styleID = styleID + } + + // MARK: Public + + var viewTypeDescription: String + var styleID: AnyHashable? + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewProviding.swift new file mode 100644 index 00000000..b36eed8c --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewProviding.swift @@ -0,0 +1,13 @@ +// Created by eric_horacek on 12/16/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +/// The capability of providing an `View` instance +/// +/// Typically conformed to by the `CallbackContext` of a `CallbackContextEpoxyModeled`. +protocol ViewProviding { + /// The `UIView` view of this type. + associatedtype View: ViewType + + /// The `UIView` view instance provided by this type. + var view: View { get } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/WillDisplayProviding.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/WillDisplayProviding.swift new file mode 100644 index 00000000..9bf21630 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/WillDisplayProviding.swift @@ -0,0 +1,41 @@ +// Created by eric_horacek on 12/15/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - WillDisplayProviding + +/// A sentinel protocol for enabling an `CallbackContextEpoxyModeled` to provide a `willDisplay` +/// closure property. +/// +/// - SeeAlso: `DidDisplayProviding` +/// - SeeAlso: `DidEndDisplayingProviding` +protocol WillDisplayProviding { } + +// MARK: - CallbackContextEpoxyModeled + +extension CallbackContextEpoxyModeled where Self: WillDisplayProviding { + + // MARK: Internal + + /// A closure that's called when a view is about to be displayed, before it has been added to the + /// view hierarcy. + typealias WillDisplay = (_ context: CallbackContext) -> Void + + /// A closure that's called when the view is about to be displayed, before it has been added to + /// the view hierarcy. + var willDisplay: WillDisplay? { + get { self[willDisplayProperty] } + set { self[willDisplayProperty] = newValue } + } + + /// Returns a copy of this model with the given will display closure called after the current will + /// display closure of this model, if there is one. + func willDisplay(_ value: WillDisplay?) -> Self { + copy(updating: willDisplayProperty, to: value) + } + + // MARK: Private + + private var willDisplayProperty: EpoxyModelProperty { + .init(keyPath: \Self.willDisplay, defaultValue: nil, updateStrategy: .chain()) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/ViewEpoxyModeled.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/ViewEpoxyModeled.swift new file mode 100644 index 00000000..27901b28 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/ViewEpoxyModeled.swift @@ -0,0 +1,10 @@ +// Created by eric_horacek on 12/4/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +/// An Epoxy model with an associated `UIView` type. +protocol ViewEpoxyModeled: EpoxyModeled { + /// The view type associated with this model. + /// + /// An instance of this view is typically configured by this model. + associatedtype View: ViewType +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift new file mode 100644 index 00000000..10e99a95 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift @@ -0,0 +1,46 @@ +// Created by eric_horacek on 10/8/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) && !os(macOS) +import SwiftUI + +// MARK: - EpoxySwiftUIUIHostingController + +/// A `UIHostingController` that hosts SwiftUI views within an Epoxy container, e.g. an Epoxy +/// `CollectionView`. +/// +/// Exposed internally to allow consumers to reason about these view controllers, e.g. to opt +/// collection view cells out of automated view controller impression tracking. +/// +/// - SeeAlso: `EpoxySwiftUIHostingView` +@available(iOS 13.0, tvOS 13.0, *) +open class EpoxySwiftUIHostingController: UIHostingController { + + // MARK: Lifecycle + + /// Creates a `UIHostingController` that optionally ignores the `safeAreaInsets` when laying out + /// its contained `RootView`. + convenience init(rootView: Content, ignoreSafeArea: Bool) { + self.init(rootView: rootView) + + // We unfortunately need to call a private API to disable the safe area. We can also accomplish + // this by dynamically subclassing this view controller's view at runtime and overriding its + // `safeAreaInsets` property and returning `.zero`. An implementation of that logic is + // available in this file in the `2d28b3181cca50b89618b54836f7a9b6e36ea78e` commit if this API + // no longer functions in future SwiftUI versions. + _disableSafeArea = ignoreSafeArea + } + + // MARK: Open + + open override func viewDidLoad() { + super.viewDidLoad() + + // A `UIHostingController` has a system background color by default as it's typically used in + // full-screen use cases. Since we're using this view controller to place SwiftUI views within + // other view controllers we default the background color to clear so we can see the views + // below, e.g. to draw highlight states in a `CollectionView`. + view.backgroundColor = .clear + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift new file mode 100644 index 00000000..c1b8c527 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift @@ -0,0 +1,389 @@ +// Created by eric_horacek on 9/16/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +#if canImport(Combine) && canImport(SwiftUI) && !os(macOS) +import Combine +import SwiftUI + +// MARK: - SwiftUIHostingViewReuseBehavior + +/// The reuse behavior of an `EpoxySwiftUIHostingView`. +enum SwiftUIHostingViewReuseBehavior: Hashable { + /// Instances of a `EpoxySwiftUIHostingView` with `RootView`s of same type can be reused within + /// the Epoxy container. + /// + /// This is the default reuse behavior. + case reusable + /// Instances of a `EpoxySwiftUIHostingView` with `RootView`s of same type can only reused within + /// the Epoxy container when they have identical `reuseID`s. + case unique(reuseID: AnyHashable) +} + +// MARK: - CallbackContextEpoxyModeled + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension CallbackContextEpoxyModeled + where + Self: WillDisplayProviding & DidEndDisplayingProviding, + CallbackContext: ViewProviding & AnimatedProviding +{ + /// Updates the appearance state of a `EpoxySwiftUIHostingView` in coordination with the + /// `willDisplay` and `didEndDisplaying` callbacks of this `EpoxyableModel`. + /// + /// - Note: You should only need to call then from the implementation of a concrete + /// `EpoxyableModel` convenience vendor method, e.g. `SwiftUI.View.itemModel(…)`. + func linkDisplayLifecycle() -> Self + where + CallbackContext.View == EpoxySwiftUIHostingView + { + willDisplay { context in + context.view.handleWillDisplay(animated: context.animated) + } + .didEndDisplaying { context in + context.view.handleDidEndDisplaying(animated: context.animated) + } + } +} + +// MARK: - EpoxySwiftUIHostingView + +/// A `UIView` that hosts a SwiftUI view within an Epoxy container, e.g. an Epoxy `CollectionView`. +/// +/// Wraps an `EpoxySwiftUIHostingController` and adds it as a child view controller to the next +/// ancestor view controller in the hierarchy. +/// +/// There's a private API that accomplishes this same behavior without needing a `UIViewController`: +/// `_UIHostingView`, but we can't safely use it as 1) the behavior may change out from under us, 2) +/// the API is private and 3) the `_UIHostingView` doesn't not accept setting a new `View` instance. +/// +/// - SeeAlso: `EpoxySwiftUIHostingController` +@available(iOS 13.0, tvOS 13.0, *) +final class EpoxySwiftUIHostingView: UIView, EpoxyableView { + + // MARK: Lifecycle + + init(style: Style) { + // Ignore the safe area to ensure the view isn't laid out incorrectly when being sized while + // overlapping the safe area. + epoxyContent = EpoxyHostingContent(rootView: style.initialContent.rootView) + viewController = EpoxySwiftUIHostingController( + rootView: .init(content: epoxyContent, environment: epoxyEnvironment), + ignoreSafeArea: true) + + dataID = style.initialContent.dataID ?? DefaultDataID.noneProvided as AnyHashable + + super.init(frame: .zero) + + epoxyEnvironment.intrinsicContentSizeInvalidator = .init(invalidate: { [weak self] in + self?.viewController.view.invalidateIntrinsicContentSize() + + // Inform the enclosing collection view that the size has changed, if we're contained in one, + // allowing the cell to resize. + // + // On iOS 16+, we could call `invalidateIntrinsicContentSize()` on the enclosing collection + // view cell instead, but that currently causes visual artifacts with `MagazineLayout`. The + // better long term fix is likely to switch to `UIHostingConfiguration` on iOS 16+ anyways. + if let enclosingCollectionView = self?.superview?.superview?.superview as? UICollectionView { + enclosingCollectionView.collectionViewLayout.invalidateLayout() + } + }) + layoutMargins = .zero + } + + @available(*, unavailable) + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Internal + + struct Style: Hashable { + init(reuseBehavior: SwiftUIHostingViewReuseBehavior, initialContent: Content) { + self.reuseBehavior = reuseBehavior + self.initialContent = initialContent + } + + var reuseBehavior: SwiftUIHostingViewReuseBehavior + var initialContent: Content + + static func == (lhs: Style, rhs: Style) -> Bool { + lhs.reuseBehavior == rhs.reuseBehavior + } + + func hash(into hasher: inout Hasher) { + hasher.combine(reuseBehavior) + } + } + + struct Content: Equatable { + init(rootView: RootView, dataID: AnyHashable?) { + self.rootView = rootView + self.dataID = dataID + } + + var rootView: RootView + var dataID: AnyHashable? + + static func == (_: Content, _: Content) -> Bool { + // The content should never be equal since we need the `rootView` to be updated on every + // content change. + false + } + } + + override func didMoveToWindow() { + super.didMoveToWindow() + + // We'll only be able to discover a valid parent `viewController` once we're added to a window, + // so we do so here in addition to the `handleWillDisplay(…)` method. + if window != nil { + addViewControllerIfNeeded() + } + } + + func setContent(_ content: Content, animated _: Bool) { + // This triggers a change in the observed `EpoxyHostingContent` object and allows the + // propagation of the SwiftUI transaction, instead of just replacing the `rootView`. + epoxyContent.rootView = content.rootView + dataID = content.dataID ?? DefaultDataID.noneProvided as AnyHashable + + // The view controller must be added to the view controller hierarchy to measure its content. + if window != nil { + addViewControllerIfNeeded() + } + + // As of iOS 15.2, `UIHostingController` now renders updated content asynchronously, and as such + // this view will get sized incorrectly with the previous content when reused unless we invoke + // this semi-private API. We couldn't find any other method to get the view to resize + // synchronously after updating `rootView`, but hopefully this will become a internal API soon so + // we can remove this call. + viewController._render(seconds: 0) + + // This is required to ensure that views with new content are properly resized. + viewController.view.invalidateIntrinsicContentSize() + } + + override func layoutMarginsDidChange() { + super.layoutMarginsDidChange() + + let margins = layoutMargins + switch effectiveUserInterfaceLayoutDirection { + case .rightToLeft: + epoxyEnvironment.layoutMargins = .init( + top: margins.top, + leading: margins.right, + bottom: margins.bottom, + trailing: margins.left) + case .leftToRight: + fallthrough + @unknown default: + epoxyEnvironment.layoutMargins = .init( + top: margins.top, + leading: margins.left, + bottom: margins.bottom, + trailing: margins.right) + } + + // Allow the layout margins update to fully propagate through to the SwiftUI View before + // invalidating the layout. + DispatchQueue.main.async { + self.viewController.view.invalidateIntrinsicContentSize() + } + } + + func handleWillDisplay(animated: Bool) { + guard state != .appeared, window != nil else { return } + transition(to: .appearing(animated: animated)) + transition(to: .appeared) + } + + func handleDidEndDisplaying(animated: Bool) { + guard state != .disappeared else { return } + transition(to: .disappearing(animated: animated)) + transition(to: .disappeared) + } + + // MARK: Private + + private let viewController: EpoxySwiftUIHostingController> + private let epoxyContent: EpoxyHostingContent + private let epoxyEnvironment = EpoxyHostingEnvironment() + private var dataID: AnyHashable + private var state: AppearanceState = .disappeared + + /// Updates the appearance state of the `viewController`. + private func transition(to state: AppearanceState) { + guard state != self.state else { return } + + // See "Handling View-Related Notifications" section for the state machine diagram. + // https://developer.apple.com/documentation/uikit/uiviewcontroller + switch (to: state, from: self.state) { + case (to: .appearing(let animated), from: .disappeared): + viewController.beginAppearanceTransition(true, animated: animated) + addViewControllerIfNeeded() + case (to: .disappearing(let animated), from: .appeared): + viewController.beginAppearanceTransition(false, animated: animated) + case (to: .disappeared, from: .disappearing): + removeViewControllerIfNeeded() + case (to: .appeared, from: .appearing): + viewController.endAppearanceTransition() + case (to: .disappeared, from: .appeared): + viewController.beginAppearanceTransition(false, animated: true) + removeViewControllerIfNeeded() + case (to: .appeared, from: .disappearing(let animated)): + viewController.beginAppearanceTransition(true, animated: animated) + viewController.endAppearanceTransition() + case (to: .disappeared, from: .appearing(let animated)): + viewController.beginAppearanceTransition(false, animated: animated) + removeViewControllerIfNeeded() + case (to: .appeared, from: .disappeared): + viewController.beginAppearanceTransition(true, animated: false) + addViewControllerIfNeeded() + viewController.endAppearanceTransition() + case (to: .appearing(let animated), from: .appeared): + viewController.beginAppearanceTransition(false, animated: animated) + viewController.beginAppearanceTransition(true, animated: animated) + case (to: .appearing(let animated), from: .disappearing): + viewController.beginAppearanceTransition(true, animated: animated) + case (to: .disappearing(let animated), from: .disappeared): + viewController.beginAppearanceTransition(true, animated: animated) + addViewControllerIfNeeded() + viewController.beginAppearanceTransition(false, animated: animated) + case (to: .disappearing(let animated), from: .appearing): + viewController.beginAppearanceTransition(false, animated: animated) + case (to: .appearing, from: .appearing), + (to: .appeared, from: .appeared), + (to: .disappearing, from: .disappearing), + (to: .disappeared, from: .disappeared): + // This should never happen since we guard on identical states. + EpoxyLogger.shared.assertionFailure("Impossible state change from \(self.state) to \(state)") + } + + self.state = state + } + + private func addViewControllerIfNeeded() { + // This isn't great, and means that we're going to add this view controller as a child view + // controller of a view controller somewhere else in the hierarchy, which the author of that + // view controller may not be expecting. However there's not really a better pathway forward + // here without requiring a view controller instance to be passed all the way through, which is + // both burdensome and error-prone. + guard let nextViewController = superview?.next(UIViewController.self) else { + EpoxyLogger.shared.assertionFailure( + """ + Unable to add a UIHostingController view, could not locate a UIViewController in the \ + responder chain for view with ID \(dataID) of type \(RootView.self). + """) + return + } + + guard viewController.parent !== nextViewController else { return } + + // If in a different parent, we need to first remove from it before we add. + if viewController.parent != nil { + removeViewControllerIfNeeded() + } + + addViewController(to: nextViewController) + + state = .appeared + } + + private func addViewController(to parent: UIViewController) { + viewController.willMove(toParent: parent) + + parent.addChild(viewController) + + addSubview(viewController.view) + + // Get the view controller's view to be sized correctly so that we don't have to wait for + // autolayout to perform a pass to do so. + viewController.view.frame = bounds + + viewController.view.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + viewController.view.leadingAnchor.constraint(equalTo: leadingAnchor), + viewController.view.topAnchor.constraint(equalTo: topAnchor), + viewController.view.trailingAnchor.constraint(equalTo: trailingAnchor), + viewController.view.bottomAnchor.constraint(equalTo: bottomAnchor), + ]) + + viewController.didMove(toParent: parent) + } + + private func removeViewControllerIfNeeded() { + guard viewController.parent != nil else { return } + + viewController.willMove(toParent: nil) + viewController.view.removeFromSuperview() + viewController.removeFromParent() + viewController.didMove(toParent: nil) + } +} + +// MARK: - AppearanceState + +/// The appearance state of a `EpoxySwiftUIHostingController` contained within a +/// `EpoxySwiftUIHostingView`. +private enum AppearanceState: Equatable { + case appearing(animated: Bool) + case appeared + case disappearing(animated: Bool) + case disappeared +} + +// MARK: - UIResponder + +extension UIResponder { + /// Recursively traverses the responder chain upwards from this responder to its next responder + /// until the a responder of the given type is located, else returns `nil`. + @nonobjc + fileprivate func next(_ type: ResponderType.Type) -> ResponderType? { + self as? ResponderType ?? next?.next(type) + } +} + +// MARK: - EpoxyHostingContent + +/// The object that is used to communicate changes in the root view to the +/// `EpoxySwiftUIHostingController`. +@available(iOS 13.0, tvOS 13.0, *) +final class EpoxyHostingContent: ObservableObject { + + // MARK: Lifecycle + + init(rootView: RootView) { + _rootView = .init(wrappedValue: rootView) + } + + // MARK: Internal + + @Published var rootView: RootView +} + +// MARK: - EpoxyHostingEnvironment + +/// The object that is used to communicate values to SwiftUI views within an +/// `EpoxySwiftUIHostingController`, e.g. layout margins. +@available(iOS 13.0, tvOS 13.0, *) +final class EpoxyHostingEnvironment: ObservableObject { + @Published var layoutMargins = EdgeInsets() + @Published var intrinsicContentSizeInvalidator = EpoxyIntrinsicContentSizeInvalidator(invalidate: { }) +} + +// MARK: - EpoxyHostingWrapper + +/// The wrapper view that is used to communicate values to SwiftUI views within an +/// `EpoxySwiftUIHostingController`, e.g. layout margins. +@available(iOS 13.0, tvOS 13.0, *) +struct EpoxyHostingWrapper: View { + @ObservedObject var content: EpoxyHostingContent + @ObservedObject var environment: EpoxyHostingEnvironment + + var body: some View { + content.rootView + .environment(\.epoxyLayoutMargins, environment.layoutMargins) + .environment(\.epoxyIntrinsicContentSizeInvalidator, environment.intrinsicContentSizeInvalidator) + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift new file mode 100644 index 00000000..47ebde44 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift @@ -0,0 +1,46 @@ +// Created by matthew_cheok on 11/19/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - EpoxyIntrinsicContentSizeInvalidator + +/// Allows the SwiftUI view contained in an Epoxy model to request the invalidation of +/// the container's intrinsic content size. +/// +/// ``` +/// @Environment(\.epoxyIntrinsicContentSizeInvalidator) var invalidateIntrinsicContentSize +/// +/// var body: some View { +/// ... +/// .onChange(of: size) { +/// invalidateIntrinsicContentSize() +/// } +/// } +/// ``` +struct EpoxyIntrinsicContentSizeInvalidator { + let invalidate: () -> Void + + func callAsFunction() { + invalidate() + } +} + +// MARK: - EnvironmentValues + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension EnvironmentValues { + /// A means of invalidating the intrinsic content size of the parent `EpoxySwiftUIHostingView`. + var epoxyIntrinsicContentSizeInvalidator: EpoxyIntrinsicContentSizeInvalidator { + get { self[EpoxyIntrinsicContentSizeInvalidatorKey.self] } + set { self[EpoxyIntrinsicContentSizeInvalidatorKey.self] = newValue } + } +} + +// MARK: - EpoxyIntrinsicContentSizeInvalidatorKey + +private struct EpoxyIntrinsicContentSizeInvalidatorKey: EnvironmentKey { + static let defaultValue = EpoxyIntrinsicContentSizeInvalidator(invalidate: { }) +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift new file mode 100644 index 00000000..44fc83fb --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift @@ -0,0 +1,53 @@ +// Created by eric_horacek on 10/8/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - View + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension View { + /// Applies the layout margins from the parent `EpoxySwiftUIHostingView` to this `View`, if there + /// are any. + /// + /// Can be used to have a background in SwiftUI underlap the safe area within a bar installer, for + /// example. + /// + /// These margins are propagated via the `EnvironmentValues.epoxyLayoutMargins`. + func epoxyLayoutMargins() -> some View { + modifier(EpoxyLayoutMarginsPadding()) + } +} + +// MARK: - EnvironmentValues + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension EnvironmentValues { + /// The layout margins of the parent `EpoxySwiftUIHostingView`, else zero if there is none. + var epoxyLayoutMargins: EdgeInsets { + get { self[EpoxyLayoutMarginsKey.self] } + set { self[EpoxyLayoutMarginsKey.self] = newValue } + } +} + +// MARK: - EpoxyLayoutMarginsKey + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +private struct EpoxyLayoutMarginsKey: EnvironmentKey { + static let defaultValue = EdgeInsets() +} + +// MARK: - EpoxyLayoutMarginsPadding + +/// A view modifier that applies the layout margins from an enclosing `EpoxySwiftUIHostingView` to +/// the modified `View`. +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +private struct EpoxyLayoutMarginsPadding: ViewModifier { + @Environment(\.epoxyLayoutMargins) var epoxyLayoutMargins + + func body(content: Content) -> some View { + content.padding(epoxyLayoutMargins) + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift new file mode 100644 index 00000000..06febc2c --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift @@ -0,0 +1,174 @@ +// Created by eric_horacek on 9/13/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - StyledView + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension StyledView where Self: ContentConfigurableView & BehaviorsConfigurableView { + /// Returns a SwiftUI `View` representing this `EpoxyableView`. + /// + /// To perform additional configuration of the `EpoxyableView` instance, call `configure` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…) + /// .configure { context in + /// context.view.doSomething() + /// } + /// ``` + /// + /// To configure the sizing behavior of the `EpoxyableView` instance, call `sizing` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…).sizing(.intrinsicSize) + /// ``` + static func swiftUIView( + content: Content, + style: Style, + behaviors: Behaviors? = nil) + -> SwiftUIView + { + SwiftUIView(storage: (content: content, style: style)) { + let view = Self(style: style) + view.setContent(content, animated: false) + return view + } + .configure { context in + // We need to create a new view instance when the style changes. + if context.oldStorage.style != style { + context.view = Self(style: style) + context.view.setContent(content, animated: context.animated) + } + // Otherwise, if the just the content changes, we need to update it. + else if context.oldStorage.content != content { + context.view.setContent(content, animated: context.animated) + context.container.invalidateIntrinsicContentSize() + } + + context.view.setBehaviors(behaviors) + } + } +} + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension StyledView + where + Self: ContentConfigurableView & BehaviorsConfigurableView, + Style == Never +{ + /// Returns a SwiftUI `View` representing this `EpoxyableView`. + /// + /// To perform additional configuration of the `EpoxyableView` instance, call `configure` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…) + /// .configure { context in + /// context.view.doSomething() + /// } + /// ``` + /// + /// To configure the sizing behavior of the `EpoxyableView` instance, call `sizing` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…).sizing(.intrinsicSize) + /// ``` + static func swiftUIView( + content: Content, + behaviors: Behaviors? = nil) + -> SwiftUIView + { + SwiftUIView(storage: content) { + let view = Self() + view.setContent(content, animated: false) + return view + } + .configure { context in + // We need to update the content of the existing view when the content is updated. + if context.oldStorage != content { + context.view.setContent(content, animated: context.animated) + context.container.invalidateIntrinsicContentSize() + } + + context.view.setBehaviors(behaviors) + } + } +} + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension StyledView + where + Self: ContentConfigurableView & BehaviorsConfigurableView, + Content == Never +{ + /// Returns a SwiftUI `View` representing this `EpoxyableView`. + /// + /// To perform additional configuration of the `EpoxyableView` instance, call `configure` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…) + /// .configure { context in + /// context.view.doSomething() + /// } + /// ``` + /// + /// To configure the sizing behavior of the `EpoxyableView` instance, call `sizing` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…).sizing(.intrinsicSize) + /// ``` + /// The sizing defaults to `.automatic`. + static func swiftUIView( + style: Style, + behaviors: Behaviors? = nil) + -> SwiftUIView + { + SwiftUIView(storage: style) { + Self(style: style) + } + .configure { context in + // We need to create a new view instance when the style changes. + if context.oldStorage != style { + context.view = Self(style: style) + } + + context.view.setBehaviors(behaviors) + } + } +} + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension StyledView + where + Self: ContentConfigurableView & BehaviorsConfigurableView, + Content == Never, + Style == Never +{ + /// Returns a SwiftUI `View` representing this `EpoxyableView`. + /// + /// To perform additional configuration of the `EpoxyableView` instance, call `configure` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…) + /// .configure { context in + /// context.view.doSomething() + /// } + /// ``` + /// + /// To configure the sizing behavior of the `EpoxyableView` instance, call `sizing` on the + /// returned SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…).sizing(.intrinsicSize) + /// ``` + /// The sizing defaults to `.automatic`. + static func swiftUIView(behaviors: Behaviors? = nil) -> SwiftUIView { + SwiftUIView { + Self() + } + .configure { context in + context.view.setBehaviors(behaviors) + } + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift new file mode 100644 index 00000000..065aaa71 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift @@ -0,0 +1,130 @@ +// Created by eric_horacek on 6/22/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - MeasuringViewRepresentable + +/// A `UIViewRepresentable` that uses a `SwiftUIMeasurementContainer` wrapping its represented +/// `UIView` to report its size that fits a proposed size to SwiftUI. +/// +/// Supports iOS 13-15 using the private `_overrideSizeThatFits(…)` method and iOS 16+ using the +/// `sizeThatFits(…)` method. +/// +/// - SeeAlso: ``SwiftUIMeasurementContainer`` +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +protocol MeasuringViewRepresentable: ViewRepresentableType + where + RepresentableViewType == SwiftUIMeasurementContainer +{ + /// The `UIView` content that's being measured by the enclosing `SwiftUIMeasurementContainer`. + associatedtype Content: ViewType + + /// The sizing strategy of the represented view. + /// + /// To configure the sizing behavior of the `View` instance, call `sizing` on this `View`, e.g.: + /// ``` + /// myView.sizing(.intrinsicSize) + /// ``` + var sizing: SwiftUIMeasurementContainerStrategy { get set } +} + +// MARK: Extensions + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension MeasuringViewRepresentable { + /// Returns a copy of this view with its sizing strategy updated to the given `sizing` value. + func sizing(_ strategy: SwiftUIMeasurementContainerStrategy) -> Self { + var copy = self + copy.sizing = strategy + return copy + } +} + +// MARK: Defaults + +#if os(iOS) || os(tvOS) +@available(iOS 13.0, tvOS 13.0, *) +extension MeasuringViewRepresentable { + func _overrideSizeThatFits( + _ size: inout CGSize, + in proposedSize: _ProposedSize, + uiView: UIViewType) + { + uiView.strategy = sizing + + // Note: this method is not double-called on iOS 16, so we don't need to do anything to prevent + // extra work here. + let children = Mirror(reflecting: proposedSize).children + + // Creates a `CGSize` by replacing `nil`s with `UIView.noIntrinsicMetric` + uiView.proposedSize = .init( + width: children.first { $0.label == "width" }?.value as? CGFloat ?? ViewType.noIntrinsicMetric, + height: children.first { $0.label == "height" }?.value as? CGFloat ?? ViewType.noIntrinsicMetric) + + size = uiView.measuredFittingSize + } + + #if swift(>=5.7) // Proxy check for being built with the iOS 15 SDK + @available(iOS 16.0, tvOS 16.0, macOS 13.0, *) + func sizeThatFits( + _ proposal: ProposedViewSize, + uiView: UIViewType, + context _: Context) + -> CGSize? + { + uiView.strategy = sizing + + // Creates a size by replacing `nil`s with `UIView.noIntrinsicMetric` + uiView.proposedSize = .init( + width: proposal.width ?? ViewType.noIntrinsicMetric, + height: proposal.height ?? ViewType.noIntrinsicMetric) + + return uiView.measuredFittingSize + } + #endif +} + +#elseif os(macOS) +@available(macOS 10.15, *) +extension MeasuringViewRepresentable { + func _overrideSizeThatFits( + _ size: inout CGSize, + in proposedSize: _ProposedSize, + nsView: NSViewType) + { + nsView.strategy = sizing + + let children = Mirror(reflecting: proposedSize).children + + // Creates a `CGSize` by replacing `nil`s with `UIView.noIntrinsicMetric` + nsView.proposedSize = .init( + width: children.first { $0.label == "width" }?.value as? CGFloat ?? ViewType.noIntrinsicMetric, + height: children.first { $0.label == "height" }?.value as? CGFloat ?? ViewType.noIntrinsicMetric) + + size = nsView.measuredFittingSize + } + + // Proxy check for being built with the macOS 13 SDK. + #if swift(>=5.7.1) + @available(macOS 13.0, *) + func sizeThatFits( + _ proposal: ProposedViewSize, + nsView: NSViewType, + context _: Context) + -> CGSize? + { + nsView.strategy = sizing + + // Creates a size by replacing `nil`s with `UIView.noIntrinsicMetric` + nsView.proposedSize = .init( + width: proposal.width ?? ViewType.noIntrinsicMetric, + height: proposal.height ?? ViewType.noIntrinsicMetric) + + return nsView.measuredFittingSize + } + #endif +} +#endif +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift new file mode 100644 index 00000000..5dcf7b22 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift @@ -0,0 +1,454 @@ +// Created by Bryn Bodayle on 1/24/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - SwiftUIMeasurementContainer + +/// A view that has an `intrinsicContentSize` of the `uiView`'s `systemLayoutSizeFitting(…)` and +/// supports double layout pass sizing and content size category changes. +/// +/// This container view uses an injected proposed width to measure the view and return its ideal +/// height through the `SwiftUISizingContext` binding. +/// +/// - SeeAlso: ``MeasuringViewRepresentable`` +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +final class SwiftUIMeasurementContainer: ViewType { + + // MARK: Lifecycle + + init(content: Content, strategy: SwiftUIMeasurementContainerStrategy) { + self.content = content + self.strategy = strategy + + // On iOS 15 and below, passing zero can result in a constraint failure the first time a view + // is displayed, but the system gracefully recovers afterwards. On iOS 16, it's fine to pass + // zero. + let initialSize: CGSize + if #available(iOS 16, tvOS 16, macOS 13, *) { + initialSize = .zero + } else { + initialSize = .init(width: 375, height: 150) + } + super.init(frame: .init(origin: .zero, size: initialSize)) + + addSubview(content) + setUpConstraints() + } + + @available(*, unavailable) + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Internal + + /// The most recently measured fitting size of the `uiView` that fits within the current + /// `proposedSize`. + /// + /// Contains `proposedSize`/`bounds.size` fallbacks for dimensions with no intrinsic size, as + /// compared to `intrinsicContentSize` which has `UIView.noIntrinsicMetric` fields in the case of + /// no intrinsic size. + var measuredFittingSize: CGSize { + _measuredFittingSize ?? measureView() + } + + /// The `UIView` content that's being measured by this container. + var content: Content { + didSet { + guard content !== oldValue else { return } + oldValue.removeFromSuperview() + addSubview(content) + // Invalidate the strategy since it's derived from this view. + _resolvedStrategy = nil + // Re-configure the constraints since they depend on the resolved strategy. + setUpConstraints() + // Finally, we need to re-measure the view. + _measuredFittingSize = nil + } + } + + /// The proposed size at the time of the latest measurement. + /// + /// Has a side-effect of updating the `measuredIntrinsicContentSize` if it's changed. + var proposedSize = CGSize.noIntrinsicMetric { + didSet { + guard oldValue != proposedSize else { return } + // The proposed size is only used by the measurement, so just re-measure. + _measuredFittingSize = nil + } + } + + /// The measurement strategy of this container. + /// + /// Has a side-effect of updating the `measuredIntrinsicContentSize` if it's changed. + var strategy: SwiftUIMeasurementContainerStrategy { + didSet { + guard oldValue != strategy else { return } + // Invalidate the resolved strategy since it's derived from this strategy. + _resolvedStrategy = nil + // Then, re-measure the view. + _measuredFittingSize = nil + } + } + + override var intrinsicContentSize: CGSize { + _intrinsicContentSize + } + + #if os(macOS) + override func layout() { + super.layout() + + // We need to re-measure the view whenever the size of the bounds changes, as the previous size + // may now be incorrect. + if latestMeasurementBoundsSize != nil, bounds.size != latestMeasurementBoundsSize { + // This will trigger SwiftUI to re-measure the view. + super.invalidateIntrinsicContentSize() + } + } + #else + override func layoutSubviews() { + super.layoutSubviews() + + // We need to re-measure the view whenever the size of the bounds changes, as the previous size + // may now be incorrect. + if latestMeasurementBoundsSize != nil, bounds.size != latestMeasurementBoundsSize { + // This will trigger SwiftUI to re-measure the view. + super.invalidateIntrinsicContentSize() + } + } + #endif + + override func invalidateIntrinsicContentSize() { + super.invalidateIntrinsicContentSize() + + // Invalidate the resolved strategy in case it changes with the re-measurement as it relies on + // the intrinsic size. + _resolvedStrategy = nil + _measuredFittingSize = nil + } + + // MARK: Private + + /// The most recently measured intrinsic content size of the `uiView`, else `noIntrinsicMetric` if + /// it has not yet been measured. + /// + /// Contains `UIView.noIntrinsicMetric` fallbacks for dimensions with no intrinsic size, + /// as compared to `measuredFittingSize` which has `proposedSize`/`bounds.size` fallbacks. + private var _intrinsicContentSize = CGSize.noIntrinsicMetric + + /// The bounds size at the time of the latest measurement. + private var latestMeasurementBoundsSize: CGSize? + + /// The most recently updated set of constraints constraining `uiView` to `self`. + private var uiViewConstraints = [NSLayoutConstraint.Attribute: NSLayoutConstraint]() + + /// The cached `resolvedStrategy` to prevent unnecessary re-measurements. + private var _resolvedStrategy: ResolvedSwiftUIMeasurementContainerStrategy? + + /// The cached `measuredFittingSize` to prevent unnecessary re-measurements. + private var _measuredFittingSize: CGSize? + + /// The resolved measurement strategy. + private var resolvedStrategy: ResolvedSwiftUIMeasurementContainerStrategy { + if let resolvedStrategy = _resolvedStrategy { + return resolvedStrategy + } + + let resolved: ResolvedSwiftUIMeasurementContainerStrategy + switch strategy { + case .automatic: + // Perform an intrinsic size measurement pass, which gives us valid values for + // `UILabel.preferredMaxLayoutWidth`. + let intrinsicSize = content.systemLayoutFittingIntrinsicSize() + + // If the view has a intrinsic width and contains a double layout pass subview, give it the + // proposed width to allow the label content to gracefully wrap to multiple lines. + if intrinsicSize.width > 0, content.containsDoubleLayoutPassSubviews() { + resolved = .intrinsicHeightProposedWidth + } else { + let zero = CGFloat(0) + switch (width: intrinsicSize.width, height: intrinsicSize.height) { + case (width: ...zero, height: ...zero): + resolved = .proposed + case (width: ...zero, height: zero.nextUp...): + resolved = .intrinsicHeightProposedWidth + case (width: zero.nextUp..., height: ...zero): + resolved = .intrinsicWidthProposedHeight + default: + resolved = .intrinsic(intrinsicSize) + } + } + case .proposed: + resolved = .proposed + case .intrinsicHeightProposedWidth: + resolved = .intrinsicHeightProposedWidth + case .intrinsicWidthProposedHeight: + resolved = .intrinsicWidthProposedHeight + case .intrinsic: + resolved = .intrinsic(content.systemLayoutFittingIntrinsicSize()) + } + _resolvedStrategy = resolved + return resolved + } + + private func setUpConstraints() { + content.translatesAutoresizingMaskIntoConstraints = false + + let leading = content.leadingAnchor.constraint(equalTo: leadingAnchor) + let top = content.topAnchor.constraint(equalTo: topAnchor) + let trailing = content.trailingAnchor.constraint(equalTo: trailingAnchor) + let bottom = content.bottomAnchor.constraint(equalTo: bottomAnchor) + let newConstraints: [NSLayoutConstraint.Attribute: NSLayoutConstraint] = [ + .leading: leading, .top: top, .trailing: trailing, .bottom: bottom, + ] + // Start with the lowest priority constraints so we aren't measuring the view too early, the + // priorities will be updated later on. + prioritizeConstraints(newConstraints, strategy: .intrinsic(.zero)) + + NSLayoutConstraint.deactivate(Array(uiViewConstraints.values)) + uiViewConstraints = newConstraints + NSLayoutConstraint.activate(Array(uiViewConstraints.values)) + } + + /// Prioritizes the given constraints based on the provided resolved strategy. + private func prioritizeConstraints( + _ constraints: [NSLayoutConstraint.Attribute: NSLayoutConstraint], + strategy: ResolvedSwiftUIMeasurementContainerStrategy) + { + // Give a required constraint in the dimensions that are fixed to the bounds, otherwise almost + // required. + switch strategy { + case .proposed: + constraints[.trailing]?.priority = .required + constraints[.bottom]?.priority = .required + case .intrinsicHeightProposedWidth: + constraints[.trailing]?.priority = .required + constraints[.bottom]?.priority = .almostRequired + case .intrinsicWidthProposedHeight: + constraints[.trailing]?.priority = .almostRequired + constraints[.bottom]?.priority = .required + case .intrinsic: + constraints[.trailing]?.priority = .almostRequired + constraints[.bottom]?.priority = .almostRequired + } + + #if os(macOS) + // On macOS, views default to having required constraints setting their height / width + // equal to their intrinsic content size. These have to be disabled in favor of the constraints + // we create here. + content.isVerticalContentSizeConstraintActive = false + content.isHorizontalContentSizeConstraintActive = false + #endif + } + + /// Measures the `uiView`, storing the resulting size in `measuredIntrinsicContentSize`. + private func measureView() -> CGSize { + latestMeasurementBoundsSize = bounds.size + prioritizeConstraints(uiViewConstraints, strategy: resolvedStrategy) + + var measuredSize: CGSize + let proposedSizeElseBounds = proposedSize.replacingNoIntrinsicMetric(with: bounds.size) + + switch resolvedStrategy { + case .proposed: + measuredSize = .noIntrinsicMetric + + case .intrinsicHeightProposedWidth: + measuredSize = content.systemLayoutFittingIntrinsicHeightFixedWidth(proposedSizeElseBounds.width) + measuredSize.width = ViewType.noIntrinsicMetric + + case .intrinsicWidthProposedHeight: + measuredSize = content.systemLayoutFittingIntrinsicWidthFixedHeight(proposedSizeElseBounds.height) + measuredSize.height = ViewType.noIntrinsicMetric + + case .intrinsic(let size): + measuredSize = size + + // If the measured size exceeds an available width or height, set the measured size to + // `noIntrinsicMetric` to ensure that the component can be compressed, otherwise it will + // overflow beyond the proposed size. + // - If the previous intrinsic content size is the same as the new proposed size, we don't + // do this as SwiftUI sometimes "proposes" the same intrinsic size back to the component and + // we don't want that scenario to prevent size changes when there is actually more space + // available. + if + proposedSize.width != ViewType.noIntrinsicMetric, + measuredSize.width > proposedSizeElseBounds.width, + _intrinsicContentSize.width != proposedSize.width + { + measuredSize.width = ViewType.noIntrinsicMetric + } + if + proposedSize.height != ViewType.noIntrinsicMetric, + measuredSize.height > proposedSizeElseBounds.height, + _intrinsicContentSize.height != proposedSize.height + { + measuredSize.height = ViewType.noIntrinsicMetric + } + } + + _intrinsicContentSize = measuredSize + + let measuredFittingSize = measuredSize.replacingNoIntrinsicMetric(with: proposedSizeElseBounds) + _measuredFittingSize = measuredFittingSize + return measuredFittingSize + } +} + +// MARK: - SwiftUIMeasurementContainerStrategy + +/// The measurement strategy of a `SwiftUIMeasurementContainer`. +enum SwiftUIMeasurementContainerStrategy { + /// The container makes a best effort to correctly choose the measurement strategy of the view. + /// + /// The best effort is based on a number of heuristics: + /// - The `uiView` will be given its intrinsic width and/or height when measurement in that + /// dimension produces a positive value, while zero/negative values will result in that + /// dimension receiving the available space proposed by the parent. + /// - If the view contains `UILabel` subviews that require a double layout pass as determined by + /// a `preferredMaxLayoutWidth` that's greater than zero after a layout, then the view will + /// default to `intrinsicHeightProposedWidth` to allow the labels to wrap. + /// + /// If you would like to opt out of automatic sizing for performance or to override the default + /// behavior, choose another strategy. + case automatic + + /// The `uiView` is sized to fill the area proposed by its parent. + /// + /// Typically used for views that should expand greedily in both axes, e.g. a background view. + case proposed + + /// The `uiView` is sized with its intrinsic height and expands horizontally to fill the width + /// proposed by its parent. + /// + /// Typically used for views that have a height that's a function of their width, e.g. a row with + /// text that can wrap to multiple lines. + case intrinsicHeightProposedWidth + + /// The `uiView` is sized with its intrinsic width and expands vertically to fill the height + /// proposed by its parent. + /// + /// Typically used for views that are free to grow vertically but have a fixed width, e.g. a view + /// in a horizontal carousel. + case intrinsicWidthProposedHeight + + /// The `uiView` is sized to its intrinsic width and height. + /// + /// Typically used for components with a specific intrinsic size in both axes, e.g. controls or + /// inputs. + case intrinsic +} + +// MARK: - ResolvedSwiftUIMeasurementContainerStrategy + +/// The resolved measurement strategy of a `SwiftUIMeasurementContainer`, matching the cases of the +/// `SwiftUIMeasurementContainerStrategy` without the automatic case. +private enum ResolvedSwiftUIMeasurementContainerStrategy { + case proposed, intrinsicHeightProposedWidth, intrinsicWidthProposedHeight, intrinsic(CGSize) +} + +// MARK: - UILayoutPriority + +extension LayoutPriorityType { + /// An "almost required" constraint, useful for creating near-required constraints that don't + /// error when unable to be satisfied. + @nonobjc + fileprivate static var almostRequired: LayoutPriorityType { .init(rawValue: required.rawValue - 1) } +} + +// MARK: - UIView + +extension ViewType { + /// The `systemLayoutSizeFitting(…)` of this view with a compressed size and fitting priorities. + @nonobjc + fileprivate func systemLayoutFittingIntrinsicSize() -> CGSize { + #if os(macOS) + intrinsicContentSize + #else + systemLayoutSizeFitting( + UIView.layoutFittingCompressedSize, + withHorizontalFittingPriority: .fittingSizeLevel, + verticalFittingPriority: .fittingSizeLevel) + #endif + } + + /// The `systemLayoutSizeFitting(…)` of this view with a compressed height with a fitting size + /// priority and with the given fixed width and fitting priority. + @nonobjc + fileprivate func systemLayoutFittingIntrinsicHeightFixedWidth( + _ width: CGFloat, + priority: LayoutPriorityType = .almostRequired) + -> CGSize + { + #if os(macOS) + return CGSize(width: width, height: intrinsicContentSize.height) + #else + let targetSize = CGSize(width: width, height: UIView.layoutFittingCompressedSize.height) + + return systemLayoutSizeFitting( + targetSize, + withHorizontalFittingPriority: priority, + verticalFittingPriority: .fittingSizeLevel) + #endif + } + + /// The `systemLayoutSizeFitting(…)` of this view with a compressed width with a fitting size + /// priority and with the given fixed height and fitting priority. + @nonobjc + fileprivate func systemLayoutFittingIntrinsicWidthFixedHeight( + _ height: CGFloat, + priority: LayoutPriorityType = .almostRequired) + -> CGSize + { + #if os(macOS) + return CGSize(width: intrinsicContentSize.width, height: height) + #else + let targetSize = CGSize(width: UIView.layoutFittingCompressedSize.width, height: height) + + return systemLayoutSizeFitting( + targetSize, + withHorizontalFittingPriority: .fittingSizeLevel, + verticalFittingPriority: priority) + #endif + } + + /// Whether this view or any of its subviews has a subview that has a double layout pass `UILabel` + /// as determined by a non-zero `preferredMaxLayoutWidth`, which implies that it should get a + /// `intrinsicHeightProposedWidth` sizing strategy to allow the label to wrap and grow. + @nonobjc + fileprivate func containsDoubleLayoutPassSubviews() -> Bool { + #if os(macOS) + return false + #else + var contains = false + if let label = self as? UILabel, label.preferredMaxLayoutWidth > 0 { + contains = true + } + for subview in subviews { + contains = contains || subview.containsDoubleLayoutPassSubviews() + } + return contains + #endif + } +} + +// MARK: - CGSize + +extension CGSize { + /// A `CGSize` with `noIntrinsicMetric` for both its width and height. + fileprivate static var noIntrinsicMetric: CGSize { + .init(width: ViewType.noIntrinsicMetric, height: ViewType.noIntrinsicMetric) + } + + /// Returns a `CGSize` with its width and/or height replaced with the corresponding field of the + /// provided `fallback` size if they are `UIView.noIntrinsicMetric`. + fileprivate func replacingNoIntrinsicMetric(with fallback: CGSize) -> CGSize { + .init( + width: width == ViewType.noIntrinsicMetric ? fallback.width : width, + height: height == ViewType.noIntrinsicMetric ? fallback.height : height) + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift new file mode 100644 index 00000000..8be06f28 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift @@ -0,0 +1,150 @@ +// Created by eric_horacek on 9/8/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - SwiftUIView + +/// A `UIViewRepresentable` SwiftUI `View` that wraps its `Content` `UIView` within a +/// `SwiftUIMeasurementContainer`, used to size a UIKit view correctly within a SwiftUI view +/// hierarchy. +/// +/// Includes an optional generic `Storage` value, which can be used to compare old and new values +/// across state changes to prevent redundant view updates. +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +struct SwiftUIView: MeasuringViewRepresentable, + UIViewConfiguringSwiftUIView +{ + + // MARK: Lifecycle + + /// Creates a SwiftUI representation of the content view with the given storage and the provided + /// `makeContent` closure to construct the content whenever `makeUIView(…)` is invoked. + init(storage: Storage, makeContent: @escaping () -> Content) { + self.storage = storage + self.makeContent = makeContent + } + + /// Creates a SwiftUI representation of the content view with the provided `makeContent` closure + /// to construct it whenever `makeUIView(…)` is invoked. + init(makeContent: @escaping () -> Content) where Storage == Void { + storage = () + self.makeContent = makeContent + } + + // MARK: Internal + + var configurations: [Configuration] = [] + + var sizing: SwiftUIMeasurementContainerStrategy = .automatic + + // MARK: Private + + /// The current stored value, with the previous value provided to the configuration closure as + /// the `oldStorage`. + private var storage: Storage + + /// A closure that's invoked to construct the represented content view. + private var makeContent: () -> Content +} + +// MARK: UIViewRepresentable + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension SwiftUIView { + func makeCoordinator() -> Coordinator { + Coordinator(storage: storage) + } + + #if os(macOS) + func makeNSView(context _: Context) -> SwiftUIMeasurementContainer { + SwiftUIMeasurementContainer(content: makeContent(), strategy: sizing) + } + + func updateNSView(_ uiView: SwiftUIMeasurementContainer, context: Context) { + let oldStorage = context.coordinator.storage + context.coordinator.storage = storage + + let configurationContext = ConfigurationContext( + oldStorage: oldStorage, + viewRepresentableContext: context, + container: uiView) + + for configuration in configurations { + configuration(configurationContext) + } + } + #else + func makeUIView(context _: Context) -> SwiftUIMeasurementContainer { + SwiftUIMeasurementContainer(content: makeContent(), strategy: sizing) + } + + func updateUIView(_ uiView: SwiftUIMeasurementContainer, context: Context) { + let oldStorage = context.coordinator.storage + context.coordinator.storage = storage + + let configurationContext = ConfigurationContext( + oldStorage: oldStorage, + viewRepresentableContext: context, + container: uiView) + + for configuration in configurations { + configuration(configurationContext) + } + } + #endif +} + +// MARK: SwiftUIView.ConfigurationContext + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension SwiftUIView { + /// The configuration context that's available to configure the `Content` view whenever the + /// `updateUIView()` method is invoked via a configuration closure. + struct ConfigurationContext: ViewProviding { + /// The previous value for the `Storage` of this `SwiftUIView`, which can be used to store + /// values across state changes to prevent redundant view updates. + var oldStorage: Storage + + /// The `UIViewRepresentable.Context`, with information about the transaction and environment. + var viewRepresentableContext: Context + + /// The backing measurement container that contains the `Content`. + var container: SwiftUIMeasurementContainer + + /// The `UIView` content that's being configured. + /// + /// Setting this to a new value updates the backing measurement container's `content`. + var view: Content { + get { container.content } + nonmutating set { container.content = newValue } + } + + /// A convenience accessor indicating whether this content update should be animated. + var animated: Bool { + viewRepresentableContext.transaction.animation != nil + } + } +} + +// MARK: SwiftUIView.Coordinator + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension SwiftUIView { + /// A coordinator that stores the `storage` associated with this view, enabling the old storage + /// value to be accessed during the `updateUIView(…)`. + final class Coordinator { + + // MARK: Lifecycle + + fileprivate init(storage: Storage) { + self.storage = storage + } + + // MARK: Internal + + fileprivate(set) var storage: Storage + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift new file mode 100644 index 00000000..4984ea0d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift @@ -0,0 +1,42 @@ +// Created by eric_horacek on 3/3/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - ViewTypeProtocol + swiftUIView + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension ViewTypeProtocol { + /// Returns a SwiftUI `View` representing this `UIView`, constructed with the given `makeView` + /// closure and sized with the given sizing configuration. + /// + /// To perform additional configuration of the `UIView` instance, call `configure` on the + /// returned SwiftUI `View`: + /// ``` + /// MyUIView.swiftUIView(…) + /// .configure { context in + /// context.view.doSomething() + /// } + /// ``` + /// + /// To configure the sizing behavior of the `UIView` instance, call `sizing` on the returned + /// SwiftUI `View`: + /// ``` + /// MyView.swiftUIView(…).sizing(.intrinsicSize) + /// ``` + /// The sizing defaults to `.automatic`. + static func swiftUIView(makeView: @escaping () -> Self) -> SwiftUIView { + SwiftUIView(makeContent: makeView) + } +} + +// MARK: - ViewTypeProtocol + +/// A protocol that all `UIView`s conform to, enabling extensions that have a `Self` reference. +protocol ViewTypeProtocol: ViewType { } + +// MARK: - ViewType + ViewTypeProtocol + +extension ViewType: ViewTypeProtocol { } +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift new file mode 100644 index 00000000..7a240582 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift @@ -0,0 +1,45 @@ +// Created by eric_horacek on 3/4/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - UIViewConfiguringSwiftUIView + +/// A protocol describing a SwiftUI `View` that can configure its `UIView` content via an array of +/// `configuration` closures. +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +protocol UIViewConfiguringSwiftUIView: View { + /// The context available to this configuration, which provides the `UIView` instance at a minimum + /// but can include additional context as needed. + associatedtype ConfigurationContext: ViewProviding + + /// A closure that is invoked to configure the represented content view. + typealias Configuration = (ConfigurationContext) -> Void + + /// A mutable array of configuration closures that should each be invoked with the + /// `ConfigurationContext` whenever `updateUIView` is called in a `UIViewRepresentable`. + var configurations: [Configuration] { get set } +} + +// MARK: Extensions + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension UIViewConfiguringSwiftUIView { + /// Returns a copy of this view updated to have the given closure applied to its represented view + /// whenever it is updated via the `updateUIView(…)` method. + func configure(_ configure: @escaping Configuration) -> Self { + var copy = self + copy.configurations.append(configure) + return copy + } + + /// Returns a copy of this view updated to have the given closures applied to its represented view + /// whenever it is updated via the `updateUIView(…)` method. + func configurations(_ configurations: [Configuration]) -> Self { + var copy = self + copy.configurations.append(contentsOf: configurations) + return copy + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/BehaviorsConfigurableView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/BehaviorsConfigurableView.swift new file mode 100644 index 00000000..33c63f56 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/BehaviorsConfigurableView.swift @@ -0,0 +1,45 @@ +// Created by Tyler Hedrick on 5/26/20. +// Copyright © 2020 Airbnb Inc. All rights reserved. + +// MARK: - BehaviorsConfigurableView + +/// A view that can be configured with a `Behaviors` instance that contains the view's non- +/// `Equatable` properties that can be updated on view instances after initialization, e.g. callback +/// closures or delegates. +/// +/// Since it is not possible to establish the equality of two `Behaviors` instances, `Behaviors` +/// will be set more often than `ContentConfigurableView.Content`, needing to be updated every time +/// the view's corresponding `EpoxyModeled` instance is updated. As such, setting behaviors should +/// be as lightweight as possible. +/// +/// Properties of `Behaviors` should be mutually exclusive with the properties in the +/// `StyledView.Style` and `ContentConfigurableView.Content`. +/// +/// - SeeAlso: `ContentConfigurableView` +/// - SeeAlso: `StyledView` +/// - SeeAlso: `EpoxyableView` +protocol BehaviorsConfigurableView: ViewType { + /// The non-`Equatable` properties that can be changed over of the lifecycle this View's + /// instances, e.g. callback closures or delegates. + /// + /// Defaults to `Never` for views that do not have `Behaviors`. + associatedtype Behaviors = Never + + /// Updates the behaviors of this view to those in the given `behaviors`, else resets the + /// behaviors if `nil`. + /// + /// Behaviors are optional as they must be "resettable" in order for Epoxy to reset the behaviors + /// on your view when no behaviors are provided. + func setBehaviors(_ behaviors: Self.Behaviors?) +} + +// MARK: Defaults + +extension BehaviorsConfigurableView where Behaviors == Never { + func setBehaviors(_ behaviors: Never?) { + switch behaviors { + case nil: + break + } + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ContentConfigurableView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ContentConfigurableView.swift new file mode 100644 index 00000000..6ebce5ac --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ContentConfigurableView.swift @@ -0,0 +1,36 @@ +// Created by Laura Skelton on 5/30/17. +// Copyright © 2017 Airbnb. All rights reserved. + +// MARK: - ContentConfigurableView + +/// A view that can be configured with a `Content` instance that contains the view's `Equatable` +/// properties that can be updated on existing view instances, e.g. text `String`s or image `URL`s. +/// +/// For performance, it is generally expected that `Content` is only set when it is not equal to the +/// previous `Content` instance that has been set on a view instance. As a further optimization, +/// this view can guard updates on the equality of each property of the `Content` against the +/// current property value when set. +/// +/// Properties of `Content` should be mutually exclusive with the properties of the +/// `StyledView.Style` and `BehaviorsConfigurableView.Behaviors`. +/// +/// - SeeAlso: `BehaviorsConfigurableView` +/// - SeeAlso: `StyledView` +/// - SeeAlso: `EpoxyableView` +protocol ContentConfigurableView: ViewType { + /// The `Equatable` properties that can be updated on instances of this view, e.g. text `String`s + /// or image `URL`s. + /// + /// Defaults to `Never` for views that do not have `Content`. + associatedtype Content: Equatable = Never + + /// Updates the content of this view to the properties of the given `content`, optionally + /// animating the updates. + func setContent(_ content: Self.Content, animated: Bool) +} + +// MARK: Defaults + +extension ContentConfigurableView where Content == Never { + func setContent(_: Never, animated _: Bool) { } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/EpoxyableView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/EpoxyableView.swift new file mode 100644 index 00000000..5f13195a --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/EpoxyableView.swift @@ -0,0 +1,5 @@ +// Created by eric_horacek on 1/13/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +/// A `UIView` that can be declaratively configured via a concrete `EpoxyableModel` instance. +typealias EpoxyableView = BehaviorsConfigurableView & ContentConfigurableView & StyledView diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/StyledView.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/StyledView.swift new file mode 100644 index 00000000..13f87119 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/StyledView.swift @@ -0,0 +1,42 @@ +// Created by Laura Skelton on 4/14/16. +// Copyright © 2016 Airbnb. All rights reserved. + +// MARK: - StyledView + +/// A view that can be initialized with a `Style` instance that contains the view's invariant +/// configuration parameters, e.g. the `UIButton.ButtonType` of a `UIButton`. +/// +/// A `Style` is expected to be invariant over the lifecycle of the view; it should not possible to +/// change the `Style` of a view after it is created. All variant properties of the view should +/// either be included in the `ContentConfigurableView.Content` if they are `Equatable` (e.g. a +/// title `String`) or the `BehaviorsConfigurableView.Behaviors` if they are not (e.g. a callback +/// closure). +/// +/// A `Style` is `Hashable` to allow views of the same type with equal `Style`s to be reused by +/// establishing whether their invariant `Style` instances are equal. +/// +/// Properties of `Style` should be mutually exclusive with the properties of the +/// `ContentConfigurableView.Content` and `BehaviorsConfigurableView.Behaviors`. +/// +/// - SeeAlso: `ContentConfigurableView` +/// - SeeAlso: `BehaviorsConfigurableView` +/// - SeeAlso: `EpoxyableView` +protocol StyledView: ViewType { + /// The style type of this view, passed into its initializer to configure the resulting instance. + /// + /// Defaults to `Never` for views that do not have a `Style`. + associatedtype Style: Hashable = Never + + /// Creates an instance of this view configured with the given `Style` instance. + init(style: Style) +} + +// MARK: Defaults + +extension StyledView where Style == Never { + init(style: Never) { + // An empty switch is required to silence the "'self.init' isn't called on all paths before + // returning from initializer" error. + switch style { } + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift new file mode 100644 index 00000000..c673d287 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift @@ -0,0 +1,52 @@ +// Created by Cal Stephens on 6/26/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI +#if canImport(UIKit) +import UIKit + +/// The platform's main view type. +/// Either `UIView` on iOS/tvOS or `NSView` on macOS. +typealias ViewType = UIView + +/// The platform's SwiftUI view representable type. +/// Either `UIViewRepresentable` on iOS/tvOS or `NSViewRepresentable` on macOS. +@available(iOS 13.0, tvOS 13.0, *) +typealias ViewRepresentableType = UIViewRepresentable + +/// The platform's layout constraint priority type. +/// Either `UILayoutPriority` on iOS/tvOS or `NSLayoutConstraint.Priority` on macOS. +typealias LayoutPriorityType = UILayoutPriority + +@available(iOS 13.0, tvOS 13.0, *) +extension ViewRepresentableType { + /// The platform's view type for `ViewRepresentableType`. + /// Either `UIViewType` on iOS/tvOS or `NSViewType` on macOS. + typealias RepresentableViewType = UIViewType +} + +#elseif canImport(AppKit) +import AppKit + +/// The platform's main view type. +/// Either `UIView` on iOS/tvOS, or `NSView` on macOS. +typealias ViewType = NSView + +/// The platform's SwiftUI view representable type. +/// Either `UIViewRepresentable` on iOS/tvOS, or `NSViewRepresentable` on macOS. +@available(macOS 10.15, *) +typealias ViewRepresentableType = NSViewRepresentable + +/// The platform's layout constraint priority type. +/// Either `UILayoutPriority` on iOS/tvOS, or `NSLayoutConstraint.Priority` on macOS. +typealias LayoutPriorityType = NSLayoutConstraint.Priority + +@available(macOS 10.15, *) +extension ViewRepresentableType { + /// The platform's view type for `ViewRepresentableType`. + /// Either `UIViewType` on iOS/tvOS or `NSViewType` on macOS. + typealias RepresentableViewType = NSViewType +} +#endif +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift new file mode 100644 index 00000000..9a0e0333 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift @@ -0,0 +1,256 @@ +// +// LRUCache.swift +// LRUCache +// +// Version 1.0.2 +// +// Created by Nick Lockwood on 05/08/2021. +// Copyright © 2021 Nick Lockwood. All rights reserved. +// +// Distributed under the permissive MIT license +// Get the latest version from here: +// +// https://github.com/nicklockwood/LRUCache +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation + +#if canImport(UIKit) +import UIKit + +/// Notification that cache should be cleared +let LRUCacheMemoryWarningNotification: NSNotification.Name = + UIApplication.didReceiveMemoryWarningNotification + +#else + +/// Notification that cache should be cleared +let LRUCacheMemoryWarningNotification: NSNotification.Name = + .init("LRUCacheMemoryWarningNotification") + +#endif + +// MARK: - LRUCache + +final class LRUCache { + + // MARK: Lifecycle + + /// Initialize the cache with the specified `totalCostLimit` and `countLimit` + init( + totalCostLimit: Int = .max, + countLimit: Int = .max, + notificationCenter: NotificationCenter = .default) + { + self.totalCostLimit = totalCostLimit + self.countLimit = countLimit + self.notificationCenter = notificationCenter + + token = notificationCenter.addObserver( + forName: LRUCacheMemoryWarningNotification, + object: nil, + queue: nil) + { [weak self] _ in + self?.removeAllValues() + } + } + + deinit { + if let token { + notificationCenter.removeObserver(token) + } + } + + // MARK: Internal + + /// The current total cost of values in the cache + private(set) var totalCost = 0 + + /// The maximum total cost permitted + var totalCostLimit: Int { + didSet { clean() } + } + + /// The maximum number of values permitted + var countLimit: Int { + didSet { clean() } + } + + // MARK: Private + + private var values: [Key: Container] = [:] + private unowned(unsafe) var head: Container? + private unowned(unsafe) var tail: Container? + private let lock: NSLock = .init() + private var token: AnyObject? + private let notificationCenter: NotificationCenter + +} + +extension LRUCache { + /// The number of values currently stored in the cache + var count: Int { + values.count + } + + /// Is the cache empty? + var isEmpty: Bool { + values.isEmpty + } + + /// Returns all values in the cache from oldest to newest + var allValues: [Value] { + lock.lock() + defer { lock.unlock() } + var values = [Value]() + var next = head + while let container = next { + values.append(container.value) + next = container.next + } + return values + } + + /// Insert a value into the cache with optional `cost` + func setValue(_ value: Value?, forKey key: Key, cost: Int = 0) { + guard let value else { + removeValue(forKey: key) + return + } + lock.lock() + if let container = values[key] { + container.value = value + totalCost -= container.cost + container.cost = cost + remove(container) + append(container) + } else { + let container = Container( + value: value, + cost: cost, + key: key) + values[key] = container + append(container) + } + totalCost += cost + lock.unlock() + clean() + } + + /// Remove a value from the cache and return it + @discardableResult + func removeValue(forKey key: Key) -> Value? { + lock.lock() + defer { lock.unlock() } + guard let container = values.removeValue(forKey: key) else { + return nil + } + remove(container) + totalCost -= container.cost + return container.value + } + + /// Fetch a value from the cache + func value(forKey key: Key) -> Value? { + lock.lock() + defer { lock.unlock() } + if let container = values[key] { + remove(container) + append(container) + return container.value + } + return nil + } + + /// Remove all values from the cache + func removeAllValues() { + lock.lock() + values.removeAll() + head = nil + tail = nil + lock.unlock() + } +} + +extension LRUCache { + + // MARK: Fileprivate + + fileprivate final class Container { + + // MARK: Lifecycle + + init(value: Value, cost: Int, key: Key) { + self.value = value + self.cost = cost + self.key = key + } + + // MARK: Internal + + var value: Value + var cost: Int + let key: Key + unowned(unsafe) var prev: Container? + unowned(unsafe) var next: Container? + + } + + // MARK: Private + + // Remove container from list (must be called inside lock) + private func remove(_ container: Container) { + if head === container { + head = container.next + } + if tail === container { + tail = container.prev + } + container.next?.prev = container.prev + container.prev?.next = container.next + container.next = nil + } + + // Append container to list (must be called inside lock) + private func append(_ container: Container) { + assert(container.next == nil) + if head == nil { + head = container + } + container.prev = tail + tail?.next = container + tail = container + } + + // Remove expired values (must be called outside lock) + private func clean() { + lock.lock() + defer { lock.unlock() } + while + totalCost > totalCostLimit || count > countLimit, + let container = head + { + remove(container) + values.removeValue(forKey: container.key) + totalCost -= container.cost + } + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+BackingConfiguration.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+BackingConfiguration.swift new file mode 100644 index 00000000..101b0363 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+BackingConfiguration.swift @@ -0,0 +1,147 @@ +// +// Archive+BackingConfiguration.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + + struct BackingConfiguration { + let file: FILEPointer + let endOfCentralDirectoryRecord: EndOfCentralDirectoryRecord + let zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory? + + #if swift(>=5.0) + let memoryFile: MemoryFile? + + init( + file: FILEPointer, + endOfCentralDirectoryRecord: EndOfCentralDirectoryRecord, + zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory? = nil, + memoryFile: MemoryFile? = nil) + { + self.file = file + self.endOfCentralDirectoryRecord = endOfCentralDirectoryRecord + self.zip64EndOfCentralDirectory = zip64EndOfCentralDirectory + self.memoryFile = memoryFile + } + #else + + init( + file: FILEPointer, + endOfCentralDirectoryRecord: EndOfCentralDirectoryRecord, + zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory?) + { + self.file = file + self.endOfCentralDirectoryRecord = endOfCentralDirectoryRecord + self.zip64EndOfCentralDirectory = zip64EndOfCentralDirectory + } + #endif + } + + static func makeBackingConfiguration(for url: URL, mode: AccessMode) + -> BackingConfiguration? + { + let fileManager = FileManager() + switch mode { + case .read: + let fileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + guard + let archiveFile = fopen(fileSystemRepresentation, "rb"), + let (eocdRecord, zip64EOCD) = Archive.scanForEndOfCentralDirectoryRecord(in: archiveFile) + else { + return nil + } + return BackingConfiguration( + file: archiveFile, + endOfCentralDirectoryRecord: eocdRecord, + zip64EndOfCentralDirectory: zip64EOCD) + case .create: + let endOfCentralDirectoryRecord = EndOfCentralDirectoryRecord( + numberOfDisk: 0, + numberOfDiskStart: 0, + totalNumberOfEntriesOnDisk: 0, + totalNumberOfEntriesInCentralDirectory: 0, + sizeOfCentralDirectory: 0, + offsetToStartOfCentralDirectory: 0, + zipFileCommentLength: 0, + zipFileCommentData: Data()) + do { + try endOfCentralDirectoryRecord.data.write(to: url, options: .withoutOverwriting) + } catch { return nil } + fallthrough + case .update: + let fileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + guard + let archiveFile = fopen(fileSystemRepresentation, "rb+"), + let (eocdRecord, zip64EOCD) = Archive.scanForEndOfCentralDirectoryRecord(in: archiveFile) + else { + return nil + } + fseeko(archiveFile, 0, SEEK_SET) + return BackingConfiguration( + file: archiveFile, + endOfCentralDirectoryRecord: eocdRecord, + zip64EndOfCentralDirectory: zip64EOCD) + } + } + + #if swift(>=5.0) + static func makeBackingConfiguration(for data: Data, mode: AccessMode) + -> BackingConfiguration? + { + let posixMode: String + switch mode { + case .read: posixMode = "rb" + case .create: posixMode = "wb+" + case .update: posixMode = "rb+" + } + let memoryFile = MemoryFile(data: data) + guard let archiveFile = memoryFile.open(mode: posixMode) else { return nil } + + switch mode { + case .read: + guard let (eocdRecord, zip64EOCD) = Archive.scanForEndOfCentralDirectoryRecord(in: archiveFile) else { + return nil + } + + return BackingConfiguration( + file: archiveFile, + endOfCentralDirectoryRecord: eocdRecord, + zip64EndOfCentralDirectory: zip64EOCD, + memoryFile: memoryFile) + case .create: + let endOfCentralDirectoryRecord = EndOfCentralDirectoryRecord( + numberOfDisk: 0, + numberOfDiskStart: 0, + totalNumberOfEntriesOnDisk: 0, + totalNumberOfEntriesInCentralDirectory: 0, + sizeOfCentralDirectory: 0, + offsetToStartOfCentralDirectory: 0, + zipFileCommentLength: 0, + zipFileCommentData: Data()) + _ = endOfCentralDirectoryRecord.data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in + fwrite(buffer.baseAddress, buffer.count, 1, archiveFile) // Errors handled during read + } + fallthrough + case .update: + guard let (eocdRecord, zip64EOCD) = Archive.scanForEndOfCentralDirectoryRecord(in: archiveFile) else { + return nil + } + + fseeko(archiveFile, 0, SEEK_SET) + return BackingConfiguration( + file: archiveFile, + endOfCentralDirectoryRecord: eocdRecord, + zip64EndOfCentralDirectory: zip64EOCD, + memoryFile: memoryFile) + } + } + #endif +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift new file mode 100644 index 00000000..28690de5 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift @@ -0,0 +1,351 @@ +// +// Archive+Helpers.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + + // MARK: - Reading + + func readUncompressed( + entry: Entry, + bufferSize: Int, + skipCRC32: Bool, + progress: Progress? = nil, + with consumer: Consumer) + throws -> CRC32 + { + let size = entry.centralDirectoryStructure.effectiveUncompressedSize + guard size <= .max else { throw ArchiveError.invalidEntrySize } + return try Data.consumePart( + of: Int64(size), + chunkSize: bufferSize, + skipCRC32: skipCRC32, + provider: { _, chunkSize -> Data in + try Data.readChunk(of: chunkSize, from: self.archiveFile) + }, + consumer: { data in + if progress?.isCancelled == true { throw ArchiveError.cancelledOperation } + try consumer(data) + progress?.completedUnitCount += Int64(data.count) + }) + } + + func readCompressed( + entry: Entry, + bufferSize: Int, + skipCRC32: Bool, + progress: Progress? = nil, + with consumer: Consumer) + throws -> CRC32 + { + let size = entry.centralDirectoryStructure.effectiveCompressedSize + guard size <= .max else { throw ArchiveError.invalidEntrySize } + return try Data.decompress( + size: Int64(size), + bufferSize: bufferSize, + skipCRC32: skipCRC32, + provider: { _, chunkSize -> Data in + try Data.readChunk(of: chunkSize, from: self.archiveFile) + }, + consumer: { data in + if progress?.isCancelled == true { throw ArchiveError.cancelledOperation } + try consumer(data) + progress?.completedUnitCount += Int64(data.count) + }) + } + + // MARK: - Writing + + func writeEntry( + uncompressedSize: Int64, + type: Entry.EntryType, + compressionMethod: CompressionMethod, + bufferSize: Int, + progress: Progress? = nil, + provider: Provider) throws -> (sizeWritten: Int64, crc32: CRC32) + { + var checksum = CRC32(0) + var sizeWritten = Int64(0) + switch type { + case .file: + switch compressionMethod { + case .none: + (sizeWritten, checksum) = try writeUncompressed( + size: uncompressedSize, + bufferSize: bufferSize, + progress: progress, + provider: provider) + case .deflate: + (sizeWritten, checksum) = try writeCompressed( + size: uncompressedSize, + bufferSize: bufferSize, + progress: progress, + provider: provider) + } + case .directory: + _ = try provider(0, 0) + if let progress { progress.completedUnitCount = progress.totalUnitCount } + case .symlink: + let (linkSizeWritten, linkChecksum) = try writeSymbolicLink( + size: Int(uncompressedSize), + provider: provider) + (sizeWritten, checksum) = (Int64(linkSizeWritten), linkChecksum) + if let progress { progress.completedUnitCount = progress.totalUnitCount } + } + return (sizeWritten, checksum) + } + + func writeLocalFileHeader( + path: String, + compressionMethod: CompressionMethod, + size: (uncompressed: UInt64, compressed: UInt64), + checksum: CRC32, + modificationDateTime: (UInt16, UInt16)) + throws -> LocalFileHeader + { + // We always set Bit 11 in generalPurposeBitFlag, which indicates an UTF-8 encoded path. + guard let fileNameData = path.data(using: .utf8) else { throw ArchiveError.invalidEntryPath } + + var uncompressedSizeOfLFH = UInt32(0) + var compressedSizeOfLFH = UInt32(0) + var extraFieldLength = UInt16(0) + var zip64ExtendedInformation: Entry.ZIP64ExtendedInformation? + var versionNeededToExtract = Version.v20.rawValue + // ZIP64 Extended Information in the Local header MUST include BOTH original and compressed file size fields. + if size.uncompressed >= maxUncompressedSize || size.compressed >= maxCompressedSize { + uncompressedSizeOfLFH = .max + compressedSizeOfLFH = .max + extraFieldLength = UInt16(20) // 2 + 2 + 8 + 8 + versionNeededToExtract = Version.v45.rawValue + zip64ExtendedInformation = Entry.ZIP64ExtendedInformation( + dataSize: extraFieldLength - 4, + uncompressedSize: size.uncompressed, + compressedSize: size.compressed, + relativeOffsetOfLocalHeader: 0, + diskNumberStart: 0) + } else { + uncompressedSizeOfLFH = UInt32(size.uncompressed) + compressedSizeOfLFH = UInt32(size.compressed) + } + + let localFileHeader = LocalFileHeader( + versionNeededToExtract: versionNeededToExtract, + generalPurposeBitFlag: UInt16(2048), + compressionMethod: compressionMethod.rawValue, + lastModFileTime: modificationDateTime.1, + lastModFileDate: modificationDateTime.0, + crc32: checksum, + compressedSize: compressedSizeOfLFH, + uncompressedSize: uncompressedSizeOfLFH, + fileNameLength: UInt16(fileNameData.count), + extraFieldLength: extraFieldLength, + fileNameData: fileNameData, + extraFieldData: zip64ExtendedInformation?.data ?? Data()) + _ = try Data.write(chunk: localFileHeader.data, to: archiveFile) + return localFileHeader + } + + func writeCentralDirectoryStructure( + localFileHeader: LocalFileHeader, + relativeOffset: UInt64, + externalFileAttributes: UInt32) + throws -> CentralDirectoryStructure + { + var extraUncompressedSize: UInt64? + var extraCompressedSize: UInt64? + var extraOffset: UInt64? + var relativeOffsetOfCD = UInt32(0) + var extraFieldLength = UInt16(0) + var zip64ExtendedInformation: Entry.ZIP64ExtendedInformation? + if localFileHeader.uncompressedSize == .max || localFileHeader.compressedSize == .max { + let zip64Field = Entry.ZIP64ExtendedInformation + .scanForZIP64Field(in: localFileHeader.extraFieldData, fields: [.uncompressedSize, .compressedSize]) + extraUncompressedSize = zip64Field?.uncompressedSize + extraCompressedSize = zip64Field?.compressedSize + } + if relativeOffset >= maxOffsetOfLocalFileHeader { + extraOffset = relativeOffset + relativeOffsetOfCD = .max + } else { + relativeOffsetOfCD = UInt32(relativeOffset) + } + extraFieldLength = [extraUncompressedSize, extraCompressedSize, extraOffset] + .compactMap { $0 } + .reduce(UInt16(0)) { $0 + UInt16(MemoryLayout.size(ofValue: $1)) } + if extraFieldLength > 0 { + // Size of extra fields, shouldn't include the leading 4 bytes + zip64ExtendedInformation = Entry.ZIP64ExtendedInformation( + dataSize: extraFieldLength, + uncompressedSize: extraUncompressedSize ?? 0, + compressedSize: extraCompressedSize ?? 0, + relativeOffsetOfLocalHeader: extraOffset ?? 0, + diskNumberStart: 0) + extraFieldLength += Entry.ZIP64ExtendedInformation.headerSize + } + let centralDirectory = CentralDirectoryStructure( + localFileHeader: localFileHeader, + fileAttributes: externalFileAttributes, + relativeOffset: relativeOffsetOfCD, + extraField: ( + extraFieldLength, + zip64ExtendedInformation?.data ?? Data())) + _ = try Data.write(chunk: centralDirectory.data, to: archiveFile) + return centralDirectory + } + + func writeEndOfCentralDirectory( + centralDirectoryStructure: CentralDirectoryStructure, + startOfCentralDirectory: UInt64, + startOfEndOfCentralDirectory: UInt64, + operation: ModifyOperation) + throws -> EndOfCentralDirectoryStructure + { + var record = endOfCentralDirectoryRecord + let sizeOfCD = sizeOfCentralDirectory + let numberOfTotalEntries = totalNumberOfEntriesInCentralDirectory + let countChange = operation.rawValue + var dataLength = centralDirectoryStructure.extraFieldLength + dataLength += centralDirectoryStructure.fileNameLength + dataLength += centralDirectoryStructure.fileCommentLength + let cdDataLengthChange = countChange * (Int(dataLength) + CentralDirectoryStructure.size) + let (updatedSizeOfCD, updatedNumberOfEntries): (UInt64, UInt64) = try { + switch operation { + case .add: + guard .max - sizeOfCD >= cdDataLengthChange else { + throw ArchiveError.invalidCentralDirectorySize + } + guard .max - numberOfTotalEntries >= countChange else { + throw ArchiveError.invalidCentralDirectoryEntryCount + } + return (sizeOfCD + UInt64(cdDataLengthChange), numberOfTotalEntries + UInt64(countChange)) + case .remove: + return (sizeOfCD - UInt64(-cdDataLengthChange), numberOfTotalEntries - UInt64(-countChange)) + } + }() + let sizeOfCDForEOCD = updatedSizeOfCD >= maxSizeOfCentralDirectory + ? UInt32.max + : UInt32(updatedSizeOfCD) + let numberOfTotalEntriesForEOCD = updatedNumberOfEntries >= maxTotalNumberOfEntries + ? UInt16.max + : UInt16(updatedNumberOfEntries) + let offsetOfCDForEOCD = startOfCentralDirectory >= maxOffsetOfCentralDirectory + ? UInt32.max + : UInt32(startOfCentralDirectory) + // ZIP64 End of Central Directory + var zip64EOCD: ZIP64EndOfCentralDirectory? + if numberOfTotalEntriesForEOCD == .max || offsetOfCDForEOCD == .max || sizeOfCDForEOCD == .max { + zip64EOCD = try writeZIP64EOCD( + totalNumberOfEntries: updatedNumberOfEntries, + sizeOfCentralDirectory: updatedSizeOfCD, + offsetOfCentralDirectory: startOfCentralDirectory, + offsetOfEndOfCentralDirectory: startOfEndOfCentralDirectory) + } + record = EndOfCentralDirectoryRecord( + record: record, + numberOfEntriesOnDisk: numberOfTotalEntriesForEOCD, + numberOfEntriesInCentralDirectory: numberOfTotalEntriesForEOCD, + updatedSizeOfCentralDirectory: sizeOfCDForEOCD, + startOfCentralDirectory: offsetOfCDForEOCD) + _ = try Data.write(chunk: record.data, to: archiveFile) + return (record, zip64EOCD) + } + + func writeUncompressed( + size: Int64, + bufferSize: Int, + progress: Progress? = nil, + provider: Provider) throws -> (sizeWritten: Int64, checksum: CRC32) + { + var position: Int64 = 0 + var sizeWritten: Int64 = 0 + var checksum = CRC32(0) + while position < size { + if progress?.isCancelled == true { throw ArchiveError.cancelledOperation } + let readSize = (size - position) >= bufferSize ? bufferSize : Int(size - position) + let entryChunk = try provider(position, readSize) + checksum = entryChunk.crc32(checksum: checksum) + sizeWritten += Int64(try Data.write(chunk: entryChunk, to: archiveFile)) + position += Int64(bufferSize) + progress?.completedUnitCount = sizeWritten + } + return (sizeWritten, checksum) + } + + func writeCompressed( + size: Int64, + bufferSize: Int, + progress: Progress? = nil, + provider: Provider) throws -> (sizeWritten: Int64, checksum: CRC32) + { + var sizeWritten: Int64 = 0 + let consumer: Consumer = { data in sizeWritten += Int64(try Data.write(chunk: data, to: self.archiveFile)) } + let checksum = try Data.compress( + size: size, + bufferSize: bufferSize, + provider: { position, size -> Data in + if progress?.isCancelled == true { throw ArchiveError.cancelledOperation } + let data = try provider(position, size) + progress?.completedUnitCount += Int64(data.count) + return data + }, + consumer: consumer) + return (sizeWritten, checksum) + } + + func writeSymbolicLink(size: Int, provider: Provider) throws -> (sizeWritten: Int, checksum: CRC32) { + // The reported size of a symlink is the number of characters in the path it points to. + let linkData = try provider(0, size) + let checksum = linkData.crc32(checksum: 0) + let sizeWritten = try Data.write(chunk: linkData, to: archiveFile) + return (sizeWritten, checksum) + } + + func writeZIP64EOCD( + totalNumberOfEntries: UInt64, + sizeOfCentralDirectory: UInt64, + offsetOfCentralDirectory: UInt64, + offsetOfEndOfCentralDirectory: UInt64) + throws -> ZIP64EndOfCentralDirectory + { + var zip64EOCD: ZIP64EndOfCentralDirectory = zip64EndOfCentralDirectory ?? { + // Shouldn't include the leading 12 bytes: (size - 12 = 44) + let record = ZIP64EndOfCentralDirectoryRecord( + sizeOfZIP64EndOfCentralDirectoryRecord: UInt64(44), + versionMadeBy: UInt16(789), + versionNeededToExtract: Version.v45.rawValue, + numberOfDisk: 0, + numberOfDiskStart: 0, + totalNumberOfEntriesOnDisk: 0, + totalNumberOfEntriesInCentralDirectory: 0, + sizeOfCentralDirectory: 0, + offsetToStartOfCentralDirectory: 0, + zip64ExtensibleDataSector: Data()) + let locator = ZIP64EndOfCentralDirectoryLocator( + numberOfDiskWithZIP64EOCDRecordStart: 0, + relativeOffsetOfZIP64EOCDRecord: 0, + totalNumberOfDisk: 1) + return ZIP64EndOfCentralDirectory(record: record, locator: locator) + }() + + let updatedRecord = ZIP64EndOfCentralDirectoryRecord( + record: zip64EOCD.record, + numberOfEntriesOnDisk: totalNumberOfEntries, + numberOfEntriesInCD: totalNumberOfEntries, + sizeOfCentralDirectory: sizeOfCentralDirectory, + offsetToStartOfCD: offsetOfCentralDirectory) + let updatedLocator = ZIP64EndOfCentralDirectoryLocator( + locator: zip64EOCD.locator, + offsetOfZIP64EOCDRecord: offsetOfEndOfCentralDirectory) + zip64EOCD = ZIP64EndOfCentralDirectory(record: updatedRecord, locator: updatedLocator) + _ = try Data.write(chunk: zip64EOCD.data, to: archiveFile) + return zip64EOCD + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+MemoryFile.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+MemoryFile.swift new file mode 100644 index 00000000..cda58976 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+MemoryFile.swift @@ -0,0 +1,183 @@ +// +// Archive+MemoryFile.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + var isMemoryArchive: Bool { url.scheme == memoryURLScheme } +} + +#if swift(>=5.0) + +extension Archive { + /// Returns a `Data` object containing a representation of the receiver. + var data: Data? { memoryFile?.data } +} + +class MemoryFile { + + // MARK: Lifecycle + + init(data: Data = Data()) { + self.data = data + } + + // MARK: Internal + + private(set) var data: Data + + func open(mode: String) -> FILEPointer? { + let cookie = Unmanaged.passRetained(self) + let writable = mode.count > 0 && (mode.first! != "r" || mode.last! == "+") + let append = mode.count > 0 && mode.first! == "a" + #if os(macOS) || canImport(UIKit) || os(Android) + let result = writable + ? funopen(cookie.toOpaque(), readStub, writeStub, seekStub, closeStub) + : funopen(cookie.toOpaque(), readStub, nil, seekStub, closeStub) + #else + let stubs = cookie_io_functions_t(read: readStub, write: writeStub, seek: seekStub, close: closeStub) + let result = fopencookie(cookie.toOpaque(), mode, stubs) + #endif + if append { + fseeko(result, 0, SEEK_END) + } + return result + } + + // MARK: Private + + private var offset = 0 + +} + +extension MemoryFile { + fileprivate func readData(buffer: UnsafeMutableRawBufferPointer) -> Int { + let size = min(buffer.count, data.count - offset) + let start = data.startIndex + data.copyBytes(to: buffer.bindMemory(to: UInt8.self), from: start + offset.. Int { + let start = data.startIndex + if offset < data.count, offset + buffer.count > data.count { + data.removeSubrange(start + offset.. data.count { + data.append(Data(count: offset - data.count)) + } + if offset == data.count { + data.append(buffer.bindMemory(to: UInt8.self)) + } else { + let start = data.startIndex // May have changed in earlier mutation + data.replaceSubrange(start + offset.. Int { + var result = -1 + if whence == SEEK_SET { + result = offset + } else if whence == SEEK_CUR { + result = self.offset + offset + } else if whence == SEEK_END { + result = data.count + offset + } + self.offset = result + return self.offset + } +} + +private func fileFromCookie(cookie: UnsafeRawPointer) -> MemoryFile { + Unmanaged.fromOpaque(cookie).takeUnretainedValue() +} + +private func closeStub(_ cookie: UnsafeMutableRawPointer?) -> Int32 { + if let cookie { + Unmanaged.fromOpaque(cookie).release() + } + return 0 +} + +#if os(macOS) || canImport(UIKit) || os(Android) +private func readStub( + _ cookie: UnsafeMutableRawPointer?, + _ bytePtr: UnsafeMutablePointer?, + _ count: Int32) + -> Int32 +{ + guard let cookie, let bytePtr else { return 0 } + return Int32(fileFromCookie(cookie: cookie).readData( + buffer: UnsafeMutableRawBufferPointer(start: bytePtr, count: Int(count)))) +} + +private func writeStub( + _ cookie: UnsafeMutableRawPointer?, + _ bytePtr: UnsafePointer?, + _ count: Int32) + -> Int32 +{ + guard let cookie, let bytePtr else { return 0 } + return Int32(fileFromCookie(cookie: cookie).writeData( + buffer: UnsafeRawBufferPointer(start: bytePtr, count: Int(count)))) +} + +private func seekStub( + _ cookie: UnsafeMutableRawPointer?, + _ offset: fpos_t, + _ whence: Int32) + -> fpos_t +{ + guard let cookie else { return 0 } + return fpos_t(fileFromCookie(cookie: cookie).seek(offset: Int(offset), whence: whence)) +} + +#else +private func readStub( + _ cookie: UnsafeMutableRawPointer?, + _ bytePtr: UnsafeMutablePointer?, + _ count: Int) + -> Int +{ + guard let cookie, let bytePtr else { return 0 } + return fileFromCookie(cookie: cookie).readData( + buffer: UnsafeMutableRawBufferPointer(start: bytePtr, count: count)) +} + +private func writeStub( + _ cookie: UnsafeMutableRawPointer?, + _ bytePtr: UnsafePointer?, + _ count: Int) + -> Int +{ + guard let cookie, let bytePtr else { return 0 } + return fileFromCookie(cookie: cookie).writeData( + buffer: UnsafeRawBufferPointer(start: bytePtr, count: count)) +} + +private func seekStub( + _ cookie: UnsafeMutableRawPointer?, + _ offset: UnsafeMutablePointer?, + _ whence: Int32) + -> Int32 +{ + guard let cookie, let offset else { return 0 } + let result = fileFromCookie(cookie: cookie).seek(offset: Int(offset.pointee), whence: whence) + if result >= 0 { + offset.pointee = result + return 0 + } else { + return -1 + } +} +#endif +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Progress.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Progress.swift new file mode 100644 index 00000000..f8c3bd69 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Progress.swift @@ -0,0 +1,66 @@ +// +// Archive+Progress.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + /// The number of the work units that have to be performed when + /// removing `entry` from the receiver. + /// + /// - Parameter entry: The entry that will be removed. + /// - Returns: The number of the work units. + func totalUnitCountForRemoving(_ entry: Entry) -> Int64 { + Int64(offsetToStartOfCentralDirectory - entry.localSize) + } + + func makeProgressForRemoving(_ entry: Entry) -> Progress { + Progress(totalUnitCount: totalUnitCountForRemoving(entry)) + } + + /// The number of the work units that have to be performed when + /// reading `entry` from the receiver. + /// + /// - Parameter entry: The entry that will be read. + /// - Returns: The number of the work units. + func totalUnitCountForReading(_ entry: Entry) -> Int64 { + switch entry.type { + case .file, .symlink: + return Int64(entry.uncompressedSize) + case .directory: + return defaultDirectoryUnitCount + } + } + + func makeProgressForReading(_ entry: Entry) -> Progress { + Progress(totalUnitCount: totalUnitCountForReading(entry)) + } + + /// The number of the work units that have to be performed when + /// adding the file at `url` to the receiver. + /// - Parameter entry: The entry that will be removed. + /// - Returns: The number of the work units. + func totalUnitCountForAddingItem(at url: URL) -> Int64 { + var count = Int64(0) + do { + let type = try FileManager.typeForItem(at: url) + switch type { + case .file, .symlink: + count = Int64(try FileManager.fileSizeForItem(at: url)) + case .directory: + count = defaultDirectoryUnitCount + } + } catch { count = -1 } + return count + } + + func makeProgressForAddingItem(at url: URL) -> Progress { + Progress(totalUnitCount: totalUnitCountForAddingItem(at: url)) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Reading.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Reading.swift new file mode 100644 index 00000000..cf5510dc --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Reading.swift @@ -0,0 +1,144 @@ +// +// Archive+Reading.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + /// Read a ZIP `Entry` from the receiver and write it to `url`. + /// + /// - Parameters: + /// - entry: The ZIP `Entry` to read. + /// - url: The destination file URL. + /// - bufferSize: The maximum size of the read buffer and the decompression buffer (if needed). + /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - progress: A progress object that can be used to track or cancel the extract operation. + /// - Returns: The checksum of the processed content or 0 if the `skipCRC32` flag was set to `true`. + /// - Throws: An error if the destination file cannot be written or the entry contains malformed content. + func extract( + _ entry: Entry, + to url: URL, + bufferSize: Int = defaultReadChunkSize, + skipCRC32: Bool = false, + progress: Progress? = nil) + throws -> CRC32 + { + guard bufferSize > 0 else { + throw ArchiveError.invalidBufferSize + } + let fileManager = FileManager() + var checksum = CRC32(0) + switch entry.type { + case .file: + guard !fileManager.itemExists(at: url) else { + throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: url.path]) + } + try fileManager.createParentDirectoryStructure(for: url) + let destinationRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + guard let destinationFile: FILEPointer = fopen(destinationRepresentation, "wb+") else { + throw CocoaError(.fileNoSuchFile) + } + defer { fclose(destinationFile) } + let consumer = { _ = try Data.write(chunk: $0, to: destinationFile) } + checksum = try extract( + entry, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + progress: progress, + consumer: consumer) + case .directory: + let consumer = { (_: Data) in + try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + } + checksum = try extract( + entry, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + progress: progress, + consumer: consumer) + case .symlink: + guard !fileManager.itemExists(at: url) else { + throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: url.path]) + } + let consumer = { (data: Data) in + guard let linkPath = String(data: data, encoding: .utf8) else { throw ArchiveError.invalidEntryPath } + try fileManager.createParentDirectoryStructure(for: url) + try fileManager.createSymbolicLink(atPath: url.path, withDestinationPath: linkPath) + } + checksum = try extract( + entry, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + progress: progress, + consumer: consumer) + } + let attributes = FileManager.attributes(from: entry) + try fileManager.setAttributes(attributes, ofItemAtPath: url.path) + return checksum + } + + /// Read a ZIP `Entry` from the receiver and forward its contents to a `Consumer` closure. + /// + /// - Parameters: + /// - entry: The ZIP `Entry` to read. + /// - bufferSize: The maximum size of the read buffer and the decompression buffer (if needed). + /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - progress: A progress object that can be used to track or cancel the extract operation. + /// - consumer: A closure that consumes contents of `Entry` as `Data` chunks. + /// - Returns: The checksum of the processed content or 0 if the `skipCRC32` flag was set to `true`.. + /// - Throws: An error if the destination file cannot be written or the entry contains malformed content. + func extract( + _ entry: Entry, + bufferSize: Int = defaultReadChunkSize, + skipCRC32: Bool = false, + progress: Progress? = nil, + consumer: Consumer) + throws -> CRC32 + { + guard bufferSize > 0 else { + throw ArchiveError.invalidBufferSize + } + var checksum = CRC32(0) + let localFileHeader = entry.localFileHeader + guard entry.dataOffset <= .max else { throw ArchiveError.invalidLocalHeaderDataOffset } + fseeko(archiveFile, off_t(entry.dataOffset), SEEK_SET) + progress?.totalUnitCount = totalUnitCountForReading(entry) + switch entry.type { + case .file: + guard let compressionMethod = CompressionMethod(rawValue: localFileHeader.compressionMethod) else { + throw ArchiveError.invalidCompressionMethod + } + switch compressionMethod { + case .none: checksum = try readUncompressed( + entry: entry, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + progress: progress, + with: consumer) + case .deflate: checksum = try readCompressed( + entry: entry, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + progress: progress, + with: consumer) + } + case .directory: + try consumer(Data()) + progress?.completedUnitCount = totalUnitCountForReading(entry) + case .symlink: + let localFileHeader = entry.localFileHeader + let size = Int(localFileHeader.compressedSize) + let data = try Data.readChunk(of: size, from: archiveFile) + checksum = data.crc32(checksum: 0) + try consumer(data) + progress?.completedUnitCount = totalUnitCountForReading(entry) + } + return checksum + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ReadingDeprecated.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ReadingDeprecated.swift new file mode 100644 index 00000000..1e303654 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ReadingDeprecated.swift @@ -0,0 +1,49 @@ +// +// Archive+ReadingDeprecated.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + + @available( + *, + deprecated, + message: "Please use `Int` for `bufferSize`.") + func extract( + _ entry: Entry, + to url: URL, + bufferSize: UInt32, + skipCRC32: Bool = false, + progress: Progress? = nil) + throws -> CRC32 + { + try extract(entry, to: url, bufferSize: Int(bufferSize), skipCRC32: skipCRC32, progress: progress) + } + + @available( + *, + deprecated, + message: "Please use `Int` for `bufferSize`.") + func extract( + _ entry: Entry, + bufferSize: UInt32, + skipCRC32: Bool = false, + progress: Progress? = nil, + consumer: Consumer) + throws -> CRC32 + { + try extract( + entry, + bufferSize: Int(bufferSize), + skipCRC32: skipCRC32, + progress: progress, + consumer: consumer) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Writing.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Writing.swift new file mode 100644 index 00000000..80064394 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Writing.swift @@ -0,0 +1,385 @@ +// +// Archive+Writing.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + enum ModifyOperation: Int { + case remove = -1 + case add = 1 + } + + typealias EndOfCentralDirectoryStructure = (EndOfCentralDirectoryRecord, ZIP64EndOfCentralDirectory?) + + /// Write files, directories or symlinks to the receiver. + /// + /// - Parameters: + /// - path: The path that is used to identify an `Entry` within the `Archive` file. + /// - baseURL: The base URL of the resource to add. + /// The `baseURL` combined with `path` must form a fully qualified file URL. + /// - compressionMethod: Indicates the `CompressionMethod` that should be applied to `Entry`. + /// By default, no compression will be applied. + /// - bufferSize: The maximum size of the write buffer and the compression buffer (if needed). + /// - progress: A progress object that can be used to track or cancel the add operation. + /// - Throws: An error if the source file cannot be read or the receiver is not writable. + func addEntry( + with path: String, + relativeTo baseURL: URL, + compressionMethod: CompressionMethod = .none, + bufferSize: Int = defaultWriteChunkSize, + progress: Progress? = nil) + throws + { + let fileURL = baseURL.appendingPathComponent(path) + + try addEntry( + with: path, + fileURL: fileURL, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress) + } + + /// Write files, directories or symlinks to the receiver. + /// + /// - Parameters: + /// - path: The path that is used to identify an `Entry` within the `Archive` file. + /// - fileURL: An absolute file URL referring to the resource to add. + /// - compressionMethod: Indicates the `CompressionMethod` that should be applied to `Entry`. + /// By default, no compression will be applied. + /// - bufferSize: The maximum size of the write buffer and the compression buffer (if needed). + /// - progress: A progress object that can be used to track or cancel the add operation. + /// - Throws: An error if the source file cannot be read or the receiver is not writable. + func addEntry( + with path: String, + fileURL: URL, + compressionMethod: CompressionMethod = .none, + bufferSize: Int = defaultWriteChunkSize, + progress: Progress? = nil) + throws + { + let fileManager = FileManager() + guard fileManager.itemExists(at: fileURL) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: fileURL.path]) + } + let type = try FileManager.typeForItem(at: fileURL) + // symlinks do not need to be readable + guard type == .symlink || fileManager.isReadableFile(atPath: fileURL.path) else { + throw CocoaError(.fileReadNoPermission, userInfo: [NSFilePathErrorKey: url.path]) + } + let modDate = try FileManager.fileModificationDateTimeForItem(at: fileURL) + let uncompressedSize = type == .directory ? 0 : try FileManager.fileSizeForItem(at: fileURL) + let permissions = try FileManager.permissionsForItem(at: fileURL) + var provider: Provider + switch type { + case .file: + let entryFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: fileURL.path) + guard let entryFile: FILEPointer = fopen(entryFileSystemRepresentation, "rb") else { + throw CocoaError(.fileNoSuchFile) + } + defer { fclose(entryFile) } + provider = { _, _ in try Data.readChunk(of: bufferSize, from: entryFile) } + try addEntry( + with: path, + type: type, + uncompressedSize: uncompressedSize, + modificationDate: modDate, + permissions: permissions, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress, + provider: provider) + case .directory: + provider = { _, _ in Data() } + try addEntry( + with: path.hasSuffix("/") ? path : path + "/", + type: type, + uncompressedSize: uncompressedSize, + modificationDate: modDate, + permissions: permissions, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress, + provider: provider) + case .symlink: + provider = { _, _ -> Data in + let linkDestination = try fileManager.destinationOfSymbolicLink(atPath: fileURL.path) + let linkFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: linkDestination) + let linkLength = Int(strlen(linkFileSystemRepresentation)) + let linkBuffer = UnsafeBufferPointer(start: linkFileSystemRepresentation, count: linkLength) + return Data(buffer: linkBuffer) + } + try addEntry( + with: path, + type: type, + uncompressedSize: uncompressedSize, + modificationDate: modDate, + permissions: permissions, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress, + provider: provider) + } + } + + /// Write files, directories or symlinks to the receiver. + /// + /// - Parameters: + /// - path: The path that is used to identify an `Entry` within the `Archive` file. + /// - type: Indicates the `Entry.EntryType` of the added content. + /// - uncompressedSize: The uncompressed size of the data that is going to be added with `provider`. + /// - modificationDate: A `Date` describing the file modification date of the `Entry`. + /// Default is the current `Date`. + /// - permissions: POSIX file permissions for the `Entry`. + /// Default is `0`o`644` for files and symlinks and `0`o`755` for directories. + /// - compressionMethod: Indicates the `CompressionMethod` that should be applied to `Entry`. + /// By default, no compression will be applied. + /// - bufferSize: The maximum size of the write buffer and the compression buffer (if needed). + /// - progress: A progress object that can be used to track or cancel the add operation. + /// - provider: A closure that accepts a position and a chunk size. Returns a `Data` chunk. + /// - Throws: An error if the source data is invalid or the receiver is not writable. + func addEntry( + with path: String, + type: Entry.EntryType, + uncompressedSize: Int64, + modificationDate: Date = Date(), + permissions: UInt16? = nil, + compressionMethod: CompressionMethod = .none, + bufferSize: Int = defaultWriteChunkSize, + progress: Progress? = nil, + provider: Provider) + throws + { + guard accessMode != .read else { throw ArchiveError.unwritableArchive } + // Directories and symlinks cannot be compressed + let compressionMethod = type == .file ? compressionMethod : .none + progress?.totalUnitCount = type == .directory ? defaultDirectoryUnitCount : uncompressedSize + let (eocdRecord, zip64EOCD) = (endOfCentralDirectoryRecord, zip64EndOfCentralDirectory) + guard offsetToStartOfCentralDirectory <= .max else { throw ArchiveError.invalidCentralDirectoryOffset } + var startOfCD = Int64(offsetToStartOfCentralDirectory) + fseeko(archiveFile, off_t(startOfCD), SEEK_SET) + let existingSize = sizeOfCentralDirectory + let existingData = try Data.readChunk(of: Int(existingSize), from: archiveFile) + fseeko(archiveFile, off_t(startOfCD), SEEK_SET) + let fileHeaderStart = Int64(ftello(archiveFile)) + let modDateTime = modificationDate.fileModificationDateTime + defer { fflush(self.archiveFile) } + do { + // Local File Header + var localFileHeader = try writeLocalFileHeader( + path: path, + compressionMethod: compressionMethod, + size: (UInt64(uncompressedSize), 0), + checksum: 0, + modificationDateTime: modDateTime) + // File Data + let (written, checksum) = try writeEntry( + uncompressedSize: uncompressedSize, + type: type, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress, + provider: provider) + startOfCD = Int64(ftello(archiveFile)) + // Write the local file header a second time. Now with compressedSize (if applicable) and a valid checksum. + fseeko(archiveFile, off_t(fileHeaderStart), SEEK_SET) + localFileHeader = try writeLocalFileHeader( + path: path, + compressionMethod: compressionMethod, + size: (UInt64(uncompressedSize), UInt64(written)), + checksum: checksum, + modificationDateTime: modDateTime) + // Central Directory + fseeko(archiveFile, off_t(startOfCD), SEEK_SET) + _ = try Data.writeLargeChunk(existingData, size: existingSize, bufferSize: bufferSize, to: archiveFile) + let permissions = permissions ?? (type == .directory ? defaultDirectoryPermissions : defaultFilePermissions) + let externalAttributes = FileManager.externalFileAttributesForEntry(of: type, permissions: permissions) + let centralDir = try writeCentralDirectoryStructure( + localFileHeader: localFileHeader, + relativeOffset: UInt64(fileHeaderStart), + externalFileAttributes: externalAttributes) + // End of Central Directory Record (including ZIP64 End of Central Directory Record/Locator) + let startOfEOCD = UInt64(ftello(archiveFile)) + let eocd = try writeEndOfCentralDirectory( + centralDirectoryStructure: centralDir, + startOfCentralDirectory: UInt64(startOfCD), + startOfEndOfCentralDirectory: startOfEOCD, + operation: .add) + (endOfCentralDirectoryRecord, zip64EndOfCentralDirectory) = eocd + } catch ArchiveError.cancelledOperation { + try rollback(UInt64(fileHeaderStart), (existingData, existingSize), bufferSize, eocdRecord, zip64EOCD) + throw ArchiveError.cancelledOperation + } + } + + /// Remove a ZIP `Entry` from the receiver. + /// + /// - Parameters: + /// - entry: The `Entry` to remove. + /// - bufferSize: The maximum size for the read and write buffers used during removal. + /// - progress: A progress object that can be used to track or cancel the remove operation. + /// - Throws: An error if the `Entry` is malformed or the receiver is not writable. + func remove(_ entry: Entry, bufferSize: Int = defaultReadChunkSize, progress: Progress? = nil) throws { + guard accessMode != .read else { throw ArchiveError.unwritableArchive } + let (tempArchive, tempDir) = try makeTempArchive() + defer { tempDir.map { try? FileManager().removeItem(at: $0) } } + progress?.totalUnitCount = totalUnitCountForRemoving(entry) + var centralDirectoryData = Data() + var offset: UInt64 = 0 + for currentEntry in self { + let cds = currentEntry.centralDirectoryStructure + if currentEntry != entry { + let entryStart = cds.effectiveRelativeOffsetOfLocalHeader + fseeko(archiveFile, off_t(entryStart), SEEK_SET) + let provider: Provider = { _, chunkSize -> Data in + try Data.readChunk(of: chunkSize, from: self.archiveFile) + } + let consumer: Consumer = { + if progress?.isCancelled == true { throw ArchiveError.cancelledOperation } + _ = try Data.write(chunk: $0, to: tempArchive.archiveFile) + progress?.completedUnitCount += Int64($0.count) + } + guard currentEntry.localSize <= .max else { throw ArchiveError.invalidLocalHeaderSize } + _ = try Data.consumePart( + of: Int64(currentEntry.localSize), + chunkSize: bufferSize, + provider: provider, + consumer: consumer) + let updatedCentralDirectory = updateOffsetInCentralDirectory( + centralDirectoryStructure: cds, + updatedOffset: entryStart - offset) + centralDirectoryData.append(updatedCentralDirectory.data) + } else { offset = currentEntry.localSize } + } + let startOfCentralDirectory = UInt64(ftello(tempArchive.archiveFile)) + _ = try Data.write(chunk: centralDirectoryData, to: tempArchive.archiveFile) + let startOfEndOfCentralDirectory = UInt64(ftello(tempArchive.archiveFile)) + tempArchive.endOfCentralDirectoryRecord = endOfCentralDirectoryRecord + tempArchive.zip64EndOfCentralDirectory = zip64EndOfCentralDirectory + let ecodStructure = try + tempArchive.writeEndOfCentralDirectory( + centralDirectoryStructure: entry.centralDirectoryStructure, + startOfCentralDirectory: startOfCentralDirectory, + startOfEndOfCentralDirectory: startOfEndOfCentralDirectory, + operation: .remove) + (tempArchive.endOfCentralDirectoryRecord, tempArchive.zip64EndOfCentralDirectory) = ecodStructure + (endOfCentralDirectoryRecord, zip64EndOfCentralDirectory) = ecodStructure + fflush(tempArchive.archiveFile) + try replaceCurrentArchive(with: tempArchive) + } + + func replaceCurrentArchive(with archive: Archive) throws { + fclose(archiveFile) + if isMemoryArchive { + #if swift(>=5.0) + guard + let data = archive.data, + let config = Archive.makeBackingConfiguration(for: data, mode: .update) + else { + throw ArchiveError.unwritableArchive + } + archiveFile = config.file + memoryFile = config.memoryFile + endOfCentralDirectoryRecord = config.endOfCentralDirectoryRecord + zip64EndOfCentralDirectory = config.zip64EndOfCentralDirectory + #endif + } else { + let fileManager = FileManager() + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + do { + _ = try fileManager.replaceItemAt(url, withItemAt: archive.url) + } catch { + _ = try fileManager.removeItem(at: url) + _ = try fileManager.moveItem(at: archive.url, to: url) + } + #else + _ = try fileManager.removeItem(at: url) + _ = try fileManager.moveItem(at: archive.url, to: url) + #endif + let fileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + guard let file = fopen(fileSystemRepresentation, "rb+") else { throw ArchiveError.unreadableArchive } + archiveFile = file + } + } +} + +// MARK: - Private + +extension Archive { + + private func updateOffsetInCentralDirectory( + centralDirectoryStructure: CentralDirectoryStructure, + updatedOffset: UInt64) + -> CentralDirectoryStructure + { + let zip64ExtendedInformation = Entry.ZIP64ExtendedInformation( + zip64ExtendedInformation: centralDirectoryStructure.zip64ExtendedInformation, offset: updatedOffset) + let offsetInCD = updatedOffset < maxOffsetOfLocalFileHeader ? UInt32(updatedOffset) : UInt32.max + return CentralDirectoryStructure( + centralDirectoryStructure: centralDirectoryStructure, + zip64ExtendedInformation: zip64ExtendedInformation, + relativeOffset: offsetInCD) + } + + private func rollback( + _ localFileHeaderStart: UInt64, + _ existingCentralDirectory: (data: Data, size: UInt64), + _ bufferSize: Int, + _ endOfCentralDirRecord: EndOfCentralDirectoryRecord, + _ zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory?) + throws + { + fflush(archiveFile) + ftruncate(fileno(archiveFile), off_t(localFileHeaderStart)) + fseeko(archiveFile, off_t(localFileHeaderStart), SEEK_SET) + _ = try Data.writeLargeChunk( + existingCentralDirectory.data, + size: existingCentralDirectory.size, + bufferSize: bufferSize, + to: archiveFile) + _ = try Data.write(chunk: existingCentralDirectory.data, to: archiveFile) + if let zip64EOCD = zip64EndOfCentralDirectory { + _ = try Data.write(chunk: zip64EOCD.data, to: archiveFile) + } + _ = try Data.write(chunk: endOfCentralDirRecord.data, to: archiveFile) + } + + private func makeTempArchive() throws -> (Archive, URL?) { + var archive: Archive + var url: URL? + if isMemoryArchive { + #if swift(>=5.0) + guard + let tempArchive = Archive( + data: Data(), + accessMode: .create, + preferredEncoding: preferredEncoding) + else { + throw ArchiveError.unwritableArchive + } + archive = tempArchive + #else + fatalError("Memory archives are unsupported.") + #endif + } else { + let manager = FileManager() + let tempDir = URL.temporaryReplacementDirectoryURL(for: self) + let uniqueString = ProcessInfo.processInfo.globallyUniqueString + let tempArchiveURL = tempDir.appendingPathComponent(uniqueString) + try manager.createParentDirectoryStructure(for: tempArchiveURL) + guard let tempArchive = Archive(url: tempArchiveURL, accessMode: .create) else { + throw ArchiveError.unwritableArchive + } + archive = tempArchive + url = tempDir + } + return (archive, url) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+WritingDeprecated.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+WritingDeprecated.swift new file mode 100644 index 00000000..311c6a81 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+WritingDeprecated.swift @@ -0,0 +1,91 @@ +// +// Archive+WritingDeprecated.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Archive { + + @available( + *, + deprecated, + message: "Please use `Int` for `bufferSize`.") + func addEntry( + with path: String, + relativeTo baseURL: URL, + compressionMethod: CompressionMethod = .none, + bufferSize: UInt32, + progress: Progress? = nil) + throws + { + try addEntry( + with: path, + relativeTo: baseURL, + compressionMethod: compressionMethod, + bufferSize: Int(bufferSize), + progress: progress) + } + + @available( + *, + deprecated, + message: "Please use `Int` for `bufferSize`.") + func addEntry( + with path: String, + fileURL: URL, + compressionMethod: CompressionMethod = .none, + bufferSize: UInt32, + progress: Progress? = nil) + throws + { + try addEntry( + with: path, + fileURL: fileURL, + compressionMethod: compressionMethod, + bufferSize: Int(bufferSize), + progress: progress) + } + + @available( + *, + deprecated, + message: "Please use `Int64` for `uncompressedSize` and provider `position`. `Int` for `bufferSize`.") + func addEntry( + with path: String, + type: Entry.EntryType, + uncompressedSize: UInt32, + modificationDate: Date = Date(), + permissions: UInt16? = nil, + compressionMethod: CompressionMethod = .none, + bufferSize: Int = defaultWriteChunkSize, + progress: Progress? = nil, + provider: (_ position: Int, _ size: Int) throws -> Data) + throws + { + let newProvider: Provider = { try provider(Int($0), $1) } + try addEntry( + with: path, + type: type, + uncompressedSize: Int64(uncompressedSize), + modificationDate: modificationDate, + permissions: permissions, + compressionMethod: compressionMethod, + bufferSize: bufferSize, + progress: progress, + provider: newProvider) + } + + @available( + *, + deprecated, + message: "Please use `Int` for `bufferSize`.") + func remove(_ entry: Entry, bufferSize: UInt32, progress: Progress? = nil) throws { + try remove(entry, bufferSize: Int(bufferSize), progress: progress) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ZIP64.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ZIP64.swift new file mode 100644 index 00000000..2b301f7d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+ZIP64.swift @@ -0,0 +1,170 @@ +// +// Archive+ZIP64.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +let zip64EOCDRecordStructSignature = 0x06064b50 +let zip64EOCDLocatorStructSignature = 0x07064b50 + +// MARK: - ExtraFieldHeaderID + +enum ExtraFieldHeaderID: UInt16 { + case zip64ExtendedInformation = 0x0001 +} + +extension Archive { + struct ZIP64EndOfCentralDirectory { + let record: ZIP64EndOfCentralDirectoryRecord + let locator: ZIP64EndOfCentralDirectoryLocator + } + + struct ZIP64EndOfCentralDirectoryRecord: DataSerializable { + let zip64EOCDRecordSignature = UInt32(zip64EOCDRecordStructSignature) + let sizeOfZIP64EndOfCentralDirectoryRecord: UInt64 + let versionMadeBy: UInt16 + let versionNeededToExtract: UInt16 + let numberOfDisk: UInt32 + let numberOfDiskStart: UInt32 + let totalNumberOfEntriesOnDisk: UInt64 + let totalNumberOfEntriesInCentralDirectory: UInt64 + let sizeOfCentralDirectory: UInt64 + let offsetToStartOfCentralDirectory: UInt64 + let zip64ExtensibleDataSector: Data + static let size = 56 + } + + struct ZIP64EndOfCentralDirectoryLocator: DataSerializable { + let zip64EOCDLocatorSignature = UInt32(zip64EOCDLocatorStructSignature) + let numberOfDiskWithZIP64EOCDRecordStart: UInt32 + let relativeOffsetOfZIP64EOCDRecord: UInt64 + let totalNumberOfDisk: UInt32 + static let size = 20 + } +} + +extension Archive.ZIP64EndOfCentralDirectoryRecord { + + // MARK: Lifecycle + + init?(data: Data, additionalDataProvider _: (Int) throws -> Data) { + guard data.count == Archive.ZIP64EndOfCentralDirectoryRecord.size else { return nil } + guard data.scanValue(start: 0) == zip64EOCDRecordSignature else { return nil } + sizeOfZIP64EndOfCentralDirectoryRecord = data.scanValue(start: 4) + versionMadeBy = data.scanValue(start: 12) + versionNeededToExtract = data.scanValue(start: 14) + // Version Needed to Extract: 4.5 - File uses ZIP64 format extensions + guard versionNeededToExtract >= Archive.Version.v45.rawValue else { return nil } + numberOfDisk = data.scanValue(start: 16) + numberOfDiskStart = data.scanValue(start: 20) + totalNumberOfEntriesOnDisk = data.scanValue(start: 24) + totalNumberOfEntriesInCentralDirectory = data.scanValue(start: 32) + sizeOfCentralDirectory = data.scanValue(start: 40) + offsetToStartOfCentralDirectory = data.scanValue(start: 48) + zip64ExtensibleDataSector = Data() + } + + init( + record: Archive.ZIP64EndOfCentralDirectoryRecord, + numberOfEntriesOnDisk: UInt64, + numberOfEntriesInCD: UInt64, + sizeOfCentralDirectory: UInt64, + offsetToStartOfCD: UInt64) + { + sizeOfZIP64EndOfCentralDirectoryRecord = record.sizeOfZIP64EndOfCentralDirectoryRecord + versionMadeBy = record.versionMadeBy + versionNeededToExtract = record.versionNeededToExtract + numberOfDisk = record.numberOfDisk + numberOfDiskStart = record.numberOfDiskStart + totalNumberOfEntriesOnDisk = numberOfEntriesOnDisk + totalNumberOfEntriesInCentralDirectory = numberOfEntriesInCD + self.sizeOfCentralDirectory = sizeOfCentralDirectory + offsetToStartOfCentralDirectory = offsetToStartOfCD + zip64ExtensibleDataSector = record.zip64ExtensibleDataSector + } + + // MARK: Internal + + var data: Data { + var zip64EOCDRecordSignature = zip64EOCDRecordSignature + var sizeOfZIP64EOCDRecord = sizeOfZIP64EndOfCentralDirectoryRecord + var versionMadeBy = versionMadeBy + var versionNeededToExtract = versionNeededToExtract + var numberOfDisk = numberOfDisk + var numberOfDiskStart = numberOfDiskStart + var totalNumberOfEntriesOnDisk = totalNumberOfEntriesOnDisk + var totalNumberOfEntriesInCD = totalNumberOfEntriesInCentralDirectory + var sizeOfCD = sizeOfCentralDirectory + var offsetToStartOfCD = offsetToStartOfCentralDirectory + var data = Data() + withUnsafePointer(to: &zip64EOCDRecordSignature) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &sizeOfZIP64EOCDRecord) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &versionMadeBy) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &versionNeededToExtract) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &numberOfDisk) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &numberOfDiskStart) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &totalNumberOfEntriesOnDisk) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &totalNumberOfEntriesInCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &sizeOfCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &offsetToStartOfCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + data.append(zip64ExtensibleDataSector) + return data + } + +} + +extension Archive.ZIP64EndOfCentralDirectoryLocator { + + // MARK: Lifecycle + + init?(data: Data, additionalDataProvider _: (Int) throws -> Data) { + guard data.count == Archive.ZIP64EndOfCentralDirectoryLocator.size else { return nil } + guard data.scanValue(start: 0) == zip64EOCDLocatorSignature else { return nil } + numberOfDiskWithZIP64EOCDRecordStart = data.scanValue(start: 4) + relativeOffsetOfZIP64EOCDRecord = data.scanValue(start: 8) + totalNumberOfDisk = data.scanValue(start: 16) + } + + init(locator: Archive.ZIP64EndOfCentralDirectoryLocator, offsetOfZIP64EOCDRecord: UInt64) { + numberOfDiskWithZIP64EOCDRecordStart = locator.numberOfDiskWithZIP64EOCDRecordStart + relativeOffsetOfZIP64EOCDRecord = offsetOfZIP64EOCDRecord + totalNumberOfDisk = locator.totalNumberOfDisk + } + + // MARK: Internal + + var data: Data { + var zip64EOCDLocatorSignature = zip64EOCDLocatorSignature + var numberOfDiskWithZIP64EOCD = numberOfDiskWithZIP64EOCDRecordStart + var offsetOfZIP64EOCDRecord = relativeOffsetOfZIP64EOCDRecord + var totalNumberOfDisk = totalNumberOfDisk + var data = Data() + withUnsafePointer(to: &zip64EOCDLocatorSignature) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &numberOfDiskWithZIP64EOCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &offsetOfZIP64EOCDRecord) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &totalNumberOfDisk) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + return data + } + +} + +extension Archive.ZIP64EndOfCentralDirectory { + var data: Data { record.data + locator.data } +} + +/// Properties that represent the maximum value of each field +var maxUInt32 = UInt32.max +var maxUInt16 = UInt16.max + +var maxCompressedSize: UInt32 { maxUInt32 } +var maxUncompressedSize: UInt32 { maxUInt32 } +var maxOffsetOfLocalFileHeader: UInt32 { maxUInt32 } +var maxOffsetOfCentralDirectory: UInt32 { maxUInt32 } +var maxSizeOfCentralDirectory: UInt32 { maxUInt32 } +var maxTotalNumberOfEntries: UInt16 { maxUInt16 } diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive.swift new file mode 100644 index 00000000..bb46a7c9 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive.swift @@ -0,0 +1,398 @@ +// +// Archive.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +/// The default chunk size when reading entry data from an archive. +let defaultReadChunkSize = Int(16 * 1024) +/// The default chunk size when writing entry data to an archive. +let defaultWriteChunkSize = defaultReadChunkSize +/// The default permissions for newly added entries. +let defaultFilePermissions = UInt16(0o644) +/// The default permissions for newly added directories. +let defaultDirectoryPermissions = UInt16(0o755) +let defaultPOSIXBufferSize = defaultReadChunkSize +let defaultDirectoryUnitCount = Int64(1) +let minEndOfCentralDirectoryOffset = Int64(22) +let endOfCentralDirectoryStructSignature = 0x06054b50 +let localFileHeaderStructSignature = 0x04034b50 +let dataDescriptorStructSignature = 0x08074b50 +let centralDirectoryStructSignature = 0x02014b50 +let memoryURLScheme = "memory" + +// MARK: - Archive + +/// A sequence of uncompressed or compressed ZIP entries. +/// +/// You use an `Archive` to create, read or update ZIP files. +/// To read an existing ZIP file, you have to pass in an existing file `URL` and `AccessMode.read`: +/// +/// var archiveURL = URL(fileURLWithPath: "/path/file.zip") +/// var archive = Archive(url: archiveURL, accessMode: .read) +/// +/// An `Archive` is a sequence of entries. You can +/// iterate over an archive using a `for`-`in` loop to get access to individual `Entry` objects: +/// +/// for entry in archive { +/// print(entry.path) +/// } +/// +/// Each `Entry` in an `Archive` is represented by its `path`. You can +/// use `path` to retrieve the corresponding `Entry` from an `Archive` via subscripting: +/// +/// let entry = archive['/path/file.txt'] +/// +/// To create a new `Archive`, pass in a non-existing file URL and `AccessMode.create`. To modify an +/// existing `Archive` use `AccessMode.update`: +/// +/// var archiveURL = URL(fileURLWithPath: "/path/file.zip") +/// var archive = Archive(url: archiveURL, accessMode: .update) +/// try archive?.addEntry("test.txt", relativeTo: baseURL, compressionMethod: .deflate) +final class Archive: Sequence { + + // MARK: Lifecycle + + /// Initializes a new ZIP `Archive`. + /// + /// You can use this initalizer to create new archive files or to read and update existing ones. + /// The `mode` parameter indicates the intended usage of the archive: `.read`, `.create` or `.update`. + /// - Parameters: + /// - url: File URL to the receivers backing file. + /// - mode: Access mode of the receiver. + /// - preferredEncoding: Encoding for entry paths. Overrides the encoding specified in the archive. + /// This encoding is only used when _decoding_ paths from the receiver. + /// Paths of entries added with `addEntry` are always UTF-8 encoded. + /// - Returns: An archive initialized with a backing file at the passed in file URL and the given access mode + /// or `nil` if the following criteria are not met: + /// - Note: + /// - The file URL _must_ point to an existing file for `AccessMode.read`. + /// - The file URL _must_ point to a non-existing file for `AccessMode.create`. + /// - The file URL _must_ point to an existing file for `AccessMode.update`. + init?(url: URL, accessMode mode: AccessMode, preferredEncoding: String.Encoding? = nil) { + self.url = url + accessMode = mode + self.preferredEncoding = preferredEncoding + guard let config = Archive.makeBackingConfiguration(for: url, mode: mode) else { + return nil + } + archiveFile = config.file + endOfCentralDirectoryRecord = config.endOfCentralDirectoryRecord + zip64EndOfCentralDirectory = config.zip64EndOfCentralDirectory + setvbuf(archiveFile, nil, _IOFBF, Int(defaultPOSIXBufferSize)) + } + + deinit { + fclose(self.archiveFile) + } + + // MARK: Internal + + typealias LocalFileHeader = Entry.LocalFileHeader + typealias DataDescriptor = Entry.DefaultDataDescriptor + typealias ZIP64DataDescriptor = Entry.ZIP64DataDescriptor + typealias CentralDirectoryStructure = Entry.CentralDirectoryStructure + + /// An error that occurs during reading, creating or updating a ZIP file. + enum ArchiveError: Error { + /// Thrown when an archive file is either damaged or inaccessible. + case unreadableArchive + /// Thrown when an archive is either opened with AccessMode.read or the destination file is unwritable. + case unwritableArchive + /// Thrown when the path of an `Entry` cannot be stored in an archive. + case invalidEntryPath + /// Thrown when an `Entry` can't be stored in the archive with the proposed compression method. + case invalidCompressionMethod + /// Thrown when the stored checksum of an `Entry` doesn't match the checksum during reading. + case invalidCRC32 + /// Thrown when an extract, add or remove operation was canceled. + case cancelledOperation + /// Thrown when an extract operation was called with zero or negative `bufferSize` parameter. + case invalidBufferSize + /// Thrown when uncompressedSize/compressedSize exceeds `Int64.max` (Imposed by file API). + case invalidEntrySize + /// Thrown when the offset of local header data exceeds `Int64.max` (Imposed by file API). + case invalidLocalHeaderDataOffset + /// Thrown when the size of local header exceeds `Int64.max` (Imposed by file API). + case invalidLocalHeaderSize + /// Thrown when the offset of central directory exceeds `Int64.max` (Imposed by file API). + case invalidCentralDirectoryOffset + /// Thrown when the size of central directory exceeds `UInt64.max` (Imposed by ZIP specification). + case invalidCentralDirectorySize + /// Thrown when number of entries in central directory exceeds `UInt64.max` (Imposed by ZIP specification). + case invalidCentralDirectoryEntryCount + /// Thrown when an archive does not contain the required End of Central Directory Record. + case missingEndOfCentralDirectoryRecord + } + + /// The access mode for an `Archive`. + enum AccessMode: UInt { + /// Indicates that a newly instantiated `Archive` should create its backing file. + case create + /// Indicates that a newly instantiated `Archive` should read from an existing backing file. + case read + /// Indicates that a newly instantiated `Archive` should update an existing backing file. + case update + } + + /// The version of an `Archive` + enum Version: UInt16 { + /// The minimum version for deflate compressed archives + case v20 = 20 + /// The minimum version for archives making use of ZIP64 extensions + case v45 = 45 + } + + struct EndOfCentralDirectoryRecord: DataSerializable { + let endOfCentralDirectorySignature = UInt32(endOfCentralDirectoryStructSignature) + let numberOfDisk: UInt16 + let numberOfDiskStart: UInt16 + let totalNumberOfEntriesOnDisk: UInt16 + let totalNumberOfEntriesInCentralDirectory: UInt16 + let sizeOfCentralDirectory: UInt32 + let offsetToStartOfCentralDirectory: UInt32 + let zipFileCommentLength: UInt16 + let zipFileCommentData: Data + static let size = 22 + } + + /// URL of an Archive's backing file. + let url: URL + /// Access mode for an archive file. + let accessMode: AccessMode + var archiveFile: FILEPointer + var endOfCentralDirectoryRecord: EndOfCentralDirectoryRecord + var zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory? + var preferredEncoding: String.Encoding? + + var totalNumberOfEntriesInCentralDirectory: UInt64 { + zip64EndOfCentralDirectory?.record.totalNumberOfEntriesInCentralDirectory + ?? UInt64(endOfCentralDirectoryRecord.totalNumberOfEntriesInCentralDirectory) + } + + var sizeOfCentralDirectory: UInt64 { + zip64EndOfCentralDirectory?.record.sizeOfCentralDirectory + ?? UInt64(endOfCentralDirectoryRecord.sizeOfCentralDirectory) + } + + var offsetToStartOfCentralDirectory: UInt64 { + zip64EndOfCentralDirectory?.record.offsetToStartOfCentralDirectory + ?? UInt64(endOfCentralDirectoryRecord.offsetToStartOfCentralDirectory) + } + + #if swift(>=5.0) + var memoryFile: MemoryFile? + + /// Initializes a new in-memory ZIP `Archive`. + /// + /// You can use this initalizer to create new in-memory archive files or to read and update existing ones. + /// + /// - Parameters: + /// - data: `Data` object used as backing for in-memory archives. + /// - mode: Access mode of the receiver. + /// - preferredEncoding: Encoding for entry paths. Overrides the encoding specified in the archive. + /// This encoding is only used when _decoding_ paths from the receiver. + /// Paths of entries added with `addEntry` are always UTF-8 encoded. + /// - Returns: An in-memory archive initialized with passed in backing data. + /// - Note: + /// - The backing `data` _must_ contain a valid ZIP archive for `AccessMode.read` and `AccessMode.update`. + /// - The backing `data` _must_ be empty (or omitted) for `AccessMode.create`. + init?(data: Data = Data(), accessMode mode: AccessMode, preferredEncoding: String.Encoding? = nil) { + guard + let url = URL(string: "\(memoryURLScheme)://"), + let config = Archive.makeBackingConfiguration(for: data, mode: mode) + else { + return nil + } + + self.url = url + accessMode = mode + self.preferredEncoding = preferredEncoding + archiveFile = config.file + memoryFile = config.memoryFile + endOfCentralDirectoryRecord = config.endOfCentralDirectoryRecord + zip64EndOfCentralDirectory = config.zip64EndOfCentralDirectory + } + #endif + + // MARK: - Helpers + + static func scanForEndOfCentralDirectoryRecord(in file: FILEPointer) + -> EndOfCentralDirectoryStructure? + { + var eocdOffset: UInt64 = 0 + var index = minEndOfCentralDirectoryOffset + fseeko(file, 0, SEEK_END) + let archiveLength = Int64(ftello(file)) + while eocdOffset == 0, index <= archiveLength { + fseeko(file, off_t(archiveLength - index), SEEK_SET) + var potentialDirectoryEndTag = UInt32() + fread(&potentialDirectoryEndTag, 1, MemoryLayout.size, file) + if potentialDirectoryEndTag == UInt32(endOfCentralDirectoryStructSignature) { + eocdOffset = UInt64(archiveLength - index) + guard let eocd: EndOfCentralDirectoryRecord = Data.readStruct(from: file, at: eocdOffset) else { + return nil + } + let zip64EOCD = scanForZIP64EndOfCentralDirectory(in: file, eocdOffset: eocdOffset) + return (eocd, zip64EOCD) + } + index += 1 + } + return nil + } + + func makeIterator() -> AnyIterator { + let totalNumberOfEntriesInCD = totalNumberOfEntriesInCentralDirectory + var directoryIndex = offsetToStartOfCentralDirectory + var index = 0 + return AnyIterator { + guard index < totalNumberOfEntriesInCD else { return nil } + guard + let centralDirStruct: CentralDirectoryStructure = Data.readStruct( + from: self.archiveFile, + at: directoryIndex) + else { + return nil + } + let offset = UInt64(centralDirStruct.effectiveRelativeOffsetOfLocalHeader) + guard + let localFileHeader: LocalFileHeader = Data.readStruct( + from: self.archiveFile, + at: offset) + else { return nil } + var dataDescriptor: DataDescriptor? + var zip64DataDescriptor: ZIP64DataDescriptor? + if centralDirStruct.usesDataDescriptor { + let additionalSize = UInt64(localFileHeader.fileNameLength) + UInt64(localFileHeader.extraFieldLength) + let isCompressed = centralDirStruct.compressionMethod != CompressionMethod.none.rawValue + let dataSize = isCompressed + ? centralDirStruct.effectiveCompressedSize + : centralDirStruct.effectiveUncompressedSize + let descriptorPosition = offset + UInt64(LocalFileHeader.size) + additionalSize + dataSize + if centralDirStruct.isZIP64 { + zip64DataDescriptor = Data.readStruct(from: self.archiveFile, at: descriptorPosition) + } else { + dataDescriptor = Data.readStruct(from: self.archiveFile, at: descriptorPosition) + } + } + defer { + directoryIndex += UInt64(CentralDirectoryStructure.size) + directoryIndex += UInt64(centralDirStruct.fileNameLength) + directoryIndex += UInt64(centralDirStruct.extraFieldLength) + directoryIndex += UInt64(centralDirStruct.fileCommentLength) + index += 1 + } + return Entry( + centralDirectoryStructure: centralDirStruct, + localFileHeader: localFileHeader, + dataDescriptor: dataDescriptor, + zip64DataDescriptor: zip64DataDescriptor) + } + } + + /// Retrieve the ZIP `Entry` with the given `path` from the receiver. + /// + /// - Note: The ZIP file format specification does not enforce unique paths for entries. + /// Therefore an archive can contain multiple entries with the same path. This method + /// always returns the first `Entry` with the given `path`. + /// + /// - Parameter path: A relative file path identifying the corresponding `Entry`. + /// - Returns: An `Entry` with the given `path`. Otherwise, `nil`. + subscript(path: String) -> Entry? { + if let encoding = preferredEncoding { + return first { $0.path(using: encoding) == path } + } + return first { $0.path == path } + } + + // MARK: Private + + private static func scanForZIP64EndOfCentralDirectory(in file: FILEPointer, eocdOffset: UInt64) + -> ZIP64EndOfCentralDirectory? + { + guard UInt64(ZIP64EndOfCentralDirectoryLocator.size) < eocdOffset else { + return nil + } + let locatorOffset = eocdOffset - UInt64(ZIP64EndOfCentralDirectoryLocator.size) + + guard UInt64(ZIP64EndOfCentralDirectoryRecord.size) < locatorOffset else { + return nil + } + let recordOffset = locatorOffset - UInt64(ZIP64EndOfCentralDirectoryRecord.size) + guard + let locator: ZIP64EndOfCentralDirectoryLocator = Data.readStruct(from: file, at: locatorOffset), + let record: ZIP64EndOfCentralDirectoryRecord = Data.readStruct(from: file, at: recordOffset) + else { + return nil + } + return ZIP64EndOfCentralDirectory(record: record, locator: locator) + } +} + +extension Archive.EndOfCentralDirectoryRecord { + + // MARK: Lifecycle + + init?(data: Data, additionalDataProvider provider: (Int) throws -> Data) { + guard data.count == Archive.EndOfCentralDirectoryRecord.size else { return nil } + guard data.scanValue(start: 0) == endOfCentralDirectorySignature else { return nil } + numberOfDisk = data.scanValue(start: 4) + numberOfDiskStart = data.scanValue(start: 6) + totalNumberOfEntriesOnDisk = data.scanValue(start: 8) + totalNumberOfEntriesInCentralDirectory = data.scanValue(start: 10) + sizeOfCentralDirectory = data.scanValue(start: 12) + offsetToStartOfCentralDirectory = data.scanValue(start: 16) + zipFileCommentLength = data.scanValue(start: 20) + guard let commentData = try? provider(Int(zipFileCommentLength)) else { return nil } + guard commentData.count == Int(zipFileCommentLength) else { return nil } + zipFileCommentData = commentData + } + + init( + record: Archive.EndOfCentralDirectoryRecord, + numberOfEntriesOnDisk: UInt16, + numberOfEntriesInCentralDirectory: UInt16, + updatedSizeOfCentralDirectory: UInt32, + startOfCentralDirectory: UInt32) + { + numberOfDisk = record.numberOfDisk + numberOfDiskStart = record.numberOfDiskStart + totalNumberOfEntriesOnDisk = numberOfEntriesOnDisk + totalNumberOfEntriesInCentralDirectory = numberOfEntriesInCentralDirectory + sizeOfCentralDirectory = updatedSizeOfCentralDirectory + offsetToStartOfCentralDirectory = startOfCentralDirectory + zipFileCommentLength = record.zipFileCommentLength + zipFileCommentData = record.zipFileCommentData + } + + // MARK: Internal + + var data: Data { + var endOfCDSignature = endOfCentralDirectorySignature + var numberOfDisk = numberOfDisk + var numberOfDiskStart = numberOfDiskStart + var totalNumberOfEntriesOnDisk = totalNumberOfEntriesOnDisk + var totalNumberOfEntriesInCD = totalNumberOfEntriesInCentralDirectory + var sizeOfCentralDirectory = sizeOfCentralDirectory + var offsetToStartOfCD = offsetToStartOfCentralDirectory + var zipFileCommentLength = zipFileCommentLength + var data = Data() + withUnsafePointer(to: &endOfCDSignature) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &numberOfDisk) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &numberOfDiskStart) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &totalNumberOfEntriesOnDisk) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &totalNumberOfEntriesInCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &sizeOfCentralDirectory) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &offsetToStartOfCD) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &zipFileCommentLength) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + data.append(zipFileCommentData) + return data + } + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift new file mode 100644 index 00000000..06566169 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift @@ -0,0 +1,403 @@ +// +// Data+Compression.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +#if canImport(zlib) +import zlib +#endif + +// MARK: - CompressionMethod + +/// The compression method of an `Entry` in a ZIP `Archive`. +enum CompressionMethod: UInt16 { + /// Indicates that an `Entry` has no compression applied to its contents. + case none = 0 + /// Indicates that contents of an `Entry` have been compressed with a zlib compatible Deflate algorithm. + case deflate = 8 +} + +/// An unsigned 32-Bit Integer representing a checksum. +typealias CRC32 = UInt32 +/// A custom handler that consumes a `Data` object containing partial entry data. +/// - Parameters: +/// - data: A chunk of `Data` to consume. +/// - Throws: Can throw to indicate errors during data consumption. +typealias Consumer = (_ data: Data) throws -> Void +/// A custom handler that receives a position and a size that can be used to provide data from an arbitrary source. +/// - Parameters: +/// - position: The current read position. +/// - size: The size of the chunk to provide. +/// - Returns: A chunk of `Data`. +/// - Throws: Can throw to indicate errors in the data source. +typealias Provider = (_ position: Int64, _ size: Int) throws -> Data + +extension Data { + enum CompressionError: Error { + case invalidStream + case corruptedData + } + + /// Compress the output of `provider` and pass it to `consumer`. + /// - Parameters: + /// - size: The uncompressed size of the data to be compressed. + /// - bufferSize: The maximum size of the compression buffer. + /// - provider: A closure that accepts a position and a chunk size. Returns a `Data` chunk. + /// - consumer: A closure that processes the result of the compress operation. + /// - Returns: The checksum of the processed content. + static func compress(size: Int64, bufferSize: Int, provider: Provider, consumer: Consumer) throws -> CRC32 { + #if os(macOS) || canImport(UIKit) + return try process( + operation: COMPRESSION_STREAM_ENCODE, + size: size, + bufferSize: bufferSize, + provider: provider, + consumer: consumer) + #else + return try encode(size: size, bufferSize: bufferSize, provider: provider, consumer: consumer) + #endif + } + + /// Decompress the output of `provider` and pass it to `consumer`. + /// - Parameters: + /// - size: The compressed size of the data to be decompressed. + /// - bufferSize: The maximum size of the decompression buffer. + /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - provider: A closure that accepts a position and a chunk size. Returns a `Data` chunk. + /// - consumer: A closure that processes the result of the decompress operation. + /// - Returns: The checksum of the processed content. + static func decompress( + size: Int64, + bufferSize: Int, + skipCRC32: Bool, + provider: Provider, + consumer: Consumer) + throws -> CRC32 + { + #if os(macOS) || canImport(UIKit) + return try process( + operation: COMPRESSION_STREAM_DECODE, + size: size, + bufferSize: bufferSize, + skipCRC32: skipCRC32, + provider: provider, + consumer: consumer) + #else + return try decode(bufferSize: bufferSize, skipCRC32: skipCRC32, provider: provider, consumer: consumer) + #endif + } + + /// Calculate the `CRC32` checksum of the receiver. + /// + /// - Parameter checksum: The starting seed. + /// - Returns: The checksum calculated from the bytes of the receiver and the starting seed. + func crc32(checksum: CRC32) -> CRC32 { + #if canImport(zlib) + return withUnsafeBytes { bufferPointer in + let length = UInt32(count) + return CRC32(zlib.crc32(UInt(checksum), bufferPointer.bindMemory(to: UInt8.self).baseAddress, length)) + } + #else + return builtInCRC32(checksum: checksum) + #endif + } + +} + +// MARK: - Apple Platforms + +#if os(macOS) || canImport(UIKit) +import Compression + +extension Data { + + static func process( + operation: compression_stream_operation, + size: Int64, + bufferSize: Int, + skipCRC32: Bool = false, + provider: Provider, + consumer: Consumer) + throws -> CRC32 + { + var crc32 = CRC32(0) + let destPointer = UnsafeMutablePointer.allocate(capacity: bufferSize) + defer { destPointer.deallocate() } + let streamPointer = UnsafeMutablePointer.allocate(capacity: 1) + defer { streamPointer.deallocate() } + var stream = streamPointer.pointee + var status = compression_stream_init(&stream, operation, COMPRESSION_ZLIB) + guard status != COMPRESSION_STATUS_ERROR else { throw CompressionError.invalidStream } + defer { compression_stream_destroy(&stream) } + stream.src_size = 0 + stream.dst_ptr = destPointer + stream.dst_size = bufferSize + var position: Int64 = 0 + var sourceData: Data? + repeat { + let isExhausted = stream.src_size == 0 + if isExhausted { + do { + sourceData = try provider(position, Int(Swift.min(size - position, Int64(bufferSize)))) + position += Int64(stream.prepare(for: sourceData)) + } catch { throw error } + } + if let sourceData { + sourceData.withUnsafeBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + stream.src_ptr = pointer.advanced(by: sourceData.count - stream.src_size) + let flags = sourceData.count < bufferSize ? Int32(COMPRESSION_STREAM_FINALIZE.rawValue) : 0 + status = compression_stream_process(&stream, flags) + } + } + if + operation == COMPRESSION_STREAM_ENCODE, + isExhausted, skipCRC32 == false { crc32 = sourceData.crc32(checksum: crc32) } + } + switch status { + case COMPRESSION_STATUS_OK, COMPRESSION_STATUS_END: + let outputData = Data(bytesNoCopy: destPointer, count: bufferSize - stream.dst_size, deallocator: .none) + try consumer(outputData) + if operation == COMPRESSION_STREAM_DECODE, !skipCRC32 { crc32 = outputData.crc32(checksum: crc32) } + stream.dst_ptr = destPointer + stream.dst_size = bufferSize + default: throw CompressionError.corruptedData + } + } while status == COMPRESSION_STATUS_OK + return crc32 + } +} + +extension compression_stream { + + fileprivate mutating func prepare(for sourceData: Data?) -> Int { + guard let sourceData else { return 0 } + + src_size = sourceData.count + return sourceData.count + } +} + +// MARK: - Linux + +#else +import CZlib + +extension Data { + static func encode(size: Int64, bufferSize: Int, provider: Provider, consumer: Consumer) throws -> CRC32 { + var stream = z_stream() + let streamSize = Int32(MemoryLayout.size) + var result = deflateInit2_( + &stream, + Z_DEFAULT_COMPRESSION, + Z_DEFLATED, + -MAX_WBITS, + 9, + Z_DEFAULT_STRATEGY, + ZLIB_VERSION, + streamSize) + defer { deflateEnd(&stream) } + guard result == Z_OK else { throw CompressionError.invalidStream } + var flush = Z_NO_FLUSH + var position: Int64 = 0 + var zipCRC32 = CRC32(0) + repeat { + let readSize = Int(Swift.min(size - position, Int64(bufferSize))) + var inputChunk = try provider(position, readSize) + zipCRC32 = inputChunk.crc32(checksum: zipCRC32) + stream.avail_in = UInt32(inputChunk.count) + try inputChunk.withUnsafeMutableBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + stream.next_in = pointer + flush = position + Int64(bufferSize) >= size ? Z_FINISH : Z_NO_FLUSH + } else if rawBufferPointer.count > 0 { + throw CompressionError.corruptedData + } else { + stream.next_in = nil + flush = Z_FINISH + } + var outputChunk = Data(count: bufferSize) + repeat { + stream.avail_out = UInt32(bufferSize) + try outputChunk.withUnsafeMutableBytes { rawBufferPointer in + guard let baseAddress = rawBufferPointer.baseAddress, rawBufferPointer.count > 0 else { + throw CompressionError.corruptedData + } + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + stream.next_out = pointer + result = deflate(&stream, flush) + } + guard result >= Z_OK else { throw CompressionError.corruptedData } + + outputChunk.count = bufferSize - Int(stream.avail_out) + try consumer(outputChunk) + } while stream.avail_out == 0 + } + position += Int64(readSize) + } while flush != Z_FINISH + return zipCRC32 + } + + static func decode(bufferSize: Int, skipCRC32: Bool, provider: Provider, consumer: Consumer) throws -> CRC32 { + var stream = z_stream() + let streamSize = Int32(MemoryLayout.size) + var result = inflateInit2_(&stream, -MAX_WBITS, ZLIB_VERSION, streamSize) + defer { inflateEnd(&stream) } + guard result == Z_OK else { throw CompressionError.invalidStream } + var unzipCRC32 = CRC32(0) + var position: Int64 = 0 + repeat { + stream.avail_in = UInt32(bufferSize) + var chunk = try provider(position, bufferSize) + position += Int64(chunk.count) + try chunk.withUnsafeMutableBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress, rawBufferPointer.count > 0 { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + stream.next_in = pointer + repeat { + var outputData = Data(count: bufferSize) + stream.avail_out = UInt32(bufferSize) + try outputData.withUnsafeMutableBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress, rawBufferPointer.count > 0 { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + stream.next_out = pointer + } else { + throw CompressionError.corruptedData + } + result = inflate(&stream, Z_NO_FLUSH) + guard + result != Z_NEED_DICT, + result != Z_DATA_ERROR, + result != Z_MEM_ERROR + else { + throw CompressionError.corruptedData + } + } + let remainingLength = UInt32(bufferSize) - stream.avail_out + outputData.count = Int(remainingLength) + try consumer(outputData) + if !skipCRC32 { unzipCRC32 = outputData.crc32(checksum: unzipCRC32) } + } while stream.avail_out == 0 + } + } + } while result != Z_STREAM_END + return unzipCRC32 + } +} + +#endif + +/// The lookup table used to calculate `CRC32` checksums when using the built-in +/// CRC32 implementation. +private let crcTable: [CRC32] = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, + 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, + 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, + 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, + 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, + 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, + 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, + 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, + 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, + 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +] + +extension Data { + + /// Lookup table-based CRC32 implenetation that is used + /// if `zlib` isn't available. + /// - Parameter checksum: Running checksum or `0` for the initial run. + /// - Returns: The calculated checksum of the receiver. + func builtInCRC32(checksum: CRC32) -> CRC32 { + // The typecast is necessary on 32-bit platforms because of + // https://bugs.swift.org/browse/SR-1774 + let mask = 0xffffffff as CRC32 + var result = checksum ^ mask + #if swift(>=5.0) + crcTable.withUnsafeBufferPointer { crcTablePointer in + self.withUnsafeBytes { bufferPointer in + var bufferIndex = 0 + while bufferIndex < self.count { + let byte = bufferPointer[bufferIndex] + let index = Int((result ^ CRC32(byte)) & 0xff) + result = (result >> 8) ^ crcTablePointer[index] + bufferIndex += 1 + } + } + } + #else + withUnsafeBytes { bytes in + let bins = stride(from: 0, to: self.count, by: 256) + for bin in bins { + for binIndex in 0..<256 { + let byteIndex = bin + binIndex + guard byteIndex < self.count else { break } + + let byte = bytes[byteIndex] + let index = Int((result ^ CRC32(byte)) & 0xff) + result = (result >> 8) ^ crcTable[index] + } + } + } + #endif + return result ^ mask + } +} + +#if !swift(>=5.0) + +// Since Swift 5.0, `Data.withUnsafeBytes()` passes an `UnsafeRawBufferPointer` instead of an `UnsafePointer` +// into `body`. +// We provide a compatible method for targets that use Swift 4.x so that we can use the new version +// across all language versions. + +extension Data { + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + let count = count + return try withUnsafeBytes { (pointer: UnsafePointer) throws -> T in + try body(UnsafeRawBufferPointer(start: pointer, count: count)) + } + } + + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + #else + mutating func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + let count = count + guard count > 0 else { + return try body(UnsafeMutableRawBufferPointer(start: nil, count: count)) + } + return try withUnsafeMutableBytes { (pointer: UnsafeMutablePointer) throws -> T in + try body(UnsafeMutableRawBufferPointer(start: pointer, count: count)) + } + } + #endif +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+CompressionDeprecated.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+CompressionDeprecated.swift new file mode 100644 index 00000000..43844b32 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+CompressionDeprecated.swift @@ -0,0 +1,44 @@ +// +// Data+CompressionDeprecated.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Data { + + @available(*, deprecated, message: "Please use `Int64` for `size` and provider `position`.") + static func compress( + size: Int, + bufferSize: Int, + provider: (_ position: Int, _ size: Int) throws -> Data, + consumer: Consumer) + throws -> CRC32 + { + let newProvider: Provider = { try provider(Int($0), $1) } + return try compress(size: Int64(size), bufferSize: bufferSize, provider: newProvider, consumer: consumer) + } + + @available(*, deprecated, message: "Please use `Int64` for `size` and provider `position`.") + static func decompress( + size: Int, + bufferSize: Int, + skipCRC32: Bool, + provider: (_ position: Int, _ size: Int) throws -> Data, + consumer: Consumer) + throws -> CRC32 + { + let newProvider: Provider = { try provider(Int($0), $1) } + return try decompress( + size: Int64(size), + bufferSize: bufferSize, + skipCRC32: skipCRC32, + provider: newProvider, + consumer: consumer) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Serialization.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Serialization.swift new file mode 100644 index 00000000..94479228 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Serialization.swift @@ -0,0 +1,149 @@ +// +// Data+Serialization.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +#if os(Android) +typealias FILEPointer = OpaquePointer +#else +typealias FILEPointer = UnsafeMutablePointer +#endif + +// MARK: - DataSerializable + +protocol DataSerializable { + static var size: Int { get } + init?(data: Data, additionalDataProvider: (Int) throws -> Data) + var data: Data { get } +} + +extension Data { + enum DataError: Error { + case unreadableFile + case unwritableFile + } + + static func readStruct(from file: FILEPointer, at offset: UInt64) + -> T? where T: DataSerializable + { + guard offset <= .max else { return nil } + fseeko(file, off_t(offset), SEEK_SET) + guard let data = try? readChunk(of: T.size, from: file) else { + return nil + } + let structure = T(data: data, additionalDataProvider: { additionalDataSize -> Data in + try self.readChunk(of: additionalDataSize, from: file) + }) + return structure + } + + static func consumePart( + of size: Int64, + chunkSize: Int, + skipCRC32: Bool = false, + provider: Provider, + consumer: Consumer) + throws -> CRC32 + { + var checksum = CRC32(0) + guard size > 0 else { + try consumer(Data()) + return checksum + } + + let readInOneChunk = (size < chunkSize) + var chunkSize = readInOneChunk ? Int(size) : chunkSize + var bytesRead: Int64 = 0 + while bytesRead < size { + let remainingSize = size - bytesRead + chunkSize = remainingSize < chunkSize ? Int(remainingSize) : chunkSize + let data = try provider(bytesRead, chunkSize) + try consumer(data) + if !skipCRC32 { + checksum = data.crc32(checksum: checksum) + } + bytesRead += Int64(chunkSize) + } + return checksum + } + + static func readChunk(of size: Int, from file: FILEPointer) throws -> Data { + let alignment = MemoryLayout.alignment + #if swift(>=4.1) + let bytes = UnsafeMutableRawPointer.allocate(byteCount: size, alignment: alignment) + #else + let bytes = UnsafeMutableRawPointer.allocate(bytes: size, alignedTo: alignment) + #endif + let bytesRead = fread(bytes, 1, size, file) + let error = ferror(file) + if error > 0 { + throw DataError.unreadableFile + } + #if swift(>=4.1) + return Data(bytesNoCopy: bytes, count: bytesRead, deallocator: .custom { buf, _ in buf.deallocate() }) + #else + let deallocator = Deallocator.custom { buf, _ in buf.deallocate(bytes: size, alignedTo: 1) } + return Data(bytesNoCopy: bytes, count: bytesRead, deallocator: deallocator) + #endif + } + + static func write(chunk: Data, to file: FILEPointer) throws -> Int { + var sizeWritten = 0 + chunk.withUnsafeBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress, rawBufferPointer.count > 0 { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + sizeWritten = fwrite(pointer, 1, chunk.count, file) + } + } + let error = ferror(file) + if error > 0 { + throw DataError.unwritableFile + } + return sizeWritten + } + + static func writeLargeChunk( + _ chunk: Data, + size: UInt64, + bufferSize: Int, + to file: FILEPointer) + throws -> UInt64 + { + var sizeWritten: UInt64 = 0 + chunk.withUnsafeBytes { rawBufferPointer in + if let baseAddress = rawBufferPointer.baseAddress, rawBufferPointer.count > 0 { + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + + while sizeWritten < size { + let remainingSize = size - sizeWritten + let chunkSize = Swift.min(Int(remainingSize), bufferSize) + let curPointer = pointer.advanced(by: Int(sizeWritten)) + fwrite(curPointer, 1, chunkSize, file) + sizeWritten += UInt64(chunkSize) + } + } + } + let error = ferror(file) + if error > 0 { + throw DataError.unwritableFile + } + return sizeWritten + } + + func scanValue(start: Int) -> T { + let subdata = subdata(in: start...size) + #if swift(>=5.0) + return subdata.withUnsafeBytes { $0.load(as: T.self) } + #else + return subdata.withUnsafeBytes { $0.pointee } + #endif + } + +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+Serialization.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+Serialization.swift new file mode 100644 index 00000000..8c22c132 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+Serialization.swift @@ -0,0 +1,189 @@ +// +// Entry+Serialization.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension Entry.LocalFileHeader { + + // MARK: Lifecycle + + init?(data: Data, additionalDataProvider provider: (Int) throws -> Data) { + guard data.count == Entry.LocalFileHeader.size else { return nil } + guard data.scanValue(start: 0) == localFileHeaderSignature else { return nil } + versionNeededToExtract = data.scanValue(start: 4) + generalPurposeBitFlag = data.scanValue(start: 6) + compressionMethod = data.scanValue(start: 8) + lastModFileTime = data.scanValue(start: 10) + lastModFileDate = data.scanValue(start: 12) + crc32 = data.scanValue(start: 14) + compressedSize = data.scanValue(start: 18) + uncompressedSize = data.scanValue(start: 22) + fileNameLength = data.scanValue(start: 26) + extraFieldLength = data.scanValue(start: 28) + let additionalDataLength = Int(fileNameLength) + Int(extraFieldLength) + guard let additionalData = try? provider(additionalDataLength) else { return nil } + guard additionalData.count == additionalDataLength else { return nil } + var subRangeStart = 0 + var subRangeEnd = Int(fileNameLength) + fileNameData = additionalData.subdata(in: subRangeStart.. Data) { + guard data.count == Entry.CentralDirectoryStructure.size else { return nil } + guard data.scanValue(start: 0) == centralDirectorySignature else { return nil } + versionMadeBy = data.scanValue(start: 4) + versionNeededToExtract = data.scanValue(start: 6) + generalPurposeBitFlag = data.scanValue(start: 8) + compressionMethod = data.scanValue(start: 10) + lastModFileTime = data.scanValue(start: 12) + lastModFileDate = data.scanValue(start: 14) + crc32 = data.scanValue(start: 16) + compressedSize = data.scanValue(start: 20) + uncompressedSize = data.scanValue(start: 24) + fileNameLength = data.scanValue(start: 28) + extraFieldLength = data.scanValue(start: 30) + fileCommentLength = data.scanValue(start: 32) + diskNumberStart = data.scanValue(start: 34) + internalFileAttributes = data.scanValue(start: 36) + externalFileAttributes = data.scanValue(start: 38) + relativeOffsetOfLocalHeader = data.scanValue(start: 42) + let additionalDataLength = Int(fileNameLength) + Int(extraFieldLength) + Int(fileCommentLength) + guard let additionalData = try? provider(additionalDataLength) else { return nil } + guard additionalData.count == additionalDataLength else { return nil } + var subRangeStart = 0 + var subRangeEnd = Int(fileNameLength) + fileNameData = additionalData.subdata(in: subRangeStart.. Data) { + guard data.count == Self.size else { return nil } + let signature: UInt32 = data.scanValue(start: 0) + // The DataDescriptor signature is not mandatory so we have to re-arrange the input data if it is missing. + var readOffset = 0 + if signature == dataDescriptorSignature { readOffset = 4 } + crc32 = data.scanValue(start: readOffset) + readOffset += MemoryLayout.size + compressedSize = data.scanValue(start: readOffset) + readOffset += Self.memoryLengthOfSize + uncompressedSize = data.scanValue(start: readOffset) + // Our add(_ entry:) methods always maintain compressed & uncompressed + // sizes and so we don't need a data descriptor for newly added entries. + // Data descriptors of already existing entries are manually preserved + // when copying those entries to the tempArchive during remove(_ entry:). + self.data = Data() + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+ZIP64.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+ZIP64.swift new file mode 100644 index 00000000..f763a218 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+ZIP64.swift @@ -0,0 +1,173 @@ +// +// Entry+ZIP64.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +// MARK: - ExtensibleDataField + +protocol ExtensibleDataField { + var headerID: UInt16 { get } + var dataSize: UInt16 { get } +} + +extension Entry { + enum EntryError: Error { + case invalidDataError + } + + struct ZIP64ExtendedInformation: ExtensibleDataField { + let headerID: UInt16 = ExtraFieldHeaderID.zip64ExtendedInformation.rawValue + let dataSize: UInt16 + static let headerSize: UInt16 = 4 + let uncompressedSize: UInt64 + let compressedSize: UInt64 + let relativeOffsetOfLocalHeader: UInt64 + let diskNumberStart: UInt32 + } + + var zip64ExtendedInformation: ZIP64ExtendedInformation? { + centralDirectoryStructure.zip64ExtendedInformation + } +} + +typealias Field = Entry.ZIP64ExtendedInformation.Field + +extension Entry.LocalFileHeader { + var validFields: [Field] { + var fields: [Field] = [] + if uncompressedSize == .max { fields.append(.uncompressedSize) } + if compressedSize == .max { fields.append(.compressedSize) } + return fields + } +} + +extension Entry.CentralDirectoryStructure { + var validFields: [Field] { + var fields: [Field] = [] + if uncompressedSize == .max { fields.append(.uncompressedSize) } + if compressedSize == .max { fields.append(.compressedSize) } + if relativeOffsetOfLocalHeader == .max { fields.append(.relativeOffsetOfLocalHeader) } + if diskNumberStart == .max { fields.append(.diskNumberStart) } + return fields + } + + var zip64ExtendedInformation: Entry.ZIP64ExtendedInformation? { + extraFields?.compactMap { $0 as? Entry.ZIP64ExtendedInformation }.first + } +} + +extension Entry.ZIP64ExtendedInformation { + + // MARK: Lifecycle + + init?(data: Data, fields: [Field]) { + let headerLength = 4 + guard fields.reduce(0, { $0 + $1.size }) + headerLength == data.count else { return nil } + var readOffset = headerLength + func value(of field: Field) throws -> T where T: BinaryInteger { + if fields.contains(field) { + defer { + readOffset += MemoryLayout.size + } + guard readOffset + field.size <= data.count else { + throw Entry.EntryError.invalidDataError + } + return data.scanValue(start: readOffset) + } else { + return 0 + } + } + do { + dataSize = data.scanValue(start: 2) + uncompressedSize = try value(of: .uncompressedSize) + compressedSize = try value(of: .compressedSize) + relativeOffsetOfLocalHeader = try value(of: .relativeOffsetOfLocalHeader) + diskNumberStart = try value(of: .diskNumberStart) + } catch { + return nil + } + } + + init?(zip64ExtendedInformation: Entry.ZIP64ExtendedInformation?, offset: UInt64) { + // Only used when removing entry, if no ZIP64 extended information exists, + // then this information will not be newly added either + guard let existingInfo = zip64ExtendedInformation else { return nil } + relativeOffsetOfLocalHeader = offset >= maxOffsetOfLocalFileHeader ? offset : 0 + uncompressedSize = existingInfo.uncompressedSize + compressedSize = existingInfo.compressedSize + diskNumberStart = existingInfo.diskNumberStart + let tempDataSize = [relativeOffsetOfLocalHeader, uncompressedSize, compressedSize] + .filter { $0 != 0 } + .reduce(UInt16(0)) { $0 + UInt16(MemoryLayout.size(ofValue: $1)) } + dataSize = tempDataSize + (diskNumberStart > 0 ? UInt16(MemoryLayout.size(ofValue: diskNumberStart)) : 0) + if dataSize == 0 { return nil } + } + + // MARK: Internal + + enum Field { + case uncompressedSize + case compressedSize + case relativeOffsetOfLocalHeader + case diskNumberStart + + var size: Int { + switch self { + case .uncompressedSize, .compressedSize, .relativeOffsetOfLocalHeader: + return 8 + case .diskNumberStart: + return 4 + } + } + } + + var data: Data { + var headerID = headerID + var dataSize = dataSize + var uncompressedSize = uncompressedSize + var compressedSize = compressedSize + var relativeOffsetOfLFH = relativeOffsetOfLocalHeader + var diskNumberStart = diskNumberStart + var data = Data() + withUnsafePointer(to: &headerID) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &dataSize) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + if uncompressedSize != 0 || compressedSize != 0 { + withUnsafePointer(to: &uncompressedSize) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + withUnsafePointer(to: &compressedSize) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + } + if relativeOffsetOfLocalHeader != 0 { + withUnsafePointer(to: &relativeOffsetOfLFH) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + } + if diskNumberStart != 0 { + withUnsafePointer(to: &diskNumberStart) { data.append(UnsafeBufferPointer(start: $0, count: 1)) } + } + return data + } + + static func scanForZIP64Field(in data: Data, fields: [Field]) -> Entry.ZIP64ExtendedInformation? { + guard data.isEmpty == false else { return nil } + var offset = 0 + var headerID: UInt16 + var dataSize: UInt16 + let extraFieldLength = data.count + let headerSize = Int(Entry.ZIP64ExtendedInformation.headerSize) + while offset < extraFieldLength - headerSize { + headerID = data.scanValue(start: offset) + dataSize = data.scanValue(start: offset + 2) + let nextOffset = offset + headerSize + Int(dataSize) + guard nextOffset <= extraFieldLength else { return nil } + if headerID == ExtraFieldHeaderID.zip64ExtendedInformation.rawValue { + return Entry.ZIP64ExtendedInformation(data: data.subdata(in: offset..: DataSerializable { + let data: Data + let dataDescriptorSignature = UInt32(dataDescriptorStructSignature) + let crc32: UInt32 + // For normal archives, the compressed and uncompressed sizes are 4 bytes each. + // For ZIP64 format archives, the compressed and uncompressed sizes are 8 bytes each. + let compressedSize: T + let uncompressedSize: T + static var memoryLengthOfSize: Int { MemoryLayout.size } + static var size: Int { memoryLengthOfSize * 2 + 8 } + } + + typealias DefaultDataDescriptor = DataDescriptor + typealias ZIP64DataDescriptor = DataDescriptor + + struct CentralDirectoryStructure: DataSerializable { + static let size = 46 + + let centralDirectorySignature = UInt32(centralDirectoryStructSignature) + let versionMadeBy: UInt16 + let versionNeededToExtract: UInt16 + let generalPurposeBitFlag: UInt16 + let compressionMethod: UInt16 + let lastModFileTime: UInt16 + let lastModFileDate: UInt16 + let crc32: UInt32 + let compressedSize: UInt32 + let uncompressedSize: UInt32 + let fileNameLength: UInt16 + let extraFieldLength: UInt16 + let fileCommentLength: UInt16 + let diskNumberStart: UInt16 + let internalFileAttributes: UInt16 + let externalFileAttributes: UInt32 + let relativeOffsetOfLocalHeader: UInt32 + let fileNameData: Data + let extraFieldData: Data + let fileCommentData: Data + + var extraFields: [ExtensibleDataField]? + + var usesDataDescriptor: Bool { (generalPurposeBitFlag & (1 << 3)) != 0 } + var usesUTF8PathEncoding: Bool { (generalPurposeBitFlag & (1 << 11)) != 0 } + var isEncrypted: Bool { (generalPurposeBitFlag & (1 << 0)) != 0 } + var isZIP64: Bool { + // If ZIP64 extended information is existing, try to treat cd as ZIP64 format + // even if the version needed to extract is lower than 4.5 + UInt8(truncatingIfNeeded: versionNeededToExtract) >= 45 || zip64ExtendedInformation != nil + } + } + + let centralDirectoryStructure: CentralDirectoryStructure + let localFileHeader: LocalFileHeader + let dataDescriptor: DefaultDataDescriptor? + let zip64DataDescriptor: ZIP64DataDescriptor? + + /// The `path` of the receiver within a ZIP `Archive`. + var path: String { + let dosLatinUS = 0x400 + let dosLatinUSEncoding = CFStringEncoding(dosLatinUS) + let dosLatinUSStringEncoding = CFStringConvertEncodingToNSStringEncoding(dosLatinUSEncoding) + let codepage437 = String.Encoding(rawValue: dosLatinUSStringEncoding) + let encoding = centralDirectoryStructure.usesUTF8PathEncoding ? .utf8 : codepage437 + return self.path(using: encoding) + } + + /// The file attributes of the receiver as key/value pairs. + /// + /// Contains the modification date and file permissions. + var fileAttributes: [FileAttributeKey: Any] { + FileManager.attributes(from: self) + } + + /// The `CRC32` checksum of the receiver. + /// + /// - Note: Always returns `0` for entries of type `EntryType.directory`. + var checksum: CRC32 { + if centralDirectoryStructure.usesDataDescriptor { + return zip64DataDescriptor?.crc32 ?? dataDescriptor?.crc32 ?? 0 + } + return centralDirectoryStructure.crc32 + } + + /// The `EntryType` of the receiver. + var type: EntryType { + // OS Type is stored in the upper byte of versionMadeBy + let osTypeRaw = centralDirectoryStructure.versionMadeBy >> 8 + let osType = OSType(rawValue: UInt(osTypeRaw)) ?? .unused + var isDirectory = path.hasSuffix("/") + switch osType { + case .unix, .osx: + let mode = mode_t(centralDirectoryStructure.externalFileAttributes >> 16) & S_IFMT + switch mode { + case S_IFREG: + return .file + case S_IFDIR: + return .directory + case S_IFLNK: + return .symlink + default: + return isDirectory ? .directory : .file + } + case .msdos: + isDirectory = isDirectory || ((centralDirectoryStructure.externalFileAttributes >> 4) == 0x01) + fallthrough // For all other OSes we can only guess based on the directory suffix char + default: return isDirectory ? .directory : .file + } + } + + /// Indicates whether or not the receiver is compressed. + var isCompressed: Bool { + localFileHeader.compressionMethod != CompressionMethod.none.rawValue + } + + /// The size of the receiver's compressed data. + var compressedSize: UInt64 { + if centralDirectoryStructure.isZIP64 { + return zip64DataDescriptor?.compressedSize ?? centralDirectoryStructure.effectiveCompressedSize + } + return UInt64(dataDescriptor?.compressedSize ?? centralDirectoryStructure.compressedSize) + } + + /// The size of the receiver's uncompressed data. + var uncompressedSize: UInt64 { + if centralDirectoryStructure.isZIP64 { + return zip64DataDescriptor?.uncompressedSize ?? centralDirectoryStructure.effectiveUncompressedSize + } + return UInt64(dataDescriptor?.uncompressedSize ?? centralDirectoryStructure.uncompressedSize) + } + + /// The combined size of the local header, the data and the optional data descriptor. + var localSize: UInt64 { + let localFileHeader = localFileHeader + var extraDataLength = Int(localFileHeader.fileNameLength) + extraDataLength += Int(localFileHeader.extraFieldLength) + var size = UInt64(LocalFileHeader.size + extraDataLength) + size += isCompressed ? compressedSize : uncompressedSize + if centralDirectoryStructure.isZIP64 { + size += zip64DataDescriptor != nil ? UInt64(ZIP64DataDescriptor.size) : 0 + } else { + size += dataDescriptor != nil ? UInt64(DefaultDataDescriptor.size) : 0 + } + return size + } + + var dataOffset: UInt64 { + var dataOffset = centralDirectoryStructure.effectiveRelativeOffsetOfLocalHeader + dataOffset += UInt64(LocalFileHeader.size) + dataOffset += UInt64(localFileHeader.fileNameLength) + dataOffset += UInt64(localFileHeader.extraFieldLength) + return dataOffset + } + + static func == (lhs: Entry, rhs: Entry) -> Bool { + lhs.path == rhs.path + && lhs.localFileHeader.crc32 == rhs.localFileHeader.crc32 + && lhs.centralDirectoryStructure.effectiveRelativeOffsetOfLocalHeader + == rhs.centralDirectoryStructure.effectiveRelativeOffsetOfLocalHeader + } + + /// Returns the `path` of the receiver within a ZIP `Archive` using a given encoding. + /// + /// - Parameters: + /// - encoding: `String.Encoding` + func path(using encoding: String.Encoding) -> String { + String(data: centralDirectoryStructure.fileNameData, encoding: encoding) ?? "" + } + +} + +extension Entry.CentralDirectoryStructure { + + init( + localFileHeader: Entry.LocalFileHeader, + fileAttributes: UInt32, + relativeOffset: UInt32, + extraField: (length: UInt16, data: Data)) + { + versionMadeBy = UInt16(789) + versionNeededToExtract = localFileHeader.versionNeededToExtract + generalPurposeBitFlag = localFileHeader.generalPurposeBitFlag + compressionMethod = localFileHeader.compressionMethod + lastModFileTime = localFileHeader.lastModFileTime + lastModFileDate = localFileHeader.lastModFileDate + crc32 = localFileHeader.crc32 + compressedSize = localFileHeader.compressedSize + uncompressedSize = localFileHeader.uncompressedSize + fileNameLength = localFileHeader.fileNameLength + extraFieldLength = extraField.length + fileCommentLength = UInt16(0) + diskNumberStart = UInt16(0) + internalFileAttributes = UInt16(0) + externalFileAttributes = fileAttributes + relativeOffsetOfLocalHeader = relativeOffset + fileNameData = localFileHeader.fileNameData + extraFieldData = extraField.data + fileCommentData = Data() + if + let zip64ExtendedInformation = Entry.ZIP64ExtendedInformation.scanForZIP64Field( + in: extraFieldData, + fields: validFields) + { + extraFields = [zip64ExtendedInformation] + } + } + + init( + centralDirectoryStructure: Entry.CentralDirectoryStructure, + zip64ExtendedInformation: Entry.ZIP64ExtendedInformation?, + relativeOffset: UInt32) + { + if let existingInfo = zip64ExtendedInformation { + extraFieldData = existingInfo.data + versionNeededToExtract = max( + centralDirectoryStructure.versionNeededToExtract, + Archive.Version.v45.rawValue) + } else { + extraFieldData = centralDirectoryStructure.extraFieldData + let existingVersion = centralDirectoryStructure.versionNeededToExtract + versionNeededToExtract = existingVersion < Archive.Version.v45.rawValue + ? centralDirectoryStructure.versionNeededToExtract + : Archive.Version.v20.rawValue + } + extraFieldLength = UInt16(extraFieldData.count) + relativeOffsetOfLocalHeader = relativeOffset + versionMadeBy = centralDirectoryStructure.versionMadeBy + generalPurposeBitFlag = centralDirectoryStructure.generalPurposeBitFlag + compressionMethod = centralDirectoryStructure.compressionMethod + lastModFileTime = centralDirectoryStructure.lastModFileTime + lastModFileDate = centralDirectoryStructure.lastModFileDate + crc32 = centralDirectoryStructure.crc32 + compressedSize = centralDirectoryStructure.compressedSize + uncompressedSize = centralDirectoryStructure.uncompressedSize + fileNameLength = centralDirectoryStructure.fileNameLength + fileCommentLength = centralDirectoryStructure.fileCommentLength + diskNumberStart = centralDirectoryStructure.diskNumberStart + internalFileAttributes = centralDirectoryStructure.internalFileAttributes + externalFileAttributes = centralDirectoryStructure.externalFileAttributes + fileNameData = centralDirectoryStructure.fileNameData + fileCommentData = centralDirectoryStructure.fileCommentData + if + let zip64ExtendedInformation = Entry.ZIP64ExtendedInformation.scanForZIP64Field( + in: extraFieldData, + fields: validFields) + { + extraFields = [zip64ExtendedInformation] + } + } +} + +extension Entry.CentralDirectoryStructure { + + var effectiveCompressedSize: UInt64 { + if isZIP64, let compressedSize = zip64ExtendedInformation?.compressedSize, compressedSize > 0 { + return compressedSize + } + return UInt64(compressedSize) + } + + var effectiveUncompressedSize: UInt64 { + if isZIP64, let uncompressedSize = zip64ExtendedInformation?.uncompressedSize, uncompressedSize > 0 { + return uncompressedSize + } + return UInt64(uncompressedSize) + } + + var effectiveRelativeOffsetOfLocalHeader: UInt64 { + if isZIP64, let offset = zip64ExtendedInformation?.relativeOffsetOfLocalHeader, offset > 0 { + return offset + } + return UInt64(relativeOffsetOfLocalHeader) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift new file mode 100644 index 00000000..69ea55e1 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift @@ -0,0 +1,368 @@ +// +// FileManager+ZIP.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension FileManager { + typealias CentralDirectoryStructure = Entry.CentralDirectoryStructure + + class func attributes(from entry: Entry) -> [FileAttributeKey: Any] { + let centralDirectoryStructure = entry.centralDirectoryStructure + let entryType = entry.type + let fileTime = centralDirectoryStructure.lastModFileTime + let fileDate = centralDirectoryStructure.lastModFileDate + let defaultPermissions = entryType == .directory ? defaultDirectoryPermissions : defaultFilePermissions + var attributes = [.posixPermissions: defaultPermissions] as [FileAttributeKey: Any] + // Certain keys are not yet supported in swift-corelibs + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + attributes[.modificationDate] = Date(dateTime: (fileDate, fileTime)) + #endif + let versionMadeBy = centralDirectoryStructure.versionMadeBy + guard let osType = Entry.OSType(rawValue: UInt(versionMadeBy >> 8)) else { return attributes } + + let externalFileAttributes = centralDirectoryStructure.externalFileAttributes + let permissions = permissions(for: externalFileAttributes, osType: osType, entryType: entryType) + attributes[.posixPermissions] = NSNumber(value: permissions) + return attributes + } + + class func permissions( + for externalFileAttributes: UInt32, + osType: Entry.OSType, + entryType: Entry.EntryType) + -> UInt16 + { + switch osType { + case .unix, .osx: + let permissions = mode_t(externalFileAttributes >> 16) & ~S_IFMT + let defaultPermissions = entryType == .directory ? defaultDirectoryPermissions : defaultFilePermissions + return permissions == 0 ? defaultPermissions : UInt16(permissions) + default: + return entryType == .directory ? defaultDirectoryPermissions : defaultFilePermissions + } + } + + class func externalFileAttributesForEntry(of type: Entry.EntryType, permissions: UInt16) -> UInt32 { + var typeInt: UInt16 + switch type { + case .file: + typeInt = UInt16(S_IFREG) + case .directory: + typeInt = UInt16(S_IFDIR) + case .symlink: + typeInt = UInt16(S_IFLNK) + } + var externalFileAttributes = UInt32(typeInt | UInt16(permissions)) + externalFileAttributes = (externalFileAttributes << 16) + return externalFileAttributes + } + + class func permissionsForItem(at URL: URL) throws -> UInt16 { + let fileManager = FileManager() + let entryFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: URL.path) + var fileStat = stat() + lstat(entryFileSystemRepresentation, &fileStat) + let permissions = fileStat.st_mode + return UInt16(permissions) + } + + class func fileModificationDateTimeForItem(at url: URL) throws -> Date { + let fileManager = FileManager() + guard fileManager.itemExists(at: url) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: url.path]) + } + let entryFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + var fileStat = stat() + lstat(entryFileSystemRepresentation, &fileStat) + #if os(macOS) || canImport(UIKit) + let modTimeSpec = fileStat.st_mtimespec + #else + let modTimeSpec = fileStat.st_mtim + #endif + + let timeStamp = TimeInterval(modTimeSpec.tv_sec) + TimeInterval(modTimeSpec.tv_nsec) / 1000000000.0 + let modDate = Date(timeIntervalSince1970: timeStamp) + return modDate + } + + class func fileSizeForItem(at url: URL) throws -> Int64 { + let fileManager = FileManager() + guard fileManager.itemExists(at: url) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: url.path]) + } + let entryFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + var fileStat = stat() + lstat(entryFileSystemRepresentation, &fileStat) + guard fileStat.st_size >= 0 else { + throw CocoaError(.fileReadTooLarge, userInfo: [NSFilePathErrorKey: url.path]) + } + // `st_size` is a signed int value + return Int64(fileStat.st_size) + } + + class func typeForItem(at url: URL) throws -> Entry.EntryType { + let fileManager = FileManager() + guard url.isFileURL, fileManager.itemExists(at: url) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: url.path]) + } + let entryFileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: url.path) + var fileStat = stat() + lstat(entryFileSystemRepresentation, &fileStat) + return Entry.EntryType(mode: mode_t(fileStat.st_mode)) + } + + /// Zips the file or directory contents at the specified source URL to the destination URL. + /// + /// If the item at the source URL is a directory, the directory itself will be + /// represented within the ZIP `Archive`. Calling this method with a directory URL + /// `file:///path/directory/` will create an archive with a `directory/` entry at the root level. + /// You can override this behavior by passing `false` for `shouldKeepParent`. In that case, the contents + /// of the source directory will be placed at the root of the archive. + /// - Parameters: + /// - sourceURL: The file URL pointing to an existing file or directory. + /// - destinationURL: The file URL that identifies the destination of the zip operation. + /// - shouldKeepParent: Indicates that the directory name of a source item should be used as root element + /// within the archive. Default is `true`. + /// - compressionMethod: Indicates the `CompressionMethod` that should be applied. + /// By default, `zipItem` will create uncompressed archives. + /// - progress: A progress object that can be used to track or cancel the zip operation. + /// - Throws: Throws an error if the source item does not exist or the destination URL is not writable. + func zipItem( + at sourceURL: URL, + to destinationURL: URL, + shouldKeepParent: Bool = true, + compressionMethod: CompressionMethod = .none, + progress: Progress? = nil) + throws + { + let fileManager = FileManager() + guard fileManager.itemExists(at: sourceURL) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: sourceURL.path]) + } + guard !fileManager.itemExists(at: destinationURL) else { + throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: destinationURL.path]) + } + guard let archive = Archive(url: destinationURL, accessMode: .create) else { + throw Archive.ArchiveError.unwritableArchive + } + let isDirectory = try FileManager.typeForItem(at: sourceURL) == .directory + if isDirectory { + let subPaths = try subpathsOfDirectory(atPath: sourceURL.path) + var totalUnitCount = Int64(0) + if let progress { + totalUnitCount = subPaths.reduce(Int64(0)) { + let itemURL = sourceURL.appendingPathComponent($1) + let itemSize = archive.totalUnitCountForAddingItem(at: itemURL) + return $0 + itemSize + } + progress.totalUnitCount = totalUnitCount + } + + // If the caller wants to keep the parent directory, we use the lastPathComponent of the source URL + // as common base for all entries (similar to macOS' Archive Utility.app) + let directoryPrefix = sourceURL.lastPathComponent + for entryPath in subPaths { + let finalEntryPath = shouldKeepParent ? directoryPrefix + "/" + entryPath : entryPath + let finalBaseURL = shouldKeepParent ? sourceURL.deletingLastPathComponent() : sourceURL + if let progress { + let itemURL = sourceURL.appendingPathComponent(entryPath) + let entryProgress = archive.makeProgressForAddingItem(at: itemURL) + progress.addChild(entryProgress, withPendingUnitCount: entryProgress.totalUnitCount) + try archive.addEntry( + with: finalEntryPath, + relativeTo: finalBaseURL, + compressionMethod: compressionMethod, + progress: entryProgress) + } else { + try archive.addEntry( + with: finalEntryPath, + relativeTo: finalBaseURL, + compressionMethod: compressionMethod) + } + } + } else { + progress?.totalUnitCount = archive.totalUnitCountForAddingItem(at: sourceURL) + let baseURL = sourceURL.deletingLastPathComponent() + try archive.addEntry( + with: sourceURL.lastPathComponent, + relativeTo: baseURL, + compressionMethod: compressionMethod, + progress: progress) + } + } + + /// Unzips the contents at the specified source URL to the destination URL. + /// + /// - Parameters: + /// - sourceURL: The file URL pointing to an existing ZIP file. + /// - destinationURL: The file URL that identifies the destination directory of the unzip operation. + /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - progress: A progress object that can be used to track or cancel the unzip operation. + /// - preferredEncoding: Encoding for entry paths. Overrides the encoding specified in the archive. + /// - Throws: Throws an error if the source item does not exist or the destination URL is not writable. + func unzipItem( + at sourceURL: URL, + to destinationURL: URL, + skipCRC32: Bool = false, + progress: Progress? = nil, + preferredEncoding: String.Encoding? = nil) + throws + { + let fileManager = FileManager() + guard fileManager.itemExists(at: sourceURL) else { + throw CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: sourceURL.path]) + } + guard let archive = Archive(url: sourceURL, accessMode: .read, preferredEncoding: preferredEncoding) else { + throw Archive.ArchiveError.unreadableArchive + } + // Defer extraction of symlinks until all files & directories have been created. + // This is necessary because we can't create links to files that haven't been created yet. + let sortedEntries = archive.sorted { left, right -> Bool in + switch (left.type, right.type) { + case (.directory, .file): return true + case (.directory, .symlink): return true + case (.file, .symlink): return true + default: return false + } + } + var totalUnitCount = Int64(0) + if let progress { + totalUnitCount = sortedEntries.reduce(0) { $0 + archive.totalUnitCountForReading($1) } + progress.totalUnitCount = totalUnitCount + } + + for entry in sortedEntries { + let path = preferredEncoding == nil ? entry.path : entry.path(using: preferredEncoding!) + let entryURL = destinationURL.appendingPathComponent(path) + guard entryURL.isContained(in: destinationURL) else { + throw CocoaError( + .fileReadInvalidFileName, + userInfo: [NSFilePathErrorKey: entryURL.path]) + } + let crc32: CRC32 + if let progress { + let entryProgress = archive.makeProgressForReading(entry) + progress.addChild(entryProgress, withPendingUnitCount: entryProgress.totalUnitCount) + crc32 = try archive.extract(entry, to: entryURL, skipCRC32: skipCRC32, progress: entryProgress) + } else { + crc32 = try archive.extract(entry, to: entryURL, skipCRC32: skipCRC32) + } + + func verifyChecksumIfNecessary() throws { + if skipCRC32 == false, crc32 != entry.checksum { + throw Archive.ArchiveError.invalidCRC32 + } + } + try verifyChecksumIfNecessary() + } + } + + // MARK: - Helpers + + func itemExists(at url: URL) -> Bool { + // Use `URL.checkResourceIsReachable()` instead of `FileManager.fileExists()` here + // because we don't want implicit symlink resolution. + // As per documentation, `FileManager.fileExists()` traverses symlinks and therefore a broken symlink + // would throw a `.fileReadNoSuchFile` false positive error. + // For ZIP files it may be intended to archive "broken" symlinks because they might be + // resolvable again when extracting the archive to a different destination. + (try? url.checkResourceIsReachable()) == true + } + + func createParentDirectoryStructure(for url: URL) throws { + let parentDirectoryURL = url.deletingLastPathComponent() + try createDirectory(at: parentDirectoryURL, withIntermediateDirectories: true, attributes: nil) + } + +} + +extension Date { + + // MARK: Lifecycle + + init(dateTime: (UInt16, UInt16)) { + var msdosDateTime = Int(dateTime.0) + msdosDateTime <<= 16 + msdosDateTime |= Int(dateTime.1) + var unixTime = tm() + unixTime.tm_sec = Int32((msdosDateTime & 31) * 2) + unixTime.tm_min = Int32((msdosDateTime >> 5) & 63) + unixTime.tm_hour = Int32((Int(dateTime.1) >> 11) & 31) + unixTime.tm_mday = Int32((msdosDateTime >> 16) & 31) + unixTime.tm_mon = Int32((msdosDateTime >> 21) & 15) + unixTime.tm_mon -= 1 // UNIX time struct month entries are zero based. + unixTime.tm_year = Int32(1980 + (msdosDateTime >> 25)) + unixTime.tm_year -= 1900 // UNIX time structs count in "years since 1900". + let time = timegm(&unixTime) + self = Date(timeIntervalSince1970: TimeInterval(time)) + } + + // MARK: Internal + + var fileModificationDateTime: (UInt16, UInt16) { + (self.fileModificationDate, self.fileModificationTime) + } + + var fileModificationDate: UInt16 { + var time = time_t(timeIntervalSince1970) + guard let unixTime = gmtime(&time) else { + return 0 + } + var year = unixTime.pointee.tm_year + 1900 // UNIX time structs count in "years since 1900". + // ZIP uses the MSDOS date format which has a valid range of 1980 - 2099. + year = year >= 1980 ? year : 1980 + year = year <= 2099 ? year : 2099 + let month = unixTime.pointee.tm_mon + 1 // UNIX time struct month entries are zero based. + let day = unixTime.pointee.tm_mday + return UInt16(day + (month * 32) + ((year - 1980) * 512)) + } + + var fileModificationTime: UInt16 { + var time = time_t(timeIntervalSince1970) + guard let unixTime = gmtime(&time) else { + return 0 + } + let hour = unixTime.pointee.tm_hour + let minute = unixTime.pointee.tm_min + let second = unixTime.pointee.tm_sec + return UInt16((second / 2) + (minute * 32) + (hour * 2048)) + } +} + +#if swift(>=4.2) +#else + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +#else + +// The swift-corelibs-foundation version of NSError.swift was missing a convenience method to create +// error objects from error codes. (https://github.com/apple/swift-corelibs-foundation/pull/1420) +// We have to provide an implementation for non-Darwin platforms using Swift versions < 4.2. + +extension CocoaError { + static func error(_ code: CocoaError.Code, userInfo: [AnyHashable: Any]? = nil, url: URL? = nil) -> Error { + var info: [String: Any] = userInfo as? [String: Any] ?? [:] + if let url { + info[NSURLErrorKey] = url + } + return NSError(domain: NSCocoaErrorDomain, code: code.rawValue, userInfo: info) + } +} + +#endif +#endif + +extension URL { + func isContained(in parentDirectoryURL: URL) -> Bool { + // Ensure this URL is contained in the passed in URL + let parentDirectoryURL = URL(fileURLWithPath: parentDirectoryURL.path, isDirectory: true).standardized + return standardized.absoluteString.hasPrefix(parentDirectoryURL.absoluteString) + } +} diff --git a/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/URL+ZIP.swift b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/URL+ZIP.swift new file mode 100644 index 00000000..add5aa64 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/EmbeddedLibraries/ZipFoundation/URL+ZIP.swift @@ -0,0 +1,32 @@ +// +// URL+ZIP.swift +// ZIPFoundation +// +// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Released under the MIT License. +// +// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. +// + +import Foundation + +extension URL { + + static func temporaryReplacementDirectoryURL(for archive: Archive) -> URL { + #if swift(>=5.0) || os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + if + archive.url.isFileURL, + let tempDir = try? FileManager().url( + for: .itemReplacementDirectory, + in: .userDomainMask, + appropriateFor: archive.url, + create: true) + { + return tempDir + } + #endif + + return URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent( + ProcessInfo.processInfo.globallyUniqueString) + } +} diff --git a/Pods/lottie-ios/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift b/Pods/lottie-ios/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift new file mode 100644 index 00000000..67be54b5 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift @@ -0,0 +1,85 @@ +// +// RoundedCornersNode.swift +// Lottie +// +// Created by Duolingo on 10/31/22. +// + +import Foundation +import QuartzCore + +// MARK: - RoundedCornersProperties + +final class RoundedCornersProperties: NodePropertyMap, KeypathSearchable { + + // MARK: Lifecycle + + init(roundedCorners: RoundedCorners) { + keypathName = roundedCorners.name + radius = NodeProperty(provider: KeyframeInterpolator(keyframes: roundedCorners.radius.keyframes)) + keypathProperties = ["Radius" : radius] + properties = Array(keypathProperties.values) + } + + // MARK: Internal + + let keypathProperties: [String: AnyNodeProperty] + let properties: [AnyNodeProperty] + let keypathName: String + + let radius: NodeProperty +} + +// MARK: - RoundedCornersNode + +final class RoundedCornersNode: AnimatorNode { + + // MARK: Lifecycle + + init(parentNode: AnimatorNode?, roundedCorners: RoundedCorners, upstreamPaths: [PathOutputNode]) { + outputNode = PassThroughOutputNode(parent: parentNode?.outputNode) + self.parentNode = parentNode + properties = RoundedCornersProperties(roundedCorners: roundedCorners) + self.upstreamPaths = upstreamPaths + } + + // MARK: Internal + + let properties: RoundedCornersProperties + + let parentNode: AnimatorNode? + let outputNode: NodeOutput + var hasLocalUpdates = false + var hasUpstreamUpdates = false + var lastUpdateFrame: CGFloat? = nil + var isEnabled = true + + // MARK: Animator Node + var propertyMap: NodePropertyMap & KeypathSearchable { + properties + } + + func forceUpstreamOutputUpdates() -> Bool { + hasLocalUpdates || hasUpstreamUpdates + } + + func rebuildOutputs(frame: CGFloat) { + for pathContainer in upstreamPaths { + let pathObjects = pathContainer.removePaths(updateFrame: frame) + for path in pathObjects { + let cornerRadius = properties.radius.value.cgFloatValue + if cornerRadius != 0 { + pathContainer.appendPath( + path.roundCorners(radius: cornerRadius), + updateFrame: frame) + } else { + pathContainer.appendPath(path, updateFrame: frame) + } + } + } + } + + // MARK: Fileprivate + + fileprivate let upstreamPaths: [PathOutputNode] +} diff --git a/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieAnimation.swift b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieAnimation.swift new file mode 100644 index 00000000..e751615d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieAnimation.swift @@ -0,0 +1,57 @@ +// +// DotLottieAnimation.swift +// Pods +// +// Created by Evandro Harrison Hoffmann on 28/06/2021. +// + +import Foundation + +// MARK: - DotLottieAnimation + +struct DotLottieAnimation: Codable { + /// Id of Animation + var id: String + + /// Loop enabled + var loop: Bool? = false + + /// Animation Playback Speed + var speed: Double? = 1 + + /// 1 or -1 + var direction: Int? = 1 + + /// mode - "bounce" | "normal" + var mode: DotLottieAnimationMode? = .normal + + /// Loop mode for animation + var loopMode: LottieLoopMode { + switch mode { + case .bounce: + return .autoReverse + case .normal, nil: + return (loop ?? false) ? .loop : .playOnce + } + } + + /// Animation speed + var animationSpeed: Double { + (speed ?? 1) * Double(direction ?? 1) + } + + /// Loads `LottieAnimation` from `animationUrl` + /// - Returns: Deserialized `LottieAnimation`. Optional. + func animation(url: URL) throws -> LottieAnimation { + let animationUrl = url.appendingPathComponent("\(id).json") + let data = try Data(contentsOf: animationUrl) + return try LottieAnimation.from(data: data) + } +} + +// MARK: - DotLottieAnimationMode + +enum DotLottieAnimationMode: String, Codable { + case normal + case bounce +} diff --git a/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift new file mode 100644 index 00000000..e426fc0a --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift @@ -0,0 +1,89 @@ +// +// DotLottieImageProvider.swift +// Lottie +// +// Created by Evandro Hoffmann on 20/10/22. +// + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +// MARK: - DotLottieImageProvider + +/// An image provider that loads the images from a DotLottieFile into memory +class DotLottieImageProvider: AnimationImageProvider { + + // MARK: Lifecycle + + /// Initializes an image provider with a specific filepath. + /// + /// - Parameter filepath: The absolute filepath containing the images. + /// + convenience init?(filepath: String) { + self.init(filepath: URL(fileURLWithPath: filepath)) + } + + init?(filepath: URL) { + guard filepath.urls.count > 0 else { return nil } + self.filepath = filepath + loadImages() + } + + // MARK: Internal + + let filepath: URL + + func imageForAsset(asset: ImageAsset) -> CGImage? { + if let base64Image = asset.base64Image { + return base64Image + } + + return images[asset.name] + } + + // MARK: Private + + /// This is intentionally a Dictionary instead of an NSCache. Files from a decompressed dotLottie zip archive + /// are only valid are deleted after being read into memory. If we used an NSCache then the OS could evict + /// the cache entries when under memory pressure, and we would have no way to reload them later. + /// - Ideally we would have a way to remove image data when under memory pressure, but this would require + /// re-decompressing the dotLottie file when requesting an image that has been loaded but then removed. + private var images = [String: CGImage]() + + private func loadImages() { + for url in filepath.urls { + #if canImport(UIKit) + if + let data = try? Data(contentsOf: url), + let image = UIImage(data: data)?.cgImage + { + images[url.lastPathComponent] = image + } + #elseif canImport(AppKit) + if + let data = try? Data(contentsOf: url), + let image = NSImage(data: data)?.lottie_CGImage + { + images[url.lastPathComponent] = image + } + #endif + } + } + +} + +// MARK: Hashable + +extension DotLottieImageProvider: Hashable { + static func ==(_ lhs: DotLottieImageProvider, _ rhs: DotLottieImageProvider) -> Bool { + lhs.filepath == rhs.filepath + } + + func hash(into hasher: inout Hasher) { + hasher.combine(filepath) + } + +} diff --git a/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieManifest.swift b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieManifest.swift new file mode 100644 index 00000000..d4750928 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieManifest.swift @@ -0,0 +1,42 @@ +// +// DotLottieManifest.swift +// Lottie +// +// Created by Evandro Harrison Hoffmann on 27/06/2020. +// + +import Foundation + +/// Manifest model for .lottie File +struct DotLottieManifest: Codable { + + var animations: [DotLottieAnimation] + var version: String? + var author: String? + var generator: String? + + /// Decodes data to Manifest model + /// - Parameter data: Data to decode + /// - Throws: Error + /// - Returns: .lottie Manifest model + static func decode(from data: Data) throws -> DotLottieManifest { + try JSONDecoder().decode(DotLottieManifest.self, from: data) + } + + /// Loads manifest from given URL + /// - Parameter path: URL path to Manifest + /// - Returns: Manifest Model + static func load(from url: URL) throws -> DotLottieManifest { + let data = try Data(contentsOf: url) + return try decode(from: data) + } + + /// Encodes to data + /// - Parameter encoder: JSONEncoder + /// - Throws: Error + /// - Returns: encoded Data + func encode(with encoder: JSONEncoder = JSONEncoder()) throws -> Data { + try encoder.encode(self) + } + +} diff --git a/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieUtils.swift b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieUtils.swift new file mode 100644 index 00000000..72994dec --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/DotLottie/DotLottieUtils.swift @@ -0,0 +1,68 @@ +// +// DotLottieUtils.swift +// Lottie +// +// Created by Evandro Harrison Hoffmann on 27/06/2020. +// + +import Foundation + +// MARK: - DotLottieUtils + +enum DotLottieUtils { + static let dotLottieExtension = "lottie" + static let jsonExtension = "json" + + /// Temp folder to app directory + static var tempDirectoryURL: URL { + if #available(iOS 10.0, macOS 10.12, *) { + return FileManager.default.temporaryDirectory + } + return URL(fileURLWithPath: NSTemporaryDirectory()) + } +} + +extension URL { + /// Checks if url is a lottie file + var isDotLottie: Bool { + pathExtension == DotLottieUtils.dotLottieExtension + } + + /// Checks if url is a json file + var isJsonFile: Bool { + pathExtension == DotLottieUtils.jsonExtension + } + + var urls: [URL] { + FileManager.default.urls(for: self) ?? [] + } +} + +extension FileManager { + /// Lists urls for all files in a directory + /// - Parameters: + /// - url: URL of directory to search + /// - skipsHiddenFiles: If should or not show hidden files + /// - Returns: Returns urls of all files matching criteria in the directory + func urls(for url: URL, skipsHiddenFiles: Bool = true) -> [URL]? { + try? contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: skipsHiddenFiles ? .skipsHiddenFiles : []) + } +} + +// MARK: - DotLottieError + +public enum DotLottieError: Error { + /// URL response has no data. + case noDataLoaded + /// Asset with this name was not found in the provided bundle. + case assetNotFound(name: String, bundle: Bundle?) + /// Animation loading from asset is not supported on macOS 10.10. + case loadingFromAssetNotSupported + + @available(*, deprecated, message: "Unused") + case invalidFileFormat + @available(*, deprecated, message: "Unused") + case invalidData + @available(*, deprecated, message: "Unused") + case animationNotAvailable +} diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerEffects/DropShadowEffect.swift b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/DropShadowEffect.swift new file mode 100644 index 00000000..655c7f1d --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/DropShadowEffect.swift @@ -0,0 +1,43 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +final class DropShadowEffect: LayerEffect { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + try super.init(from: decoder) + } + + required init(dictionary: [String: Any]) throws { + try super.init(dictionary: dictionary) + } + + // MARK: Internal + + /// The color of the drop shadow + var color: ColorEffectValue? { + value(named: "Shadow Color") + } + + /// Opacity between 0 and 255 + var opacity: Vector1DEffectValue? { + value(named: "Opacity") + } + + /// The direction / angle of the drop shadow, in degrees + var direction: Vector1DEffectValue? { + value(named: "Direction") + } + + /// The distance of the drop shadow + var distance: Vector1DEffectValue? { + value(named: "Distance") + } + + /// The softness of the drop shadow + var softness: Vector1DEffectValue? { + value(named: "Softness") + } + +} diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift new file mode 100644 index 00000000..125c65d2 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift @@ -0,0 +1,36 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +final class ColorEffectValue: EffectValue { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + value = try? container.decode(KeyframeGroup.self, forKey: .value) + try super.init(from: decoder) + } + + required init(dictionary: [String: Any]) throws { + let valueDictionary: [String: Any] = try dictionary.value(for: CodingKeys.value) + value = try KeyframeGroup(dictionary: valueDictionary) + try super.init(dictionary: dictionary) + } + + // MARK: Internal + + /// The value of the color + let value: KeyframeGroup? + + override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(value, forKey: .value) + } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case value = "v" + } +} diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift new file mode 100644 index 00000000..8cae5e59 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift @@ -0,0 +1,97 @@ +// Created by Cal Stephens on 8/15/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - EffectValueType + +/// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effect-values +enum EffectValueType: Int, Codable, Sendable { + case slider = 0 + case angle = 1 + case color = 2 + case unknown = 9999 + + init(from decoder: Decoder) throws { + self = try EffectValueType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown + } +} + +// MARK: ClassFamily + +extension EffectValueType: ClassFamily { + static var discriminator: Discriminator = .type + + func getType() -> AnyObject.Type { + switch self { + case .slider: + return Vector1DEffectValue.self + case .angle: + return Vector1DEffectValue.self + case .color: + return ColorEffectValue.self + case .unknown: + // Unsupported + return LayerEffect.self + } + } +} + +// MARK: - EffectValue + +class EffectValue: Codable, DictionaryInitializable { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: EffectValue.CodingKeys.self) + type = try container.decode(EffectValueType.self, forKey: .type) + name = try container.decode(String.self, forKey: .name) + } + + required init(dictionary: [String: Any]) throws { + type = (try? dictionary.value(for: CodingKeys.type)).flatMap(EffectValueType.init(rawValue:)) ?? .unknown + name = (try? dictionary.value(for: CodingKeys.name)) ?? "Effect" + } + + // MARK: Internal + + /// The type of effect value + let type: EffectValueType + + /// The name of the effect value + let name: String + + // MARK: Fileprivate + + fileprivate enum CodingKeys: String, CodingKey { + case type = "ty" + case name = "nm" + } +} + +extension [EffectValue] { + static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [EffectValue] { + try dictionaries.compactMap { dictionary in + let shapeType = dictionary[EffectValue.CodingKeys.type.rawValue] as? Int + switch EffectValueType(rawValue: shapeType ?? EffectValueType.unknown.rawValue) { + case .slider: + return try Vector1DEffectValue(dictionary: dictionary) + case .angle: + return try Vector1DEffectValue(dictionary: dictionary) + case .color: + return try ColorEffectValue(dictionary: dictionary) + case .unknown: + // Unsupported + return try EffectValue(dictionary: dictionary) + case nil: + return nil + } + } + } +} + +// MARK: - EffectValue + Sendable + +/// Since `EffectValue` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `EffectValue` subclasses are immutable `Sendable` values. +// swiftlint:disable:next no_unchecked_sendable +extension EffectValue: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift new file mode 100644 index 00000000..59555a49 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift @@ -0,0 +1,36 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +final class Vector1DEffectValue: EffectValue { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + value = try? container.decode(KeyframeGroup.self, forKey: .value) + try super.init(from: decoder) + } + + required init(dictionary: [String: Any]) throws { + let valueDictionary: [String: Any] = try dictionary.value(for: CodingKeys.value) + value = try KeyframeGroup(dictionary: valueDictionary) + try super.init(dictionary: dictionary) + } + + // MARK: Internal + + /// The value of the slider + let value: KeyframeGroup? + + override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(value, forKey: .value) + } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case value = "v" + } +} diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerEffects/LayerEffect.swift b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/LayerEffect.swift new file mode 100644 index 00000000..9bb8c27c --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerEffects/LayerEffect.swift @@ -0,0 +1,102 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - LayerEffectType + +/// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effects +enum LayerEffectType: Int, Codable, Sendable { + case dropShadow = 25 + case unknown = 9999 + + init(from decoder: Decoder) throws { + self = try LayerEffectType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown + } +} + +// MARK: ClassFamily + +extension LayerEffectType: ClassFamily { + static var discriminator: Discriminator = .type + + func getType() -> AnyObject.Type { + switch self { + case .dropShadow: + return DropShadowEffect.self + case .unknown: + // Unsupported + return LayerEffect.self + } + } +} + +// MARK: - LayerEffect + +class LayerEffect: Codable, DictionaryInitializable { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: LayerEffect.CodingKeys.self) + name = try container.decodeIfPresent(String.self, forKey: .name) ?? "Effect" + type = try container.decode(LayerEffectType.self, forKey: .type) + effects = try container.decodeIfPresent([EffectValue].self, ofFamily: EffectValueType.self, forKey: .effects) ?? [] + } + + required init(dictionary: [String: Any]) throws { + name = (try? dictionary.value(for: CodingKeys.name)) ?? "Layer" + type = LayerEffectType(rawValue: try dictionary.value(for: CodingKeys.type)) ?? .unknown + if let valueDictionaries = dictionary[CodingKeys.effects.rawValue] as? [[String: Any]] { + effects = try [EffectValue].fromDictionaries(valueDictionaries) + } else { + effects = [] + } + } + + // MARK: Internal + + /// The name of the effect + let name: String + + /// The type of effect + let type: LayerEffectType + + /// Values that configure the behavior of the effect + let effects: [EffectValue] + + /// Retrieves the `EffectValue` for the given name + func value(named name: String) -> ValueType? { + effects.first(where: { + $0.name == name && $0 is ValueType + }) as? ValueType + } + + // MARK: Fileprivate + + fileprivate enum CodingKeys: String, CodingKey { + case name = "nm" + case type = "ty" + case effects = "ef" + } +} + +extension [LayerEffect] { + static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerEffect] { + try dictionaries.compactMap { dictionary in + let shapeType = dictionary[LayerEffect.CodingKeys.type.rawValue] as? Int + switch LayerEffectType(rawValue: shapeType ?? LayerEffectType.unknown.rawValue) { + case .dropShadow: + return try DropShadowEffect(dictionary: dictionary) + case .unknown, nil: + // Unsupported + return try LayerEffect(dictionary: dictionary) + } + } + } +} + +// MARK: - LayerEffect + Sendable + +/// Since `LayerEffect` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `LayerEffect` subclasses are immutable `Sendable` values. +// swiftlint:disable:next no_unchecked_sendable +extension LayerEffect: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerStyles/DropShadowStyle.swift b/Pods/lottie-ios/Sources/Private/Model/LayerStyles/DropShadowStyle.swift new file mode 100644 index 00000000..1f2d14a9 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerStyles/DropShadowStyle.swift @@ -0,0 +1,70 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +final class DropShadowStyle: LayerStyle { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DropShadowStyle.CodingKeys.self) + opacity = try container.decode(KeyframeGroup.self, forKey: .opacity) + color = try container.decode(KeyframeGroup.self, forKey: .color) + angle = try container.decode(KeyframeGroup.self, forKey: .angle) + size = try container.decode(KeyframeGroup.self, forKey: .size) + distance = try container.decode(KeyframeGroup.self, forKey: .distance) + try super.init(from: decoder) + } + + required init(dictionary: [String: Any]) throws { + let opacityDictionary: [String: Any] = try dictionary.value(for: CodingKeys.opacity) + opacity = try KeyframeGroup(dictionary: opacityDictionary) + let colorDictionary: [String: Any] = try dictionary.value(for: CodingKeys.color) + color = try KeyframeGroup(dictionary: colorDictionary) + let angleDictionary: [String: Any] = try dictionary.value(for: CodingKeys.angle) + angle = try KeyframeGroup(dictionary: angleDictionary) + let sizeDictionary: [String: Any] = try dictionary.value(for: CodingKeys.size) + size = try KeyframeGroup(dictionary: sizeDictionary) + let distanceDictionary: [String: Any] = try dictionary.value(for: CodingKeys.distance) + distance = try KeyframeGroup(dictionary: distanceDictionary) + try super.init(dictionary: dictionary) + } + + // MARK: Internal + + /// The opacity of the drop shadow + let opacity: KeyframeGroup + + /// The color of the drop shadow + let color: KeyframeGroup + + /// The angle of the drop shadow, in degrees, + /// with `0` representing a shadow straight-down from the layer + /// (`offsetY=distance, offsetX=0`). + let angle: KeyframeGroup + + /// The size of the drop shadow + let size: KeyframeGroup + + /// The distance of the drop shadow + let distance: KeyframeGroup + + override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(opacity, forKey: .opacity) + try container.encode(color, forKey: .color) + try container.encode(angle, forKey: .angle) + try container.encode(size, forKey: .size) + try container.encode(distance, forKey: .distance) + } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case color = "c" + case opacity = "o" + case angle = "a" + case size = "s" + case distance = "d" + } +} diff --git a/Pods/lottie-ios/Sources/Private/Model/LayerStyles/LayerStyle.swift b/Pods/lottie-ios/Sources/Private/Model/LayerStyles/LayerStyle.swift new file mode 100644 index 00000000..b6ef1c32 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/LayerStyles/LayerStyle.swift @@ -0,0 +1,84 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - LayerStyleType + +enum LayerStyleType: Int, Codable, Sendable { + case dropShadow = 1 + case unknown = 9999 + + init(from decoder: Decoder) throws { + self = try LayerStyleType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown + } +} + +// MARK: ClassFamily + +extension LayerStyleType: ClassFamily { + static var discriminator: Discriminator = .type + + func getType() -> AnyObject.Type { + switch self { + case .dropShadow: + return DropShadowStyle.self + case .unknown: + // Unsupported + return LayerStyle.self + } + } +} + +// MARK: - LayerStyle + +class LayerStyle: Codable, DictionaryInitializable { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: LayerStyle.CodingKeys.self) + name = try container.decodeIfPresent(String.self, forKey: .name) ?? "Style" + type = try container.decode(LayerStyleType.self, forKey: .type) + } + + required init(dictionary: [String: Any]) throws { + name = (try? dictionary.value(for: CodingKeys.name)) ?? "Layer" + type = LayerStyleType(rawValue: try dictionary.value(for: CodingKeys.type)) ?? .unknown + } + + // MARK: Internal + + /// The name of the style + let name: String + + /// The type of style + let type: LayerStyleType + + // MARK: Fileprivate + + fileprivate enum CodingKeys: String, CodingKey { + case name = "nm" + case type = "ty" + } +} + +extension [LayerStyle] { + static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerStyle] { + try dictionaries.compactMap { dictionary in + let shapeType = dictionary[LayerStyle.CodingKeys.type.rawValue] as? Int + switch LayerStyleType(rawValue: shapeType ?? LayerStyleType.unknown.rawValue) { + case .dropShadow: + return try DropShadowStyle(dictionary: dictionary) + case .unknown, nil: + // Unsupported + return try LayerStyle(dictionary: dictionary) + } + } + } +} + +// MARK: - LayerStyle + Sendable + +/// Since `LayerStyle` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `LayerStyle` subclasses are immutable `Sendable` values. +// swiftlint:disable:next no_unchecked_sendable +extension LayerStyle: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Private/Model/ShapeItems/RoundedCorners.swift b/Pods/lottie-ios/Sources/Private/Model/ShapeItems/RoundedCorners.swift new file mode 100644 index 00000000..6cc1aa85 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Model/ShapeItems/RoundedCorners.swift @@ -0,0 +1,45 @@ +// +// RoundedCorners.swift +// Lottie +// +// Created by Duolingo on 10/31/22. +// + +// MARK: - RoundedCorners + +final class RoundedCorners: ShapeItem { + + // MARK: Lifecycle + + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: RoundedCorners.CodingKeys.self) + radius = try + container.decode( + KeyframeGroup.self, + forKey: .radius) + try super.init(from: decoder) + } + + required init(dictionary: [String: Any]) throws { + let radiusDictionary: [String: Any] = try dictionary.value(for: CodingKeys.radius) + radius = try KeyframeGroup(dictionary: radiusDictionary) + try super.init(dictionary: dictionary) + } + + // MARK: Internal + + /// The radius of rounded corners + let radius: KeyframeGroup + + override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(radius, forKey: .radius) + } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case radius = "r" + } +} diff --git a/Pods/lottie-ios/Sources/Private/Utility/Helpers/AnyEquatable.swift b/Pods/lottie-ios/Sources/Private/Utility/Helpers/AnyEquatable.swift new file mode 100644 index 00000000..e695eb8c --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Utility/Helpers/AnyEquatable.swift @@ -0,0 +1,22 @@ +// Created by miguel_jimenez on 8/2/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - AnyEquatable + +struct AnyEquatable { + private let value: Any + private let equals: (Any) -> Bool + + init(_ value: T) { + self.value = value + equals = { $0 as? T == value } + } +} + +// MARK: Equatable + +extension AnyEquatable: Equatable { + static func ==(lhs: AnyEquatable, rhs: AnyEquatable) -> Bool { + lhs.equals(rhs.value) + } +} diff --git a/Pods/lottie-ios/Sources/Private/Utility/Helpers/Binding+Map.swift b/Pods/lottie-ios/Sources/Private/Utility/Helpers/Binding+Map.swift new file mode 100644 index 00000000..5dba7547 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Utility/Helpers/Binding+Map.swift @@ -0,0 +1,20 @@ +// Created by miguel_jimenez on 7/27/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension Binding { + + /// Helper to transform a `Binding` from one `Value` type to another. + func map(transform: @escaping (Value) -> Transformed) -> Binding { + .init { + transform(wrappedValue) + } set: { newValue in + guard let newValue = newValue as? Value else { return } + self.wrappedValue = newValue + } + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/Utility/Helpers/View+ValueChanged.swift b/Pods/lottie-ios/Sources/Private/Utility/Helpers/View+ValueChanged.swift new file mode 100644 index 00000000..68d6a86a --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Utility/Helpers/View+ValueChanged.swift @@ -0,0 +1,22 @@ +// Created by miguel_jimenez on 7/26/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(Combine) && canImport(SwiftUI) +import Combine +import SwiftUI + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension View { + /// A backwards compatible wrapper for iOS 14 `onChange` + @ViewBuilder + func valueChanged(value: T, onChange: @escaping (T) -> Void) -> some View { + if #available(iOS 14.0, *, macOS 11.0, tvOS 14.0) { + self.onChange(of: value, perform: onChange) + } else { + onReceive(Just(value)) { value in + onChange(value) + } + } + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Private/Utility/LottieAnimationSource.swift b/Pods/lottie-ios/Sources/Private/Utility/LottieAnimationSource.swift new file mode 100644 index 00000000..16748348 --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Utility/LottieAnimationSource.swift @@ -0,0 +1,51 @@ +// Created by Cal Stephens on 7/26/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - LottieAnimationSource + +/// A data source for a Lottie animation. +/// Either a `LottieAnimation` loaded from a `.json` file, +/// or a `DotLottieFile` loaded from a `.lottie` file. +public enum LottieAnimationSource: Sendable { + /// A `LottieAnimation` loaded from a `.json` file + case lottieAnimation(LottieAnimation) + + /// A `DotLottieFile` loaded from a `.lottie` file + case dotLottieFile(DotLottieFile) +} + +extension LottieAnimationSource { + /// The default animation displayed by this data source + var animation: LottieAnimation? { + switch self { + case .lottieAnimation(let animation): + return animation + case .dotLottieFile: + return dotLottieAnimation?.animation + } + } + + /// The `DotLottieFile.Animation`, if this is a dotLottie animation + var dotLottieAnimation: DotLottieFile.Animation? { + switch self { + case .lottieAnimation: + return nil + case .dotLottieFile(let dotLottieFile): + return dotLottieFile.animation() + } + } +} + +extension LottieAnimation { + /// This animation represented as a `LottieAnimationSource` + public var animationSource: LottieAnimationSource { + .lottieAnimation(self) + } +} + +extension DotLottieFile { + /// This animation represented as a `LottieAnimationSource` + public var animationSource: LottieAnimationSource { + .dotLottieFile(self) + } +} diff --git a/Pods/lottie-ios/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift b/Pods/lottie-ios/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift new file mode 100644 index 00000000..01c5d5ee --- /dev/null +++ b/Pods/lottie-ios/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift @@ -0,0 +1,158 @@ +// +// BezierPathRoundExtension.swift +// Lottie +// +// Created by Duolingo on 11/1/22. +// + +import CoreGraphics +import Foundation + +// Adapted to Swift from lottie-web & lottie-android: + +// Rounded corner algorithm: +// Iterate through each vertex. +// If a vertex is a sharp corner, it rounds it. +// If a vertex has control points, it is already rounded, so it does nothing. +// +// To round a vertex: +// Split the vertex into two. +// Move vertex 1 directly towards the previous vertex. +// Set vertex 1's in control point to itself so it is not rounded on that side. +// Extend vertex 1's out control point towards the original vertex. +// +// Repeat for vertex 2: +// Move vertex 2 directly towards the next vertex. +// Set vertex 2's out point to itself so it is not rounded on that side. +// Extend vertex 2's in control point towards the original vertex. +// +// The distance that the vertices and control points are moved are relative to the +// shape's vertex distances and the roundedness set in the animation. + +extension CompoundBezierPath { + // Round corners of a compound bezier + func roundCorners(radius: CGFloat) -> CompoundBezierPath { + var newPaths = [BezierPath]() + for path in paths { + newPaths.append( + path.roundCorners(radius: radius)) + } + + return CompoundBezierPath(paths: newPaths) + } +} + +extension BezierPath { + // Computes a new `BezierPath` with each corner rounded based on the given `radius` + func roundCorners(radius: CGFloat) -> BezierPath { + var newPath = BezierPath() + var uniquePath = BezierPath() + + var currentVertex: CurveVertex + var closestVertex: CurveVertex + var distance: CGFloat + var newPosPerc: CGFloat + var closestIndex: Int + + var iX: CGFloat + var iY: CGFloat + var vX: CGFloat + var vY: CGFloat + var oX: CGFloat + var oY: CGFloat + + var startIndex = 0 + + let TANGENT_LENGTH = 0.5519 + + // If start and end are the same we close the path + if + elements[0].vertex.point == elements[elements.count - 1].vertex.point, + elements[0].vertex.inTangent == elements[elements.count - 1].vertex.inTangent, + elements[0].vertex.outTangent == elements[elements.count - 1].vertex.outTangent + { + startIndex = 1 + newPath.close() + } + + guard elements.count - startIndex > 1 else { + return self + } + + for i in startIndex.. Void)? + + /// The configuration that this `LottieAnimationView` uses when playing its animation + public var configuration: LottieConfiguration { + didSet { + if configuration.renderingEngine != oldValue.renderingEngine { + makeAnimationLayer(usingEngine: configuration.renderingEngine) + } + } + } + + /// The underlying CALayer created to display the content. + /// Use this property to change CALayer props like the content's transform, anchor point, etc. + public var animationLayer: CALayer? { rootAnimationLayer } + + public var screenScale: CGFloat { + didSet { + rootAnimationLayer?.renderScale = screenScale + } + } + + /// Describes the behavior of an AnimationView when the app is moved to the background. + /// + /// The default for the Main Thread animation engine is `pause`, + /// which pauses the animation when the application moves to + /// the background. This prevents the animation from consuming CPU + /// resources when not on-screen. The completion block is called with + /// `false` for completed. + /// + /// The default for the Core Animation engine is `continuePlaying`, + /// since the Core Animation engine does not have any CPU overhead. + public var backgroundBehavior: LottieBackgroundBehavior { + get { + let currentBackgroundBehavior = _backgroundBehavior ?? .default(for: currentRenderingEngine ?? .mainThread) + + if + currentRenderingEngine == .mainThread, + _backgroundBehavior == .continuePlaying + { + logger.assertionFailure(""" + `LottieBackgroundBehavior.continuePlaying` should not be used with the Main Thread + rendering engine, since this would waste CPU resources on playing an animation + that is not visible. Consider using a different background mode, or switching to + the Core Animation rendering engine (which does not have any CPU overhead). + """) + } + + return currentBackgroundBehavior + } + set { + _backgroundBehavior = newValue + } + } + + /// Sets the animation backing the animation layer. Setting this will clear the + /// layer's contents, completion blocks and current state. The new animation will + /// be loaded up and set to the beginning of its timeline. + public var animation: LottieAnimation? { + didSet { + makeAnimationLayer(usingEngine: configuration.renderingEngine) + + if let animation { + animationLoaded?(self, animation) + } + } + } + + /// A closure that is called when `self.animation` is loaded. When setting this closure, + /// it is called immediately if `self.animation` is non-nil. + /// + /// When initializing a `LottieAnimationView`, the animation will either be loaded + /// synchronously (when loading a `LottieAnimation` from a .json file on disk) + /// or asynchronously (when loading a `DotLottieFile` from disk, or downloading + /// an animation from a URL). This closure is called in both cases once the + /// animation is loaded and applied, so can be a useful way to configure this + /// `LottieAnimationView` regardless of which initializer was used. For example: + /// + /// ``` + /// let animationView: LottieAnimationView + /// + /// if loadDotLottieFile { + /// // Loads the .lottie file asynchronously + /// animationView = LottieAnimationView(dotLottieName: "animation") + /// } else { + /// // Loads the .json file synchronously + /// animationView = LottieAnimationView(name: "animation") + /// } + /// + /// animationView.animationLoaded = { animationView, animation in + /// // If using a .lottie file, this is called once the file finishes loading. + /// // If using a .json file, this is called immediately (since the animation is loaded synchronously). + /// animationView.play() + /// } + /// ``` + public var animationLoaded: ((_ animationLayer: LottieAnimationLayer, _ animation: LottieAnimation) -> Void)? { + didSet { + if let animation { + animationLoaded?(self, animation) + } + } + } + + /// Sets the image provider for the animation layer. An image provider provides the + /// animation with its required image data. + /// + /// Setting this will cause the animation to reload its image contents. + public var imageProvider: AnimationImageProvider { + didSet { + rootAnimationLayer?.imageProvider = imageProvider.cachedImageProvider + reloadImages() + } + } + + /// Sets the text provider for animation layer. A text provider provides the + /// animation with values for text layers + public var textProvider: AnimationKeypathTextProvider { + didSet { + rootAnimationLayer?.textProvider = textProvider + } + } + + /// Sets the text provider for animation layer. A text provider provides the + /// animation with values for text layers + public var fontProvider: AnimationFontProvider { + didSet { + rootAnimationLayer?.fontProvider = fontProvider + } + } + + /// Whether or not the animation is masked to the bounds. Defaults to true. + public var maskAnimationToBounds = true { + didSet { + animationLayer?.masksToBounds = maskAnimationToBounds + } + } + + /// Returns `true` if the animation is currently playing. + public var isAnimationPlaying: Bool { + guard let animationLayer = rootAnimationLayer else { + return false + } + + if let valueFromLayer = animationLayer.isAnimationPlaying { + return valueFromLayer + } else { + return animationLayer.animation(forKey: activeAnimationName) != nil + } + } + + /// Sets the loop behavior for `play` calls. Defaults to `playOnce` + public var loopMode: LottieLoopMode = .playOnce { + didSet { + updateInFlightAnimation() + } + } + + /// When `true` the animation layer will rasterize its contents when not animating. + /// Rasterizing will improve performance of static animations. + /// + /// Note: this will not produce crisp results at resolutions above the animations natural resolution. + /// + /// Defaults to `false` + public var shouldRasterizeWhenIdle = false { + didSet { + updateRasterizationState() + } + } + + /// Sets the current animation time with a Progress Time + /// + /// Note: Setting this will stop the current animation, if any. + /// Note 2: If `animation` is nil, setting this will fallback to 0 + public var currentProgress: AnimationProgressTime { + set { + if let animation { + currentFrame = animation.frameTime(forProgress: newValue) + currentPlaybackMode = .paused(at: .progress(newValue)) + } else { + currentFrame = 0 + } + } + get { + if let animation { + return animation.progressTime(forFrame: currentFrame) + } else { + return 0 + } + } + } + + /// Sets the current animation time with a time in seconds. + /// + /// Note: Setting this will stop the current animation, if any. + /// Note 2: If `animation` is nil, setting this will fallback to 0 + public var currentTime: TimeInterval { + set { + if let animation { + currentFrame = animation.frameTime(forTime: newValue) + currentPlaybackMode = .paused(at: .time(newValue)) + } else { + currentFrame = 0 + } + } + get { + if let animation { + return animation.time(forFrame: currentFrame) + } else { + return 0 + } + } + } + + /// Sets the current animation time with a frame in the animations framerate. + /// + /// Note: Setting this will stop the current animation, if any. + public var currentFrame: AnimationFrameTime { + set { + removeCurrentAnimationIfNecessary() + updateAnimationFrame(newValue) + currentPlaybackMode = .paused(at: .frame(currentFrame)) + } + get { + rootAnimationLayer?.currentFrame ?? 0 + } + } + + /// Returns the current animation frame while an animation is playing. + public var realtimeAnimationFrame: AnimationFrameTime { + isAnimationPlaying ? rootAnimationLayer?.presentation()?.currentFrame ?? currentFrame : currentFrame + } + + /// Returns the current animation frame while an animation is playing. + public var realtimeAnimationProgress: AnimationProgressTime { + if let animation { + return animation.progressTime(forFrame: realtimeAnimationFrame) + } + return 0 + } + + /// Sets the speed of the animation playback. Defaults to 1 + public var animationSpeed: CGFloat = 1 { + didSet { + updateInFlightAnimation() + } + } + + /// When `true` the animation will play back at the framerate encoded in the + /// `LottieAnimation` model. When `false` the animation will play at the framerate + /// of the device. + /// + /// Defaults to false + public var respectAnimationFrameRate = false { + didSet { + rootAnimationLayer?.respectAnimationFrameRate = respectAnimationFrameRate + } + } + + /// The rendering engine currently being used by this layer. + /// - This will only be `nil` in cases where the configuration is `automatic` + /// but a `RootAnimationLayer` hasn't been constructed yet + public var currentRenderingEngine: RenderingEngine? { + switch configuration.renderingEngine { + case .specific(let engine): + return engine + + case .automatic: + guard let animationLayer else { + return nil + } + + if animationLayer is CoreAnimationLayer { + return .coreAnimation + } else { + return .mainThread + } + } + } + + /// Whether or not the Main Thread rendering engine should use `forceDisplayUpdate()` + /// when rendering each individual frame. + /// - The main thread rendering engine implements optimizations to decrease the amount + /// of properties that have to be re-rendered on each frame. There are some cases + /// where this can result in bugs / incorrect behavior, so we allow it to be disabled. + /// - Forcing a full render on every frame will decrease performance, and is not recommended + /// except as a workaround to a bug in the main thread rendering engine. + /// - Has no effect when using the Core Animation rendering engine. + public var mainThreadRenderingEngineShouldForceDisplayUpdateOnEachFrame = false { + didSet { + (rootAnimationLayer as? MainThreadAnimationLayer)?.forceDisplayUpdateOnEachFrame + = mainThreadRenderingEngineShouldForceDisplayUpdateOnEachFrame + } + } + + /// Sets the lottie file backing the animation layer. Setting this will clear the + /// layer's contents, completion blocks and current state. The new animation will + /// be loaded up and set to the beginning of its timeline. + /// The loopMode, animationSpeed and imageProvider will be set according + /// to lottie file settings + /// - Parameters: + /// - animationId: Internal animation id to play. Optional + /// Defaults to play first animation in file. + /// - dotLottieFile: Lottie file to play + public func loadAnimation( + _ animationId: String? = nil, + from dotLottieFile: DotLottieFile) + { + guard let dotLottieAnimation = dotLottieFile.animation(for: animationId) else { return } + loadAnimation(dotLottieAnimation) + } + + /// Sets the lottie file backing the animation layer. Setting this will clear the + /// layer's contents, completion blocks and current state. The new animation will + /// be loaded up and set to the beginning of its timeline. + /// The loopMode, animationSpeed and imageProvider will be set according + /// to lottie file settings + /// - Parameters: + /// - atIndex: Internal animation index to play. + /// Defaults to play first animation in file. + /// - dotLottieFile: Lottie file to play + public func loadAnimation( + atIndex index: Int, + from dotLottieFile: DotLottieFile) + { + guard let dotLottieAnimation = dotLottieFile.animation(at: index) else { return } + loadAnimation(dotLottieAnimation) + } + + /// Reloads the images supplied to the animation from the `imageProvider` + public func reloadImages() { + rootAnimationLayer?.reloadImages() + } + + /// Forces the LottieAnimationView to redraw its contents. + public func forceDisplayUpdate() { + rootAnimationLayer?.forceDisplayUpdate() + } + + /// Sets a ValueProvider for the specified keypath. The value provider will be set + /// on all properties that match the keypath. + /// + /// Nearly all properties of a Lottie animation can be changed at runtime using a + /// combination of `Animation Keypaths` and `Value Providers`. + /// Setting a ValueProvider on a keypath will cause the animation to update its + /// contents and read the new Value Provider. + /// + /// A value provider provides a typed value on a frame by frame basis. + /// + /// - Parameter valueProvider: The new value provider for the properties. + /// - Parameter keypath: The keypath used to search for properties. + /// + /// Example: + /// ``` + /// /// A keypath that finds the color value for all `Fill 1` nodes. + /// let fillKeypath = AnimationKeypath(keypath: "**.Fill 1.Color") + /// /// A Color Value provider that returns a reddish color. + /// let redValueProvider = ColorValueProvider(Color(r: 1, g: 0.2, b: 0.3, a: 1)) + /// /// Set the provider on the animationView. + /// animationView.setValueProvider(redValueProvider, keypath: fillKeypath) + /// ``` + public func setValueProvider(_ valueProvider: AnyValueProvider, keypath: AnimationKeypath) { + guard let animationLayer = rootAnimationLayer else { return } + + valueProviders[keypath] = valueProvider + animationLayer.setValueProvider(valueProvider, keypath: keypath) + } + + /// Reads the value of a property specified by the Keypath. + /// Returns nil if no property is found. + /// + /// - Parameter for: The keypath used to search for the property. + /// - Parameter atFrame: The Frame Time of the value to query. If nil then the current frame is used. + public func getValue(for keypath: AnimationKeypath, atFrame: AnimationFrameTime?) -> Any? { + rootAnimationLayer?.getValue(for: keypath, atFrame: atFrame) + } + + /// Reads the original value of a property specified by the Keypath. + /// This will ignore any value providers and can be useful when implementing a value providers that makes change to the original value from the animation. + /// Returns nil if no property is found. + /// + /// - Parameter for: The keypath used to search for the property. + /// - Parameter atFrame: The Frame Time of the value to query. If nil then the current frame is used. + public func getOriginalValue(for keypath: AnimationKeypath, atFrame: AnimationFrameTime?) -> Any? { + rootAnimationLayer?.getOriginalValue(for: keypath, atFrame: atFrame) + } + + /// Logs all child keypaths. + public func logHierarchyKeypaths() { + rootAnimationLayer?.logHierarchyKeypaths() + } + + /// Computes and returns a list of all child keypaths in the current animation. + /// The returned list is the same as the log output of `logHierarchyKeypaths()` + public func allHierarchyKeypaths() -> [String] { + rootAnimationLayer?.allHierarchyKeypaths() ?? [] + } + + /// Converts a CGRect from the LottieAnimationView's coordinate space into the + /// coordinate space of the layer found at Keypath. + /// + /// If no layer is found, nil is returned + /// + /// - Parameter rect: The CGRect to convert. + /// - Parameter toLayerAt: The keypath used to find the layer. + public func convert(_ rect: CGRect, toLayerAt keypath: AnimationKeypath?) -> CGRect? { + guard let animationLayer = rootAnimationLayer else { return nil } + guard let keypath else { + return convert(rect, to: animationLayer) + } + guard let sublayer = animationLayer.layer(for: keypath) else { + return nil + } + setNeedsLayout() + layoutIfNeeded() + forceDisplayUpdate() + return animationLayer.convert(rect, to: sublayer) + } + + /// Converts a CGPoint from the LottieAnimationView's coordinate space into the + /// coordinate space of the layer found at Keypath. + /// + /// If no layer is found, nil is returned + /// + /// - Parameter point: The CGPoint to convert. + /// - Parameter toLayerAt: The keypath used to find the layer. + public func convert(_ point: CGPoint, toLayerAt keypath: AnimationKeypath?) -> CGPoint? { + guard let animationLayer = rootAnimationLayer else { return nil } + guard let keypath else { + return convert(point, to: animationLayer) + } + guard let sublayer = animationLayer.layer(for: keypath) else { + return nil + } + setNeedsLayout() + layoutIfNeeded() + forceDisplayUpdate() + return animationLayer.convert(point, to: sublayer) + } + + /// Sets the enabled state of all animator nodes found with the keypath search. + /// This can be used to interactively enable / disable parts of the animation. + /// + /// - Parameter isEnabled: When true the animator nodes affect the rendering tree. When false the node is removed from the tree. + /// - Parameter keypath: The keypath used to find the node(s). + public func setNodeIsEnabled(isEnabled: Bool, keypath: AnimationKeypath) { + guard let animationLayer = rootAnimationLayer else { return } + let nodes = animationLayer.animatorNodes(for: keypath) + if let nodes { + for node in nodes { + node.isEnabled = isEnabled + } + forceDisplayUpdate() + } + } + + /// Markers are a way to describe a point in time by a key name. + /// + /// Markers are encoded into animation JSON. By using markers a designer can mark + /// playback points for a developer to use without having to worry about keeping + /// track of animation frames. If the animation file is updated, the developer + /// does not need to update playback code. + /// + /// Returns the Progress Time for the marker named. Returns nil if no marker found. + public func progressTime(forMarker named: String) -> AnimationProgressTime? { + guard let animation else { + return nil + } + return animation.progressTime(forMarker: named) + } + + /// Markers are a way to describe a point in time by a key name. + /// + /// Markers are encoded into animation JSON. By using markers a designer can mark + /// playback points for a developer to use without having to worry about keeping + /// track of animation frames. If the animation file is updated, the developer + /// does not need to update playback code. + /// + /// Returns the Frame Time for the marker named. Returns nil if no marker found. + public func frameTime(forMarker named: String) -> AnimationFrameTime? { + guard let animation else { + return nil + } + return animation.frameTime(forMarker: named) + } + + /// Markers are a way to describe a point in time and a duration by a key name. + /// + /// Markers are encoded into animation JSON. By using markers a designer can mark + /// playback points for a developer to use without having to worry about keeping + /// track of animation frames. If the animation file is updated, the developer + /// does not need to update playback code. + /// + /// - Returns: The duration frame time for the marker, or `nil` if no marker found. + public func durationFrameTime(forMarker named: String) -> AnimationFrameTime? { + guard let animation else { + return nil + } + return animation.durationFrameTime(forMarker: named) + } + + public func updateAnimationForBackgroundState() { + if let currentContext = animationContext { + switch backgroundBehavior { + case .stop: + removeCurrentAnimation() + updateAnimationFrame(currentContext.playFrom) + case .pause: + removeCurrentAnimation() + case .pauseAndRestore: + currentContext.closure.ignoreDelegate = true + removeCurrentAnimation() + /// Keep the stale context around for when the app enters the foreground. + animationContext = currentContext + case .forceFinish: + removeCurrentAnimation() + updateAnimationFrame(currentContext.playTo) + case .continuePlaying: + break + } + } + } + + public func updateAnimationForForegroundState(wasWaitingToPlayAnimation: Bool) { + if let currentContext = animationContext { + if wasWaitingToPlayAnimation { + addNewAnimationForContext(currentContext) + } else if backgroundBehavior == .pauseAndRestore { + /// Restore animation from saved state + updateInFlightAnimation() + } + } + } + + // MARK: Internal + + var rootAnimationLayer: RootAnimationLayer? = nil + + /// Context describing the animation that is currently playing in this `LottieAnimationView` + /// - When non-nil, an animation is currently playing in this layer. Otherwise, + /// the layer is paused on a specific frame. + fileprivate(set) var animationContext: AnimationContext? + + var hasAnimationContext: Bool { + animationContext != nil + } + + /// Set animation name from Interface Builder + var animationName: String? { + didSet { + animation = animationName.flatMap { + LottieAnimation.named($0, animationCache: nil) + } + } + } + + /// Updates the animation frame. Does not affect any current animations + func updateAnimationFrame(_ newFrame: CGFloat) { + // In performance tests, we have to wrap the animation layer setup + // in a `CATransaction` in order for the layers to be deallocated at + // the correct time. The `CATransaction`s in this method interfere + // with the ones managed by the performance test, and aren't actually + // necessary in a headless environment, so we disable them. + if TestHelpers.performanceTestsAreRunning { + rootAnimationLayer?.currentFrame = newFrame + rootAnimationLayer?.forceDisplayUpdate() + return + } + + CATransaction.begin() + CATransaction.setCompletionBlock { + self.rootAnimationLayer?.forceDisplayUpdate() + } + CATransaction.setDisableActions(true) + rootAnimationLayer?.currentFrame = newFrame + CATransaction.commit() + } + + /// Updates an in flight animation. + func updateInFlightAnimation() { + guard let animationContext else { return } + + guard animationContext.closure.animationState != .complete else { + // Tried to re-add an already completed animation. Cancel. + self.animationContext = nil + return + } + + /// Tell existing context to ignore its closure + animationContext.closure.ignoreDelegate = true + + /// Make a new context, stealing the completion block from the previous. + let newContext = AnimationContext( + playFrom: animationContext.playFrom, + playTo: animationContext.playTo, + closure: animationContext.closure.completionBlock) + + /// Remove current animation, and freeze the current frame. + let pauseFrame = realtimeAnimationFrame + rootAnimationLayer?.removeAnimation(forKey: activeAnimationName) + rootAnimationLayer?.currentFrame = pauseFrame + + addNewAnimationForContext(newContext) + } + + func updateRasterizationState() { + if isAnimationPlaying { + animationLayer?.shouldRasterize = false + } else { + animationLayer?.shouldRasterize = shouldRasterizeWhenIdle + } + } + + func loadAnimation(_ animationSource: LottieAnimationSource?) { + switch animationSource { + case .lottieAnimation(let animation): + self.animation = animation + case .dotLottieFile(let dotLottieFile): + loadAnimation(from: dotLottieFile) + case nil: + animation = nil + } + } + + // MARK: Fileprivate + + fileprivate var _activeAnimationName: String = LottieAnimationLayer.animationName + fileprivate var animationID = 0 + + fileprivate var activeAnimationName: String { + switch rootAnimationLayer?.primaryAnimationKey { + case .specific(let animationKey): + return animationKey + case .managed, nil: + return _activeAnimationName + } + } + + /// Stops the current in flight animation and freezes the animation in its current state. + fileprivate func removeCurrentAnimation() { + guard animationContext != nil else { return } + let pauseFrame = realtimeAnimationFrame + animationLayer?.removeAnimation(forKey: activeAnimationName) + updateAnimationFrame(pauseFrame) + animationContext = nil + } + + fileprivate func makeAnimationLayer(usingEngine renderingEngine: RenderingEngineOption) { + /// Disable the default implicit crossfade animation Core Animation creates + /// when adding or removing sublayers. + actions = ["sublayers": NSNull()] + + /// Remove current animation if any + removeCurrentAnimation() + + if let oldAnimation = animationLayer { + oldAnimation.removeFromSuperlayer() + rootAnimationLayer = nil + } + + guard let animation else { + return + } + let rootAnimationLayer: RootAnimationLayer? + switch renderingEngine { + case .automatic: + rootAnimationLayer = makeAutomaticEngineLayer(for: animation) + case .specific(.coreAnimation): + rootAnimationLayer = makeCoreAnimationLayer(for: animation) + case .specific(.mainThread): + rootAnimationLayer = makeMainThreadAnimationLayer(for: animation) + } + + guard let animationLayer = rootAnimationLayer else { + return + } + + animationLayer.lottieAnimationLayer = self + + for (keypath, valueProvider) in valueProviders { + animationLayer.setValueProvider(valueProvider, keypath: keypath) + } + + animationLayerDidLoad?(self, renderingEngine) + + animationLayer.renderScale = screenScale + + addSublayer(animationLayer) + self.rootAnimationLayer = animationLayer + reloadImages() + animationLayer.setNeedsDisplay() + setNeedsLayout() + currentFrame = CGFloat(animation.startFrame) + } + + fileprivate func makeMainThreadAnimationLayer(for animation: LottieAnimation) -> MainThreadAnimationLayer { + let mainThreadAnimationLayer = MainThreadAnimationLayer( + animation: animation, + imageProvider: imageProvider.cachedImageProvider, + textProvider: textProvider, + fontProvider: fontProvider, + maskAnimationToBounds: maskAnimationToBounds, + logger: logger) + + mainThreadAnimationLayer.forceDisplayUpdateOnEachFrame = mainThreadRenderingEngineShouldForceDisplayUpdateOnEachFrame + return mainThreadAnimationLayer + } + + fileprivate func makeCoreAnimationLayer(for animation: LottieAnimation) -> CoreAnimationLayer? { + do { + let coreAnimationLayer = try CoreAnimationLayer( + animation: animation, + imageProvider: imageProvider.cachedImageProvider, + textProvider: textProvider, + fontProvider: fontProvider, + maskAnimationToBounds: maskAnimationToBounds, + compatibilityTrackerMode: .track, + logger: logger) + + coreAnimationLayer.didSetUpAnimation = { [logger] compatibilityIssues in + logger.assert( + compatibilityIssues.isEmpty, + "Encountered Core Animation compatibility issues while setting up animation:\n" + + compatibilityIssues.map { $0.description }.joined(separator: "\n") + "\n\n" + + """ + This animation cannot be rendered correctly by the Core Animation engine. + To resolve this issue, you can use `RenderingEngineOption.automatic`, which automatically falls back + to the Main Thread rendering engine when necessary, or just use `RenderingEngineOption.mainThread`. + + """) + } + + return coreAnimationLayer + } catch { + // This should never happen, because we initialize the `CoreAnimationLayer` with + // `CompatibilityTracker.Mode.track` (which reports errors in `didSetUpAnimation`, + // not by throwing). + logger.assertionFailure("Encountered unexpected error \(error)") + return nil + } + } + + fileprivate func makeAutomaticEngineLayer(for animation: LottieAnimation) -> CoreAnimationLayer? { + do { + // Attempt to set up the Core Animation layer. This can either throw immediately in `init`, + // or throw an error later in `CALayer.display()` that will be reported in `didSetUpAnimation`. + let coreAnimationLayer = try CoreAnimationLayer( + animation: animation, + imageProvider: imageProvider.cachedImageProvider, + textProvider: textProvider, + fontProvider: fontProvider, + maskAnimationToBounds: maskAnimationToBounds, + compatibilityTrackerMode: .abort, + logger: logger) + + coreAnimationLayer.didSetUpAnimation = { [weak self] issues in + self?.automaticEngineLayerDidSetUpAnimation(issues) + } + + return coreAnimationLayer + } catch { + if case CompatibilityTracker.Error.encounteredCompatibilityIssue(let compatibilityIssue) = error { + automaticEngineLayerDidSetUpAnimation([compatibilityIssue]) + } else { + // This should never happen, because we expect `CoreAnimationLayer` to only throw + // `CompatibilityTracker.Error.encounteredCompatibilityIssue` errors. + logger.assertionFailure("Encountered unexpected error \(error)") + automaticEngineLayerDidSetUpAnimation([]) + } + + return nil + } + } + + // Handles any compatibility issues with the Core Animation engine + // by falling back to the Main Thread engine + fileprivate func automaticEngineLayerDidSetUpAnimation(_ compatibilityIssues: [CompatibilityIssue]) { + // If there weren't any compatibility issues, then there's nothing else to do + if compatibilityIssues.isEmpty { + return + } + + logger.warn( + "Encountered Core Animation compatibility issue while setting up animation:\n" + + compatibilityIssues.map { $0.description }.joined(separator: "\n") + "\n" + + """ + This animation may have additional compatibility issues, but animation setup was cancelled early to avoid wasted work. + + Automatically falling back to Main Thread rendering engine. This fallback comes with some additional performance + overhead, which can be reduced by manually specifying that this animation should always use the Main Thread engine. + + """) + + let animationContext = animationContext + let currentFrame = currentFrame + + // Disable the completion handler delegate before tearing down the `CoreAnimationLayer` + // and building the `MainThreadAnimationLayer`. Otherwise deinitializing the + // `CoreAnimationLayer` would trigger the animation completion handler even though + // the animation hasn't even started playing yet. + animationContext?.closure.ignoreDelegate = true + + makeAnimationLayer(usingEngine: .mainThread) + + // Set up the Main Thread animation layer using the same configuration that + // was being used by the previous Core Animation layer + self.currentFrame = currentFrame + + if let animationContext { + // `AnimationContext.closure` (`AnimationCompletionDelegate`) is a reference type + // that is the animation layer's `CAAnimationDelegate`, and holds a reference to + // the animation layer. Reusing a single instance across different animation layers + // can cause the animation setup to fail, so we create a copy of the `animationContext`: + addNewAnimationForContext(AnimationContext( + playFrom: animationContext.playFrom, + playTo: animationContext.playTo, + closure: animationContext.closure.completionBlock)) + } + } + + /// Removes the current animation and pauses the animation at the current frame + /// if necessary before setting up a new animation. + /// - This is not necessary with the Core Animation engine, and skipping + /// this step lets us avoid building the animations twice (once paused + /// and once again playing) + /// - This method should only be called immediately before setting up another + /// animation -- otherwise this LottieAnimationView could be put in an inconsistent state. + fileprivate func removeCurrentAnimationIfNecessary() { + switch currentRenderingEngine { + case .mainThread: + removeCurrentAnimation() + case .coreAnimation, nil: + // We still need to remove the `animationContext`, since it should only be present + // when an animation is actually playing. Without this calling `removeCurrentAnimationIfNecessary()` + // and then setting the animation to a specific paused frame would put this + // `LottieAnimationView` in an inconsistent state. + animationContext = nil + } + } + + /// Adds animation to animation layer and sets the delegate. If animation layer or animation are nil, exits. + fileprivate func addNewAnimationForContext(_ animationContext: AnimationContext) { + guard let animationlayer = rootAnimationLayer, let animation else { + return + } + + self.animationContext = animationContext + + animationID = animationID + 1 + _activeAnimationName = LottieAnimationLayer.animationName + String(animationID) + + if let coreAnimationLayer = animationlayer as? CoreAnimationLayer { + var animationContext = animationContext + + // Core Animation doesn't natively support negative speed values, + // so instead we can swap `playFrom` / `playTo` + if animationSpeed < 0 { + let temp = animationContext.playFrom + animationContext.playFrom = animationContext.playTo + animationContext.playTo = temp + } + + var timingConfiguration = CoreAnimationLayer.CAMediaTimingConfiguration( + autoreverses: loopMode.caAnimationConfiguration.autoreverses, + repeatCount: loopMode.caAnimationConfiguration.repeatCount, + speed: abs(Float(animationSpeed))) + + // The animation should start playing from the `currentFrame`, + // if `currentFrame` is included in the time range being played. + let lowerBoundTime = min(animationContext.playFrom, animationContext.playTo) + let upperBoundTime = max(animationContext.playFrom, animationContext.playTo) + if (lowerBoundTime ..< upperBoundTime).contains(round(currentFrame)) { + // We have to configure this differently depending on the loop mode: + switch loopMode { + // When playing exactly once (and not looping), we can just set the + // `playFrom` time to be the `currentFrame`. Since the animation duration + // is based on `playFrom` and `playTo`, this automatically truncates the + // duration (so the animation stops playing at `playFrom`). + // - Don't do this if the animation is already at that frame + // (e.g. playing from 100% to 0% when the animation is already at 0%) + // since that would cause the animation to not play at all. + case .playOnce: + if animationContext.playTo != currentFrame { + animationContext.playFrom = currentFrame + } + + // When looping, we specifically _don't_ want to affect the duration of the animation, + // since that would affect the duration of all subsequent loops. We just want to adjust + // the duration of the _first_ loop. Instead of setting `playFrom`, we just add a `timeOffset` + // so the first loop begins at `currentTime` but all subsequent loops are the standard duration. + default: + if animationSpeed < 0 { + timingConfiguration.timeOffset = animation.time(forFrame: animationContext.playFrom) - currentTime + } else { + timingConfiguration.timeOffset = currentTime - animation.time(forFrame: animationContext.playFrom) + } + } + } + + // If attempting to play a zero-duration animation, just pause on that single frame instead + if animationContext.playFrom == animationContext.playTo { + currentFrame = animationContext.playTo + animationContext.closure.completionBlock?(true) + return + } + + coreAnimationLayer.playAnimation(configuration: .init( + animationContext: animationContext, + timingConfiguration: timingConfiguration)) + + return + } + + /// At this point there is no animation on animationLayer and its state is set. + + let framerate = animation.framerate + + let playFrom = animationContext.playFrom.clamp(animation.startFrame, animation.endFrame) + let playTo = animationContext.playTo.clamp(animation.startFrame, animation.endFrame) + + let duration = ((max(playFrom, playTo) - min(playFrom, playTo)) / CGFloat(framerate)) + + let playingForward: Bool = + ( + (animationSpeed > 0 && playFrom < playTo) || + (animationSpeed < 0 && playTo < playFrom)) + + var startFrame = currentFrame.clamp(min(playFrom, playTo), max(playFrom, playTo)) + if startFrame == playTo { + startFrame = playFrom + } + + let timeOffset: TimeInterval = playingForward + ? Double(startFrame - min(playFrom, playTo)) / framerate + : Double(max(playFrom, playTo) - startFrame) / framerate + + let layerAnimation = CABasicAnimation(keyPath: "currentFrame") + layerAnimation.fromValue = playFrom + layerAnimation.toValue = playTo + layerAnimation.speed = Float(animationSpeed) + layerAnimation.duration = TimeInterval(duration) + layerAnimation.fillMode = CAMediaTimingFillMode.both + layerAnimation.repeatCount = loopMode.caAnimationConfiguration.repeatCount + layerAnimation.autoreverses = loopMode.caAnimationConfiguration.autoreverses + + layerAnimation.isRemovedOnCompletion = false + if timeOffset != 0 { + let currentLayerTime = convertTime(CACurrentMediaTime(), from: nil) + layerAnimation.beginTime = currentLayerTime - (timeOffset * 1 / Double(abs(animationSpeed))) + } + layerAnimation.delegate = animationContext.closure + animationContext.closure.animationLayer = animationlayer + animationContext.closure.animationKey = activeAnimationName + + animationlayer.add(layerAnimation, forKey: activeAnimationName) + updateRasterizationState() + } + + // MARK: Private + + static private let animationName = "Lottie" + + private let logger: LottieLogger + + /// The `LottieBackgroundBehavior` that was specified manually by setting `self.backgroundBehavior` + private var _backgroundBehavior: LottieBackgroundBehavior? + + /// Whether or not the current animation should be overridden with + /// the marker matching the current "reduced motion" mode. + private var shouldOverrideWithReducedMotionAnimation: Bool { + reducedMotionMarker != nil + } + + /// The marker that corresponds to the current "reduced motion" mode. + private var reducedMotionMarker: Marker? { + switch configuration.reducedMotionOption.currentReducedMotionMode { + case .standardMotion: + return nil + case .reducedMotion: + return animation?.reducedMotionMarker + } + } + + private func loadAnimation(_ dotLottieAnimation: DotLottieFile.Animation) { + loopMode = dotLottieAnimation.configuration.loopMode + animationSpeed = CGFloat(dotLottieAnimation.configuration.speed) + + if let imageProvider = dotLottieAnimation.configuration.imageProvider { + self.imageProvider = imageProvider + } + + animation = dotLottieAnimation.animation + } + + /// Plays the marker that corresponds to the current "reduced motion" mode if present. + private func playReducedMotionAnimation(completion: LottieCompletionBlock?) { + guard let reducedMotionMarker else { return } + + // `play(marker:)` calls the `play(fromFrame:toFrame:)` method which calls this + // `playReducedMotionAnimation` method when `shouldOverrideWithReducedMotionAnimation` + // is `true`. To prevent infinite recursion, disable the reduced motion functionality + // until the end of this function. + let currentConfiguration = configuration + configuration.reducedMotionOption = .standardMotion + defer { configuration = currentConfiguration } + + play(marker: reducedMotionMarker.name, completion: completion) + } + +} + +// MARK: - LottieLoopMode + caAnimationConfiguration + +extension LottieLoopMode { + /// The `CAAnimation` configuration that reflects this mode + var caAnimationConfiguration: (repeatCount: Float, autoreverses: Bool) { + switch self { + case .playOnce: + return (repeatCount: 1, autoreverses: false) + case .loop: + return (repeatCount: .greatestFiniteMagnitude, autoreverses: false) + case .autoReverse: + return (repeatCount: .greatestFiniteMagnitude, autoreverses: true) + case .repeat(let amount): + return (repeatCount: amount, autoreverses: false) + case .repeatBackwards(let amount): + return (repeatCount: amount, autoreverses: true) + } + } +} diff --git a/Pods/lottie-ios/Sources/Public/Animation/LottiePlaybackMode.swift b/Pods/lottie-ios/Sources/Public/Animation/LottiePlaybackMode.swift new file mode 100644 index 00000000..dd93a95e --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Animation/LottiePlaybackMode.swift @@ -0,0 +1,260 @@ +// Created by Cal Stephens on 8/3/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +import Foundation + +// MARK: - LottiePlaybackMode + +/// Configuration for how a Lottie animation should be played +public enum LottiePlaybackMode: Hashable { + + /// The animation is paused at the given state (e.g. paused at a specific frame) + case paused(at: PausedState) + + /// The animation is playing using the given playback mode (e.g. looping from the start to the end) + case playing(_ mode: PlaybackMode) + + @available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.") + case progress(_ progress: AnimationProgressTime) + + @available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.") + case frame(_ frame: AnimationFrameTime) + + @available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.") + case time(_ time: TimeInterval) + + @available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.") + case pause + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + case fromProgress(_ fromProgress: AnimationProgressTime?, toProgress: AnimationProgressTime, loopMode: LottieLoopMode) + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + case fromFrame(_ fromFrame: AnimationFrameTime?, toFrame: AnimationFrameTime, loopMode: LottieLoopMode) + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + case fromMarker( + _ fromMarker: String?, + toMarker: String, + playEndMarkerFrame: Bool = true, + loopMode: LottieLoopMode) + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + case marker(_ marker: String, loopMode: LottieLoopMode) + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + case markers(_ markers: [String]) + + // MARK: Public + + public enum PausedState: Hashable { + /// Any existing animation will be paused at the current frame. + case currentFrame + + /// The animation is paused at the given progress value, + /// a value between 0.0 (0% progress) and 1.0 (100% progress). + case progress(_ progress: AnimationProgressTime) + + /// The animation is paused at the given frame of the animation. + case frame(_ frame: AnimationFrameTime) + + /// The animation is paused at the given time value from the start of the animation. + case time(_ time: TimeInterval) + + /// Pauses the animation at a given marker and position + case marker(_ name: String, position: LottieMarkerPosition = .start) + } + + public enum PlaybackMode: Hashable { + /// Plays the animation from a progress (0-1) to a progress (0-1). + /// - Parameter fromProgress: The start progress of the animation. If `nil` the animation will start at the current progress. + /// - Parameter toProgress: The end progress of the animation. + /// - Parameter loopMode: The loop behavior of the animation. + case fromProgress( + _ fromProgress: AnimationProgressTime?, + toProgress: AnimationProgressTime, + loopMode: LottieLoopMode) + + /// The animation plays from the given `fromFrame` to the given `toFrame`. + /// - Parameter fromFrame: The start frame of the animation. If `nil` the animation will start at the current frame. + /// - Parameter toFrame: The end frame of the animation. + /// - Parameter loopMode: The loop behavior of the animation. + case fromFrame( + _ fromFrame: AnimationFrameTime?, + toFrame: AnimationFrameTime, + loopMode: LottieLoopMode) + + /// Plays the animation from a named marker to another marker. + /// + /// Markers are point in time that are encoded into the Animation data and assigned a name. + /// + /// NOTE: If markers are not found the play command will exit. + /// + /// - Parameter fromMarker: The start marker for the animation playback. If `nil` the + /// animation will start at the current progress. + /// - Parameter toMarker: The end marker for the animation playback. + /// - Parameter playEndMarkerFrame: A flag to determine whether or not to play the frame of the end marker. If the + /// end marker represents the end of the section to play, it should be to true. If the provided end marker + /// represents the beginning of the next section, it should be false. + /// - Parameter loopMode: The loop behavior of the animation. + case fromMarker( + _ fromMarker: String?, + toMarker: String, + playEndMarkerFrame: Bool = true, + loopMode: LottieLoopMode) + + /// Plays the animation from a named marker to the end of the marker's duration. + /// + /// A marker is a point in time with an associated duration that is encoded into the + /// animation data and assigned a name. + /// + /// NOTE: If marker is not found the play command will exit. + /// + /// - Parameter marker: The start marker for the animation playback. + /// - Parameter loopMode: The loop behavior of the animation. + case marker( + _ marker: String, + loopMode: LottieLoopMode) + + /// Plays the given markers sequentially in order. + /// + /// A marker is a point in time with an associated duration that is encoded into the + /// animation data and assigned a name. Multiple markers can be played sequentially + /// to create programmable animations. + /// + /// If a marker is not found, it will be skipped. + /// + /// If a marker doesn't have a duration value, it will play with a duration of 0 + /// (effectively being skipped). + /// + /// If another animation is played (by calling any `play` method) while this + /// marker sequence is playing, the marker sequence will be cancelled. + /// + /// - Parameter markers: The list of markers to play sequentially. + case markers(_ markers: [String]) + } + +} + +extension LottiePlaybackMode { + public static var paused: Self { + .paused(at: .currentFrame) + } + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + public static func toProgress(_ toProgress: AnimationProgressTime, loopMode: LottieLoopMode) -> LottiePlaybackMode { + .playing(.fromProgress(nil, toProgress: toProgress, loopMode: loopMode)) + } + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) -> LottiePlaybackMode { + .playing(.fromFrame(nil, toFrame: toFrame, loopMode: loopMode)) + } + + @available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.") + public static func toMarker( + _ toMarker: String, + playEndMarkerFrame: Bool = true, + loopMode: LottieLoopMode) + -> LottiePlaybackMode + { + .playing(.fromMarker(nil, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: loopMode)) + } +} + +extension LottiePlaybackMode.PlaybackMode { + /// Plays the animation from the current progress to a progress value (0-1). + /// - Parameter toProgress: The end progress of the animation. + /// - Parameter loopMode: The loop behavior of the animation. + public static func toProgress(_ toProgress: AnimationProgressTime, loopMode: LottieLoopMode) -> Self { + .fromProgress(nil, toProgress: toProgress, loopMode: loopMode) + } + + // Plays the animation from the current frame to the given frame. + /// - Parameter toFrame: The end frame of the animation. + /// - Parameter loopMode: The loop behavior of the animation. + public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) -> Self { + .fromFrame(nil, toFrame: toFrame, loopMode: loopMode) + } + + /// Plays the animation from the current frame to some marker. + /// + /// Markers are point in time that are encoded into the Animation data and assigned a name. + /// + /// NOTE: If the marker isn't found the play command will exit. + /// + /// - Parameter toMarker: The end marker for the animation playback. + /// - Parameter playEndMarkerFrame: A flag to determine whether or not to play the frame of the end marker. If the + /// end marker represents the end of the section to play, it should be to true. If the provided end marker + /// represents the beginning of the next section, it should be false. + /// - Parameter loopMode: The loop behavior of the animation. + public static func toMarker( + _ toMarker: String, + playEndMarkerFrame: Bool = true, + loopMode: LottieLoopMode) + -> Self + { + .fromMarker(nil, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: loopMode) + } +} + +// MARK: - LottieMarkerPosition + +/// The position within a marker. +public enum LottieMarkerPosition: Hashable { + case start + case end +} + +extension LottiePlaybackMode { + /// Returns a copy of this `PlaybackMode` with the `LottieLoopMode` updated to the given value + func loopMode(_ updatedLoopMode: LottieLoopMode) -> LottiePlaybackMode { + switch self { + case .playing(let playbackMode): + return .playing(playbackMode.loopMode(updatedLoopMode)) + + case .fromProgress(let fromProgress, toProgress: let toProgress, _): + return .playing(.fromProgress( + fromProgress, + toProgress: toProgress, + loopMode: updatedLoopMode)) + + case .fromFrame(let fromFrame, toFrame: let toFrame, _): + return .playing(.fromFrame( + fromFrame, + toFrame: toFrame, + loopMode: updatedLoopMode)) + + case .fromMarker(let fromMarker, let toMarker, let playEndMarkerFrame, _): + return .playing(.fromMarker( + fromMarker, + toMarker: toMarker, + playEndMarkerFrame: playEndMarkerFrame, + loopMode: updatedLoopMode)) + + case .marker(let marker, _): + return .playing(.marker(marker, loopMode: updatedLoopMode)) + + case .pause, .paused, .progress(_), .time(_), .frame(_), .markers: + return self + } + } +} + +extension LottiePlaybackMode.PlaybackMode { + /// Returns a copy of this `PlaybackMode` with the `LottieLoopMode` updated to the given value + func loopMode(_ updatedLoopMode: LottieLoopMode) -> LottiePlaybackMode.PlaybackMode { + switch self { + case .fromProgress(let fromProgress, let toProgress, _): + return .fromProgress(fromProgress, toProgress: toProgress, loopMode: updatedLoopMode) + case .fromFrame(let fromFrame, let toFrame, _): + return .fromFrame(fromFrame, toFrame: toFrame, loopMode: updatedLoopMode) + case .fromMarker(let fromMarker, let toMarker, let playEndMarkerFrame, _): + return .fromMarker(fromMarker, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: updatedLoopMode) + case .marker(let marker, _): + return .marker(marker, loopMode: updatedLoopMode) + case .markers: + return self + } + } +} diff --git a/Pods/lottie-ios/Sources/Public/Animation/LottieView.swift b/Pods/lottie-ios/Sources/Public/Animation/LottieView.swift new file mode 100644 index 00000000..463c0ed5 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Animation/LottieView.swift @@ -0,0 +1,579 @@ +// Created by Bryn Bodayle on 1/20/22. +// Copyright © 2022 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +// MARK: - LottieView + +/// A wrapper which exposes Lottie's `LottieAnimationView` to SwiftUI +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +public struct LottieView: UIViewConfiguringSwiftUIView { + + // MARK: Lifecycle + + /// Creates a `LottieView` that displays the given animation + public init(animation: LottieAnimation?) where Placeholder == EmptyView { + _animationSource = State(initialValue: animation.map(LottieAnimationSource.lottieAnimation)) + placeholder = nil + } + + /// Initializes a `LottieView` with the provided `DotLottieFile` for display. + /// + /// - Important: Avoid using this initializer with the `SynchronouslyBlockingCurrentThread` APIs. + /// If decompression of a `.lottie` file is necessary, prefer using the `.init(_ loadAnimation:)` + /// initializer, which takes an asynchronous closure: + /// ``` + /// LottieView { + /// try await DotLottieFile.named(name) + /// } + /// ``` + public init(dotLottieFile: DotLottieFile?) where Placeholder == EmptyView { + _animationSource = State(initialValue: dotLottieFile.map(LottieAnimationSource.dotLottieFile)) + placeholder = nil + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `LottieAnimation`. + /// The `loadAnimation` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + public init(_ loadAnimation: @escaping () async throws -> LottieAnimation?) where Placeholder == EmptyView { + self.init(loadAnimation, placeholder: EmptyView.init) + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `LottieAnimation`. + /// The `loadAnimation` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + /// While the animation is loading, the `placeholder` view is shown in place of the `LottieAnimationView`. + public init( + _ loadAnimation: @escaping () async throws -> LottieAnimation?, + @ViewBuilder placeholder: @escaping (() -> Placeholder)) + { + self.init { + try await loadAnimation().map(LottieAnimationSource.lottieAnimation) + } placeholder: { + placeholder() + } + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `DotLottieFile`. + /// The `loadDotLottieFile` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + /// You can use the `DotLottieFile` static methods API which use Swift concurrency to load your `.lottie` files: + /// ``` + /// LottieView { + /// try await DotLottieFile.named(name) + /// } + /// ``` + public init(_ loadDotLottieFile: @escaping () async throws -> DotLottieFile?) where Placeholder == EmptyView { + self.init(loadDotLottieFile, placeholder: EmptyView.init) + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `DotLottieFile`. + /// The `loadDotLottieFile` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + /// While the animation is loading, the `placeholder` view is shown in place of the `LottieAnimationView`. + /// You can use the `DotLottieFile` static methods API which use Swift concurrency to load your `.lottie` files: + /// ``` + /// LottieView { + /// try await DotLottieFile.named(name) + /// } placeholder: { + /// LoadingView() + /// } + /// ``` + public init( + _ loadDotLottieFile: @escaping () async throws -> DotLottieFile?, + @ViewBuilder placeholder: @escaping (() -> Placeholder)) + { + self.init { + try await loadDotLottieFile().map(LottieAnimationSource.dotLottieFile) + } placeholder: { + placeholder() + } + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `LottieAnimationSource`. + /// The `loadAnimation` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + /// While the animation is loading, the `placeholder` view is shown in place of the `LottieAnimationView`. + public init(_ loadAnimation: @escaping () async throws -> LottieAnimationSource?) where Placeholder == EmptyView { + self.init(loadAnimation, placeholder: EmptyView.init) + } + + /// Creates a `LottieView` that asynchronously loads and displays the given `LottieAnimationSource`. + /// The `loadAnimation` closure is called exactly once in `onAppear`. + /// If you wish to call `loadAnimation` again at a different time, you can use `.reloadAnimationTrigger(...)`. + /// While the animation is loading, the `placeholder` view is shown in place of the `LottieAnimationView`. + public init( + _ loadAnimation: @escaping () async throws -> LottieAnimationSource?, + @ViewBuilder placeholder: @escaping () -> Placeholder) + { + self.loadAnimation = loadAnimation + self.placeholder = placeholder + _animationSource = State(initialValue: nil) + } + + // MARK: Public + + public var body: some View { + LottieAnimationView.swiftUIView { + LottieAnimationView( + animationSource: animationSource, + imageProvider: imageProviderConfiguration?.imageProvider, + textProvider: textProvider, + fontProvider: fontProvider, + configuration: configuration, + logger: logger) + } + .sizing(sizing) + .configure { context in + applyCurrentAnimationConfiguration(to: context.view) + } + .configurations(configurations) + .opacity(animationSource == nil ? 0 : 1) + .overlay { + placeholder?() + .opacity(animationSource == nil ? 1 : 0) + } + .onAppear { + loadAnimationIfNecessary() + } + .valueChanged(value: reloadAnimationTrigger) { _ in + reloadAnimationTriggerDidChange() + } + } + + /// Returns a copy of this `LottieView` updated to have the given closure applied to its + /// represented `LottieAnimationView` whenever it is updated via the `updateUIView(…)` + /// or `updateNSView(…)` method. + public func configure(_ configure: @escaping (LottieAnimationView) -> Void) -> Self { + var copy = self + copy.configurations.append { context in + configure(context.view) + } + return copy + } + + /// Returns a copy of this view that can be resized by scaling its animation to fit the size + /// offered by its parent. + public func resizable() -> Self { + var copy = self + copy.sizing = .proposed + return copy + } + + @available(*, deprecated, renamed: "playing()", message: "Will be removed in a future major release.") + public func play() -> Self { + playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce))) + } + + /// Returns a copy of this view that loops its animation from the start to end whenever visible + public func looping() -> Self { + playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop))) + } + + @available(*, deprecated, renamed: "playing(_:)", message: "Will be removed in a future major release.") + public func play(loopMode: LottieLoopMode = .playOnce) -> Self { + playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode))) + } + + @available(*, deprecated, renamed: "playbackMode(_:)", message: "Will be removed in a future major release.") + public func play(_ playbackMode: LottiePlaybackMode) -> Self { + self.playbackMode(playbackMode) + } + + /// Returns a copy of this view playing with the given playback mode + public func playing(_ mode: LottiePlaybackMode.PlaybackMode) -> Self { + playbackMode(.playing(mode)) + } + + /// Returns a copy of this view playing from the current frame to the end frame, + /// with the given `LottiePlaybackMode`. + public func playing(loopMode: LottieLoopMode) -> Self { + playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode))) + } + + // Returns a copy of this view playing once from the current frame to the end frame + public func playing() -> Self { + playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce))) + } + + /// Returns a copy of this view paused with the given state + public func paused(at state: LottiePlaybackMode.PausedState = .currentFrame) -> Self { + playbackMode(.paused(at: state)) + } + + /// Returns a copy of this view using the given `LottiePlaybackMode` + public func playbackMode(_ playbackMode: LottiePlaybackMode) -> Self { + var copy = self + copy.playbackMode = playbackMode + return copy + } + + /// Returns a copy of this view playing its animation at the given speed + public func animationSpeed(_ animationSpeed: Double) -> Self { + var copy = self + copy.animationSpeed = animationSpeed + return copy + } + + /// Returns a copy of this view with the given closure that is called whenever the + /// `LottieAnimationSource` provided via `init` is loaded and applied to the underlying `LottieAnimationView`. + public func animationDidLoad(_ animationDidLoad: @escaping (LottieAnimationSource) -> Void) -> Self { + var copy = self + copy.animationDidLoad = animationDidLoad + return copy + } + + /// Returns a copy of this view with the given `LottieCompletionBlock` that is called + /// when an animation finishes playing. + public func animationDidFinish(_ animationCompletionHandler: LottieCompletionBlock?) -> Self { + var copy = self + copy.animationCompletionHandler = { [previousCompletionHandler = self.animationCompletionHandler] completed in + previousCompletionHandler?(completed) + animationCompletionHandler?(completed) + } + return copy + } + + /// Returns a copy of this view updated to have the provided background behavior. + public func backgroundBehavior(_ value: LottieBackgroundBehavior) -> Self { + configure { view in + view.backgroundBehavior = value + } + } + + /// Returns a copy of this view with its accessibility label updated to the given value. + public func accessibilityLabel(_ accessibilityLabel: String?) -> Self { + configure { view in + #if os(macOS) + view.setAccessibilityElement(accessibilityLabel != nil) + view.setAccessibilityLabel(accessibilityLabel) + #else + view.isAccessibilityElement = accessibilityLabel != nil + view.accessibilityLabel = accessibilityLabel + #endif + } + } + + /// Returns a copy of this view with its `LottieConfiguration` updated to the given value. + public func configuration(_ configuration: LottieConfiguration) -> Self { + var copy = self + copy.configuration = configuration + + copy = copy.configure { view in + if view.configuration != configuration { + view.configuration = configuration + } + } + + return copy + } + + /// Returns a copy of this view with its `LottieLogger` updated to the given value. + /// - The underlying `LottieAnimationView`'s `LottieLogger` is immutable after configured, + /// so this value is only used when initializing the `LottieAnimationView` for the first time. + public func logger(_ logger: LottieLogger) -> Self { + var copy = self + copy.logger = logger + return copy + } + + /// Returns a copy of this view with its image provider updated to the given value. + /// The image provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func imageProvider(_ imageProvider: ImageProvider) -> Self { + var copy = self + + copy.imageProviderConfiguration = ( + imageProvider: imageProvider, + imageProvidersAreEqual: { untypedLHS, untypedRHS in + guard + let lhs = untypedLHS as? ImageProvider, + let rhs = untypedRHS as? ImageProvider + else { return false } + + return lhs == rhs + }) + + return copy + } + + /// Returns a copy of this view with its text provider updated to the given value. + /// The image provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func textProvider(_ textProvider: TextProvider) -> Self { + var copy = self + copy.textProvider = textProvider + + copy = copy.configure { view in + if (view.textProvider as? TextProvider) != textProvider { + view.textProvider = textProvider + } + } + + return copy + } + + /// Returns a copy of this view with its image provider updated to the given value. + /// The image provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func fontProvider(_ fontProvider: FontProvider) -> Self { + var copy = self + copy.fontProvider = fontProvider + + copy = configure { view in + if (view.fontProvider as? FontProvider) != fontProvider { + view.fontProvider = fontProvider + } + } + + return copy + } + + /// Returns a copy of this view using the given value provider for the given keypath. + /// The value provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func valueProvider( + _ valueProvider: ValueProvider, + for keypath: AnimationKeypath) + -> Self + { + configure { view in + if (view.valueProviders[keypath] as? ValueProvider) != valueProvider { + view.setValueProvider(valueProvider, keypath: keypath) + } + } + } + + /// Returns a copy of this view updated to display the given `AnimationProgressTime`. + /// - If the `currentProgress` value is provided, the `currentProgress` of the + /// underlying `LottieAnimationView` is updated. This will pause any existing animations. + /// - If the `animationProgress` is `nil`, no changes will be made and any existing animations + /// will continue playing uninterrupted. + public func currentProgress(_ currentProgress: AnimationProgressTime?) -> Self { + guard let currentProgress else { return self } + var copy = self + copy.playbackMode = .paused(at: .progress(currentProgress)) + return copy + } + + /// Returns a copy of this view updated to display the given `AnimationFrameTime`. + /// - If the `currentFrame` value is provided, the `currentFrame` of the + /// underlying `LottieAnimationView` is updated. This will pause any existing animations. + /// - If the `currentFrame` is `nil`, no changes will be made and any existing animations + /// will continue playing uninterrupted. + public func currentFrame(_ currentFrame: AnimationFrameTime?) -> Self { + guard let currentFrame else { return self } + var copy = self + copy.playbackMode = .paused(at: .frame(currentFrame)) + return copy + } + + /// Returns a copy of this view updated to display the given time value. + /// - If the `currentTime` value is provided, the `currentTime` of the + /// underlying `LottieAnimationView` is updated. This will pause any existing animations. + /// - If the `currentTime` is `nil`, no changes will be made and any existing animations + /// will continue playing uninterrupted. + public func currentTime(_ currentTime: TimeInterval?) -> Self { + guard let currentTime else { return self } + var copy = self + copy.playbackMode = .paused(at: .time(currentTime)) + return copy + } + + /// Returns a new instance of this view, which will invoke the provided `loadAnimation` closure + /// whenever the `binding` value is updated. + /// + /// - Note: This function requires a valid `loadAnimation` closure provided during view initialization, + /// otherwise `reloadAnimationTrigger` will have no effect. + /// - Parameters: + /// - binding: The binding that triggers the reloading when its value changes. + /// - showPlaceholder: When `true`, the current animation will be removed before invoking `loadAnimation`, + /// displaying the `Placeholder` until the new animation loads. + /// When `false`, the previous animation remains visible while the new one loads. + public func reloadAnimationTrigger(_ value: some Equatable, showPlaceholder: Bool = true) -> Self { + var copy = self + copy.reloadAnimationTrigger = AnyEquatable(value) + copy.showPlaceholderWhileReloading = showPlaceholder + return copy + } + + /// Returns a view that updates the given binding each frame with the animation's `realtimeAnimationProgress`. + /// The `LottieView` is wrapped in a `TimelineView` with the `.animation` schedule. + /// - This is a one-way binding. Its value is updated but never read. + /// - If provided, the binding will be updated each frame with the `realtimeAnimationProgress` + /// of the underlying `LottieAnimationView`. This is potentially expensive since it triggers + /// a state update every frame. + /// - If the binding is `nil`, the `TimelineView` will be paused and no updates will occur to the binding. + @available(iOS 15.0, tvOS 15.0, macOS 12.0, *) + public func getRealtimeAnimationProgress(_ realtimeAnimationProgress: Binding?) -> some View { + TimelineView(.animation(paused: realtimeAnimationProgress == nil)) { _ in + configure { view in + if let realtimeAnimationProgress { + DispatchQueue.main.async { + realtimeAnimationProgress.wrappedValue = view.realtimeAnimationProgress + } + } + } + } + } + + /// Returns a view that updates the given binding each frame with the animation's `realtimeAnimationProgress`. + /// The `LottieView` is wrapped in a `TimelineView` with the `.animation` schedule. + /// - This is a one-way binding. Its value is updated but never read. + /// - If provided, the binding will be updated each frame with the `realtimeAnimationProgress` + /// of the underlying `LottieAnimationView`. This is potentially expensive since it triggers + /// a state update every frame. + /// - If the binding is `nil`, the `TimelineView` will be paused and no updates will occur to the binding. + @available(iOS 15.0, tvOS 15.0, macOS 12.0, *) + public func getRealtimeAnimationFrame(_ realtimeAnimationFrame: Binding?) -> some View { + TimelineView(.animation(paused: realtimeAnimationFrame == nil)) { _ in + configure { view in + if let realtimeAnimationFrame { + DispatchQueue.main.async { + realtimeAnimationFrame.wrappedValue = view.realtimeAnimationFrame + } + } + } + } + } + + /// Returns a copy of this view with the `DotLottieConfigurationComponents` + /// updated to the given value. + /// - Defaults to `[.imageProvider]` + /// - If a component is specified here, that value in the `DotLottieConfiguration` + /// of an active dotLottie animation will override any value provided via other methods. + public func dotLottieConfigurationComponents( + _ dotLottieConfigurationComponents: DotLottieConfigurationComponents) + -> Self + { + var copy = self + copy.dotLottieConfigurationComponents = dotLottieConfigurationComponents + return copy + } + + // MARK: Internal + + var configurations = [SwiftUIView.Configuration]() + + // MARK: Private + + @State private var animationSource: LottieAnimationSource? + private var playbackMode: LottiePlaybackMode? + private var animationSpeed: Double? + private var reloadAnimationTrigger: AnyEquatable? + private var loadAnimation: (() async throws -> LottieAnimationSource?)? + private var animationDidLoad: ((LottieAnimationSource) -> Void)? + private var animationCompletionHandler: LottieCompletionBlock? + private var showPlaceholderWhileReloading = false + private var textProvider: AnimationKeypathTextProvider = DefaultTextProvider() + private var fontProvider: AnimationFontProvider = DefaultFontProvider() + private var configuration: LottieConfiguration = .shared + private var dotLottieConfigurationComponents: DotLottieConfigurationComponents = .imageProvider + private var logger: LottieLogger = .shared + private var sizing = SwiftUIMeasurementContainerStrategy.automatic + private let placeholder: (() -> Placeholder)? + + private var imageProviderConfiguration: ( + imageProvider: AnimationImageProvider, + imageProvidersAreEqual: (AnimationImageProvider, AnimationImageProvider) -> Bool)? + + private func loadAnimationIfNecessary() { + guard let loadAnimation else { return } + + Task { + do { + animationSource = try await loadAnimation() + } catch { + logger.warn("Failed to load asynchronous Lottie animation with error: \(error)") + } + } + } + + private func reloadAnimationTriggerDidChange() { + guard loadAnimation != nil else { return } + + if showPlaceholderWhileReloading { + animationSource = nil + } + + loadAnimationIfNecessary() + } + + /// Applies playback configuration for the current animation to the `LottieAnimationView` + private func applyCurrentAnimationConfiguration(to view: LottieAnimationView) { + guard let animationSource else { return } + var imageProviderConfiguration = imageProviderConfiguration + var playbackMode = playbackMode + var animationSpeed = animationSpeed + + // When playing a dotLottie animation, its `DotLottieConfiguration` + // can override some behavior of the animation. + if let dotLottieConfiguration = animationSource.dotLottieAnimation?.configuration { + // Only use the value from the `DotLottieConfiguration` is that component + // is specified in the list of `dotLottieConfigurationComponents`. + if dotLottieConfigurationComponents.contains(.loopMode) { + playbackMode = playbackMode?.loopMode(dotLottieConfiguration.loopMode) + } + + if dotLottieConfigurationComponents.contains(.animationSpeed) { + animationSpeed = dotLottieConfiguration.speed + } + + if + dotLottieConfigurationComponents.contains(.imageProvider), + let dotLottieImageProvider = dotLottieConfiguration.dotLottieImageProvider + { + imageProviderConfiguration = ( + imageProvider: dotLottieImageProvider, + imageProvidersAreEqual: { untypedLHS, untypedRHS in + guard + let lhs = untypedLHS as? DotLottieImageProvider, + let rhs = untypedRHS as? DotLottieImageProvider + else { return false } + + return lhs == rhs + }) + } + } + + // We check referential equality of the animation before updating as updating the + // animation has a side-effect of rebuilding the animation layer, and it would be + // prohibitive to do so on every state update. + if animationSource.animation !== view.animation { + view.loadAnimation(animationSource) + animationDidLoad?(animationSource) + } + + if + let playbackMode, + playbackMode != view.currentPlaybackMode + { + view.setPlaybackMode(playbackMode, completion: animationCompletionHandler) + } + + if + let (imageProvider, imageProvidersAreEqual) = imageProviderConfiguration, + !imageProvidersAreEqual(imageProvider, view.imageProvider) + { + view.imageProvider = imageProvider + } + + if + let animationSpeed, + animationSpeed != view.animationSpeed + { + view.animationSpeed = animationSpeed + } + } +} + +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +extension View { + + /// The `.overlay` modifier that uses a `ViewBuilder` is available in iOS 15+, this helper function helps us to use the same API in older OSs + fileprivate func overlay( + @ViewBuilder content: () -> some View) + -> some View + { + overlay(content(), alignment: .center) + } +} + +#endif diff --git a/Pods/lottie-ios/Sources/Public/AnimationCache/DefaultAnimationCache.swift b/Pods/lottie-ios/Sources/Public/AnimationCache/DefaultAnimationCache.swift new file mode 100644 index 00000000..57f2a9b4 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/AnimationCache/DefaultAnimationCache.swift @@ -0,0 +1,67 @@ +// +// DefaultAnimationCache.swift +// Lottie +// +// Created by Marcelo Fabri on 10/18/22. +// + +import Foundation + +// MARK: - DefaultAnimationCache + +/// A thread-safe Animation Cache that will store animations up to `cacheSize`. +/// +/// Once `cacheSize` is reached, animations can be ejected. +/// The default size of the cache is 100. +/// +/// This cache implementation also responds to memory pressure. +public class DefaultAnimationCache: AnimationCacheProvider { + + // MARK: Lifecycle + + public init() { + cache.countLimit = Self.defaultCacheCountLimit + } + + // MARK: Public + + /// The global shared Cache. + public static let sharedCache = DefaultAnimationCache() + + /// The maximum number of animations that can be stored in the cache. + public var cacheSize: Int { + get { cache.countLimit } + set { cache.countLimit = newValue } + } + + /// Clears the Cache. + public func clearCache() { + cache.removeAllValues() + } + + public func animation(forKey key: String) -> LottieAnimation? { + cache.value(forKey: key) + } + + public func setAnimation(_ animation: LottieAnimation, forKey key: String) { + cache.setValue(animation, forKey: key) + } + + // MARK: Private + + private static let defaultCacheCountLimit = 100 + + /// The underlying storage of this cache. + /// - We use the `LRUCache` library instead of `NSCache`, because `NSCache` + /// clears all cached values when the app is backgrounded instead of + /// only when the app receives a memory warning notification. + private let cache = LRUCache() +} + +// MARK: Sendable + +// LottieAnimationCache has a Sendable requirement, but we can't +// redesign DefaultAnimationCache to be properly Sendable without +// making breaking changes. +// swiftlint:disable:next no_unchecked_sendable +extension DefaultAnimationCache: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Public/AnimationCache/LottieAnimationCache.swift b/Pods/lottie-ios/Sources/Public/AnimationCache/LottieAnimationCache.swift new file mode 100644 index 00000000..efb6a3ee --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/AnimationCache/LottieAnimationCache.swift @@ -0,0 +1,15 @@ +// +// LottieAnimationCache.swift +// Lottie +// +// Created by Marcelo Fabri on 10/17/22. +// + +/// A customization point to configure which `AnimationCacheProvider` will be used. +public enum LottieAnimationCache { + + /// The animation cache that will be used when loading `LottieAnimation` models. + /// Using an Animation Cache can increase performance when loading an animation multiple times. + /// Defaults to DefaultAnimationCache.sharedCache. + public static var shared: AnimationCacheProvider? = DefaultAnimationCache.sharedCache +} diff --git a/Pods/lottie-ios/Sources/Public/Configuration/DecodingStrategy.swift b/Pods/lottie-ios/Sources/Public/Configuration/DecodingStrategy.swift new file mode 100644 index 00000000..f1cfe3c4 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Configuration/DecodingStrategy.swift @@ -0,0 +1,15 @@ +// Created by Cal Stephens on 7/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +/// How animation files should be decoded +public enum DecodingStrategy: Hashable { + /// Use Codable. This is was the default strategy introduced on Lottie 3, but should be rarely + /// used as it's slower than `dictionaryBased`. Kept here for any possible compatibility issues + /// that may come up, but consider it soft-deprecated. + case legacyCodable + + /// Manually deserialize a dictionary into an Animation. + /// This should be at least 2-3x faster than using Codable and due to that + /// it's the default as of Lottie 4.x. + case dictionaryBased +} diff --git a/Pods/lottie-ios/Sources/Public/Configuration/LottieConfiguration.swift b/Pods/lottie-ios/Sources/Public/Configuration/LottieConfiguration.swift new file mode 100644 index 00000000..646ace71 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Configuration/LottieConfiguration.swift @@ -0,0 +1,47 @@ +// Created by Cal Stephens on 12/13/21. +// Copyright © 2021 Airbnb Inc. All rights reserved. + +import QuartzCore + +/// Global configuration options for Lottie animations +public struct LottieConfiguration: Hashable { + + // MARK: Lifecycle + + public init( + renderingEngine: RenderingEngineOption = .automatic, + decodingStrategy: DecodingStrategy = .dictionaryBased, + colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB(), + reducedMotionOption: ReducedMotionOption = .systemReducedMotionToggle) + { + self.renderingEngine = renderingEngine + self.decodingStrategy = decodingStrategy + self.colorSpace = colorSpace + self.reducedMotionOption = reducedMotionOption + } + + // MARK: Public + + /// The global configuration of Lottie, + /// which applies to all `LottieAnimationView`s by default. + public static var shared = LottieConfiguration() + + /// The rendering engine implementation to use when displaying an animation + /// - Defaults to `RenderingEngineOption.automatic`, which uses the + /// Core Animation rendering engine for supported animations, and + /// falls back to using the Main Thread rendering engine for + /// animations that use features not supported by the Core Animation engine. + public var renderingEngine: RenderingEngineOption + + /// The decoding implementation to use when parsing an animation JSON file + public var decodingStrategy: DecodingStrategy + + /// Options for controlling animation behavior in response to user / system "reduced motion" configuration. + /// - Defaults to `ReducedMotionOption.systemReducedMotionToggle`, which returns `.reducedMotion` + /// when the system `UIAccessibility.isReduceMotionEnabled` option is `true`. + public var reducedMotionOption: ReducedMotionOption + + /// The color space to be used for rendering + /// - Defaults to `CGColorSpaceCreateDeviceRGB()` + public var colorSpace: CGColorSpace +} diff --git a/Pods/lottie-ios/Sources/Public/Configuration/ReducedMotionOption.swift b/Pods/lottie-ios/Sources/Public/Configuration/ReducedMotionOption.swift new file mode 100644 index 00000000..0101dc9b --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Configuration/ReducedMotionOption.swift @@ -0,0 +1,114 @@ +// Created by Cal Stephens on 7/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +// MARK: - ReducedMotionOption + +/// Options for controlling animation behavior in response to user / system "reduced motion" configuration +public enum ReducedMotionOption { + /// Always use the specific given `ReducedMotionMode` value. + case specific(ReducedMotionMode) + + /// Dynamically check the given `ReducedMotionOptionProvider` each time an animation begins. + /// - Includes a Hashable `dataID` to support `ReducedMotionOption`'s `Hashable` requirement, + /// which is required due to `LottieConfiguration`'s existing `Hashable` requirement. + case dynamic(ReducedMotionOptionProvider, dataID: AnyHashable) +} + +extension ReducedMotionOption { + /// The standard behavior where Lottie animations play normally with no overrides. + /// By default this mode is used when the system "reduced motion" option is disabled. + public static var standardMotion: ReducedMotionOption { .specific(.standardMotion) } + + /// Lottie animations with a "reduced motion" marker will play that marker instead of any other animations. + /// By default this mode is used when the system "reduced motion" option is enabled. + /// - Valid marker names include "reduced motion", "reducedMotion", "reduced_motion" (case insensitive). + public static var reducedMotion: ReducedMotionOption { .specific(.reducedMotion) } + + /// A `ReducedMotionOptionProvider` that returns `.reducedMotion` when + /// the system `UIAccessibility.isReduceMotionEnabled` option is `true`. + /// This is the default option of `LottieConfiguration`. + public static var systemReducedMotionToggle: ReducedMotionOption { + .dynamic(SystemReducedMotionOptionProvider(), dataID: ObjectIdentifier(SystemReducedMotionOptionProvider.self)) + } +} + +extension ReducedMotionOption { + /// The current `ReducedMotionMode` based on the currently selected option. + public var currentReducedMotionMode: ReducedMotionMode { + switch self { + case .specific(let specificMode): + return specificMode + case .dynamic(let optionProvider, _): + return optionProvider.currentReducedMotionMode + } + } +} + +// MARK: Hashable + +extension ReducedMotionOption: Hashable { + public static func ==(_ lhs: ReducedMotionOption, _ rhs: ReducedMotionOption) -> Bool { + switch (lhs, rhs) { + case (.specific(let lhsMode), .specific(let rhsMode)): + return lhsMode == rhsMode + case (.dynamic(_, let lhsDataID), .dynamic(_, dataID: let rhsDataID)): + return lhsDataID == rhsDataID + case (.dynamic, .specific), (.specific, .dynamic): + return false + } + } + + public func hash(into hasher: inout Hasher) { + switch self { + case .specific(let mode): + hasher.combine(mode) + case .dynamic(_, let dataID): + hasher.combine(dataID) + } + } +} + +// MARK: - ReducedMotionMode + +public enum ReducedMotionMode: Hashable { + /// The default behavior where Lottie animations play normally with no overrides + /// By default this mode is used when the system "reduced motion" option is disabled. + case standardMotion + + /// Lottie animations with a "reduced motion" marker will play that marker instead of any other animations. + /// By default this mode is used when the system "reduced motion" option is enabled. + case reducedMotion +} + +// MARK: - ReducedMotionOptionProvider + +/// A type that returns a dynamic `ReducedMotionMode` which is checked when playing a Lottie animation. +public protocol ReducedMotionOptionProvider { + var currentReducedMotionMode: ReducedMotionMode { get } +} + +// MARK: - SystemReducedMotionOptionProvider + +/// A `ReducedMotionOptionProvider` that returns `.reducedMotion` when +/// the system `UIAccessibility.isReduceMotionEnabled` option is `true`. +public struct SystemReducedMotionOptionProvider: ReducedMotionOptionProvider { + public init() { } + + public var currentReducedMotionMode: ReducedMotionMode { + #if canImport(UIKit) + if UIAccessibility.isReduceMotionEnabled { + return .reducedMotion + } else { + return .standardMotion + } + #else + return .standardMotion + #endif + } +} diff --git a/Pods/lottie-ios/Sources/Public/Configuration/RenderingEngineOption.swift b/Pods/lottie-ios/Sources/Public/Configuration/RenderingEngineOption.swift new file mode 100644 index 00000000..187303d8 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Configuration/RenderingEngineOption.swift @@ -0,0 +1,113 @@ +// Created by Cal Stephens on 7/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +// MARK: - RenderingEngineOption + +public enum RenderingEngineOption: Hashable { + /// Uses the Core Animation engine for supported animations, and falls back to using + /// the Main Thread engine for animations that use features not supported by the + /// Core Animation engine. + case automatic + + /// Uses the specified rendering engine + case specific(RenderingEngine) + + // MARK: Public + + /// The Main Thread rendering engine, which supports all Lottie features + /// but runs on the main thread, which comes with some CPU overhead and + /// can cause the animation to play at a low framerate when the CPU is busy. + public static var mainThread: RenderingEngineOption { .specific(.mainThread) } + + /// The Core Animation rendering engine, that animates using Core Animation + /// and has better performance characteristics than the Main Thread engine, + /// but doesn't support all Lottie features. + /// - In general, prefer using `RenderingEngineOption.automatic` over + /// `RenderingEngineOption.coreAnimation`. The Core Animation rendering + /// engine doesn't support all features supported by the Main Thread + /// rendering engine. When using `RenderingEngineOption.automatic`, + /// Lottie will automatically fall back to the Main Thread engine + /// when necessary. + public static var coreAnimation: RenderingEngineOption { .specific(.coreAnimation) } +} + +// MARK: - RenderingEngine + +/// The rendering engine implementation to use when displaying an animation +public enum RenderingEngine: Hashable { + /// The Main Thread rendering engine, which supports all Lottie features + /// but runs on the main thread, which comes with some CPU overhead and + /// can cause the animation to play at a low framerate when the CPU is busy. + case mainThread + + /// The Core Animation rendering engine, that animates using Core Animation + /// and has better performance characteristics than the Main Thread engine, + /// but doesn't support all Lottie features. + case coreAnimation +} + +// MARK: - RenderingEngineOption + RawRepresentable, CustomStringConvertible + +extension RenderingEngineOption: RawRepresentable, CustomStringConvertible { + + // MARK: Lifecycle + + public init?(rawValue: String) { + if rawValue == "Automatic" { + self = .automatic + } else if let engine = RenderingEngine(rawValue: rawValue) { + self = .specific(engine) + } else { + return nil + } + } + + // MARK: Public + + public var rawValue: String { + switch self { + case .automatic: + return "Automatic" + case .specific(let engine): + return engine.rawValue + } + } + + public var description: String { + rawValue + } + +} + +// MARK: - RenderingEngine + RawRepresentable, CustomStringConvertible + +extension RenderingEngine: RawRepresentable, CustomStringConvertible { + + // MARK: Lifecycle + + public init?(rawValue: String) { + switch rawValue { + case "Main Thread": + self = .mainThread + case "Core Animation": + self = .coreAnimation + default: + return nil + } + } + + // MARK: Public + + public var rawValue: String { + switch self { + case .mainThread: + return "Main Thread" + case .coreAnimation: + return "Core Animation" + } + } + + public var description: String { + rawValue + } +} diff --git a/Pods/lottie-ios/Sources/Public/Controls/AnimatedButton.swift b/Pods/lottie-ios/Sources/Public/Controls/AnimatedButton.swift new file mode 100644 index 00000000..1e91c67a --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/AnimatedButton.swift @@ -0,0 +1,127 @@ +// +// AnimatedButton.swift +// lottie-swift +// +// Created by Brandon Withrow on 2/4/19. +// + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +// MARK: - AnimatedButton + +/// An interactive button that plays an animation when pressed. +open class AnimatedButton: AnimatedControl { + + // MARK: Lifecycle + + public override init( + animation: LottieAnimation?, + configuration: LottieConfiguration = .shared) + { + super.init(animation: animation, configuration: configuration) + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + } + + public override init() { + super.init() + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + } + + // MARK: Open + + #if canImport(UIKit) + open override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + let _ = super.beginTracking(touch, with: event) + let touchEvent = UIControl.Event.touchDown + if let playRange = rangesForEvents[touchEvent.id] { + animationView.play(fromProgress: playRange.from, toProgress: playRange.to, loopMode: .playOnce) + } + return true + } + + open override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + super.endTracking(touch, with: event) + let touchEvent: UIControl.Event + if let touch, bounds.contains(touch.location(in: self)) { + touchEvent = UIControl.Event.touchUpInside + performAction?() + } else { + touchEvent = UIControl.Event.touchUpOutside + } + + if let playRange = rangesForEvents[touchEvent.id] { + animationView.play(fromProgress: playRange.from, toProgress: playRange.to, loopMode: .playOnce) + } + } + + #elseif canImport(AppKit) + open override func handle(_ event: LottieNSControlEvent) { + super.handle(event) + + if let playRange = rangesForEvents[event.id] { + animationView.play(fromProgress: playRange.from, toProgress: playRange.to, loopMode: .playOnce) + } + + if event == .touchUpInside { + performAction?() + } + } + #endif + + // MARK: Public + + /// A closure that is called when the button is pressed / clicked + public var performAction: (() -> Void)? + + #if canImport(UIKit) + public override var accessibilityTraits: UIAccessibilityTraits { + set { super.accessibilityTraits = newValue } + get { super.accessibilityTraits.union(.button) } + } + #endif + + /// Sets the play range for the given UIControlEvent. + public func setPlayRange(fromProgress: AnimationProgressTime, toProgress: AnimationProgressTime, event: LottieControlEvent) { + rangesForEvents[event.id] = (from: fromProgress, to: toProgress) + } + + /// Sets the play range for the given UIControlEvent. + public func setPlayRange(fromMarker fromName: String, toMarker toName: String, event: LottieControlEvent) { + if + let start = animationView.progressTime(forMarker: fromName), + let end = animationView.progressTime(forMarker: toName) + { + rangesForEvents[event.id] = (from: start, to: end) + } + } + + // MARK: Private + + private var rangesForEvents: [AnyHashable: (from: CGFloat, to: CGFloat)] = [LottieControlEvent.touchUpInside.id: ( + from: 0, + to: 1)] +} diff --git a/Pods/lottie-ios/Sources/Public/Controls/AnimatedControl.swift b/Pods/lottie-ios/Sources/Public/Controls/AnimatedControl.swift new file mode 100644 index 00000000..ae2cdd56 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/AnimatedControl.swift @@ -0,0 +1,245 @@ +// +// AnimatedControl.swift +// lottie-swift +// +// Created by Brandon Withrow on 2/4/19. +// + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +// MARK: - AnimatedControl + +/// Lottie comes prepacked with a two Animated Controls, `AnimatedSwitch` and +/// `AnimatedButton`. Both of these controls are built on top of `AnimatedControl` +/// +/// `AnimatedControl` is a subclass of `UIControl` that provides an interactive +/// mechanism for controlling the visual state of an animation in response to +/// user actions. +/// +/// The `AnimatedControl` will show and hide layers depending on the current +/// `UIControl.State` of the control. +/// +/// Users of `AnimationControl` can set a Layer Name for each `UIControl.State`. +/// When the state is change the `AnimationControl` will change the visibility +/// of its layers. +/// +/// NOTE: Do not initialize directly. This is intended to be subclassed. +open class AnimatedControl: LottieControlType { + + // MARK: Lifecycle + + // MARK: Initializers + + public init( + animation: LottieAnimation?, + configuration: LottieConfiguration = .shared) + { + animationView = LottieAnimationView( + animation: animation, + configuration: configuration) + + super.init(frame: animation?.bounds ?? .zero) + commonInit() + } + + public init() { + animationView = LottieAnimationView() + super.init(frame: .zero) + commonInit() + } + + required public init?(coder aDecoder: NSCoder) { + animationView = LottieAnimationView() + super.init(coder: aDecoder) + commonInit() + } + + // MARK: Open + + // MARK: UIControl Overrides + + open override var isEnabled: Bool { + didSet { + updateForState() + } + } + + #if canImport(UIKit) + open override var isSelected: Bool { + didSet { + updateForState() + } + } + #endif + + open override var isHighlighted: Bool { + didSet { + updateForState() + } + } + + open override var intrinsicContentSize: CGSize { + animationView.intrinsicContentSize + } + + #if canImport(UIKit) + open override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + updateForState() + return super.beginTracking(touch, with: event) + } + + open override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + updateForState() + return super.continueTracking(touch, with: event) + } + + open override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + updateForState() + return super.endTracking(touch, with: event) + } + + open override func cancelTracking(with event: UIEvent?) { + updateForState() + super.cancelTracking(with: event) + } + + #elseif canImport(AppKit) + open override func mouseDown(with mouseDownEvent: NSEvent) { + guard let window else { return } + + currentState = .highlighted + updateForState() + handle(LottieControlEvent(mouseDownEvent.type, inside: eventIsInside(mouseDownEvent))) + + // AppKit mouse-tracking loop from: + // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html#//apple_ref/doc/uid/10000060i-CH6-SW4 + var keepOn = true + while + keepOn, + let event = window.nextEvent( + matching: .any, + until: .distantFuture, + inMode: .eventTracking, + dequeue: true) + { + if event.type == .leftMouseUp { + keepOn = false + } + + let isInside = eventIsInside(event) + handle(LottieControlEvent(event.type, inside: isInside)) + + let expectedState = (isInside && keepOn) ? LottieNSControlState.highlighted : .normal + if currentState != expectedState { + currentState = expectedState + updateForState() + } + } + } + + func handle(_: LottieNSControlEvent) { + // To be overridden in subclasses + } + + private func eventIsInside(_ event: NSEvent) -> Bool { + let mouseLocation = convert(event.locationInWindow, from: nil) + return isMousePoint(mouseLocation, in: bounds) + } + #endif + + open func animationDidSet() { } + + // MARK: Public + + /// The animation view in which the animation is rendered. + public let animationView: LottieAnimationView + + /// The animation backing the animated control. + public var animation: LottieAnimation? { + didSet { + animationView.animation = animation + animationView.bounds = animation?.bounds ?? .zero + #if canImport(UIKit) + setNeedsLayout() + #elseif canImport(AppKit) + needsLayout = true + #endif + updateForState() + animationDidSet() + } + } + + /// The speed of the animation playback. Defaults to 1 + public var animationSpeed: CGFloat { + set { animationView.animationSpeed = newValue } + get { animationView.animationSpeed } + } + + /// Sets which Animation Layer should be visible for the given state. + public func setLayer(named: String, forState: LottieControlState) { + stateMap[forState.rawValue] = named + updateForState() + } + + /// Sets a ValueProvider for the specified keypath + public func setValueProvider(_ valueProvider: AnyValueProvider, keypath: AnimationKeypath) { + animationView.setValueProvider(valueProvider, keypath: keypath) + } + + // MARK: Internal + + var stateMap: [UInt: String] = [:] + + #if canImport(UIKit) + var currentState: LottieControlState { + state + } + + #elseif canImport(AppKit) + var currentState = LottieControlState.normal + #endif + + func updateForState() { + guard let animationLayer = animationView.animationLayer else { return } + if + let layerName = stateMap[currentState.rawValue], + let stateLayer = animationLayer.layer(for: AnimationKeypath(keypath: layerName)) + { + for layer in animationLayer._animationLayers { + layer.isHidden = true + } + stateLayer.isHidden = false + } else { + for layer in animationLayer._animationLayers { + layer.isHidden = false + } + } + } + + // MARK: Private + + private func commonInit() { + #if canImport(UIKit) + animationView.clipsToBounds = false + clipsToBounds = true + #endif + + animationView.translatesAutoresizingMaskIntoConstraints = false + animationView.backgroundBehavior = .forceFinish + addSubview(animationView) + animationView.contentMode = .scaleAspectFit + + #if canImport(UIKit) + animationView.isUserInteractionEnabled = false + #endif + + animationView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + animationView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + animationView.topAnchor.constraint(equalTo: topAnchor).isActive = true + animationView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + } +} diff --git a/Pods/lottie-ios/Sources/Public/Controls/AnimatedSwitch.swift b/Pods/lottie-ios/Sources/Public/Controls/AnimatedSwitch.swift new file mode 100644 index 00000000..899e2bd8 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/AnimatedSwitch.swift @@ -0,0 +1,271 @@ +// +// AnimatedSwitch.swift +// lottie-swift +// +// Created by Brandon Withrow on 2/4/19. +// + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +// MARK: - AnimatedSwitch + +/// An interactive switch with an 'On' and 'Off' state. When the user taps on the +/// switch the state is toggled and the appropriate animation is played. +/// +/// Both the 'On' and 'Off' have an animation play range associated with their state. +/// +/// Also available as a SwiftUI view (`LottieSwitch`). +open class AnimatedSwitch: AnimatedControl { + + // MARK: Lifecycle + + public override init( + animation: LottieAnimation?, + configuration: LottieConfiguration = .shared) + { + /// Generate a haptic generator if available. + #if os(iOS) + hapticGenerator = HapticGenerator() + #else + hapticGenerator = NullHapticGenerator() + #endif + super.init(animation: animation, configuration: configuration) + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + + updateOnState(isOn: _isOn, animated: false, shouldFireHaptics: false) + } + + public override init() { + /// Generate a haptic generator if available. + #if os(iOS) + hapticGenerator = HapticGenerator() + #else + hapticGenerator = NullHapticGenerator() + #endif + + super.init() + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + + updateOnState(isOn: _isOn, animated: false, shouldFireHaptics: false) + } + + required public init?(coder aDecoder: NSCoder) { + /// Generate a haptic generator if available. + #if os(iOS) + hapticGenerator = HapticGenerator() + #else + hapticGenerator = NullHapticGenerator() + #endif + super.init(coder: aDecoder) + + #if canImport(UIKit) + isAccessibilityElement = true + #elseif canImport(AppKit) + setAccessibilityElement(true) + #endif + } + + // MARK: Open + + open override func animationDidSet() { + updateOnState(isOn: _isOn, animated: animateUpdateWhenChangingAnimation, shouldFireHaptics: false) + } + + #if canImport(UIKit) + open override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + super.endTracking(touch, with: event) + updateOnState(isOn: !_isOn, animated: true, shouldFireHaptics: true) + sendActions(for: .valueChanged) + } + + #elseif canImport(AppKit) + open override func handle(_ event: LottieNSControlEvent) { + super.handle(event) + + if event == .touchUpInside { + updateOnState(isOn: !_isOn, animated: true, shouldFireHaptics: true) + } + } + #endif + + // MARK: Public + + /// Defines what happens when the user taps the switch while an + /// animation is still in flight + public enum CancelBehavior { + case reverse // default - plays the current animation in reverse + case none // does not update the animation when canceled + } + + /// The cancel behavior for the switch. See CancelBehavior for options + public var cancelBehavior: CancelBehavior = .reverse + + /// If `false` the switch will not play the animation when changing between animations. + public var animateUpdateWhenChangingAnimation = true + + #if canImport(UIKit) + public override var accessibilityTraits: UIAccessibilityTraits { + set { super.accessibilityTraits = newValue } + get { super.accessibilityTraits.union(.button) } + } + #endif + + /// A closure that is called when the `isOn` state is updated + public var stateUpdated: ((_ isOn: Bool) -> Void)? + + /// The current state of the switch. + public var isOn: Bool { + set { + /// This is forwarded to a private variable because the animation needs to be updated without animation when set externally and with animation when set internally. + guard _isOn != newValue else { return } + updateOnState(isOn: newValue, animated: false, shouldFireHaptics: false) + } + get { + _isOn + } + } + + /// Set the state of the switch and specify animation and haptics + public func setIsOn(_ isOn: Bool, animated: Bool, shouldFireHaptics: Bool = true) { + guard isOn != _isOn else { return } + updateOnState(isOn: isOn, animated: animated, shouldFireHaptics: shouldFireHaptics) + } + + /// Sets the play range for the given state. When the switch is toggled, the animation range is played. + public func setProgressForState( + fromProgress: AnimationProgressTime, + toProgress: AnimationProgressTime, + forOnState: Bool) + { + if forOnState { + onStartProgress = fromProgress + onEndProgress = toProgress + } else { + offStartProgress = fromProgress + offEndProgress = toProgress + } + + updateOnState(isOn: _isOn, animated: false, shouldFireHaptics: false) + } + + // MARK: Internal + + private(set) var onStartProgress: CGFloat = 0 + private(set) var onEndProgress: CGFloat = 1 + private(set) var offStartProgress: CGFloat = 1 + private(set) var offEndProgress: CGFloat = 0 + + // MARK: Animation State + + func updateOnState(isOn: Bool, animated: Bool, shouldFireHaptics: Bool) { + _isOn = isOn + var startProgress = isOn ? onStartProgress : offStartProgress + var endProgress = isOn ? onEndProgress : offEndProgress + let finalProgress = endProgress + + if cancelBehavior == .reverse { + let realtimeProgress = animationView.realtimeAnimationProgress + + let previousStateStart = isOn ? offStartProgress : onStartProgress + let previousStateEnd = isOn ? offEndProgress : onEndProgress + if + realtimeProgress.isInRange( + min(previousStateStart, previousStateEnd), + max(previousStateStart, previousStateEnd)) + { + /// Animation is currently in the previous time range. Reverse the previous play. + startProgress = previousStateEnd + endProgress = previousStateStart + } + } + + updateAccessibilityLabel() + + guard animated == true else { + animationView.currentProgress = finalProgress + return + } + + if shouldFireHaptics { + hapticGenerator.generateImpact() + } + + animationView.play( + fromProgress: startProgress, + toProgress: endProgress, + loopMode: LottieLoopMode.playOnce, + completion: { [weak self] finished in + guard let self else { return } + + // For the Main Thread rendering engine, we freeze the animation at the expected final progress + // once the animation is complete. This isn't necessary on the Core Animation engine. + if finished, !(self.animationView.animationLayer is CoreAnimationLayer) { + self.animationView.currentProgress = finalProgress + } + }) + } + + // MARK: Fileprivate + + fileprivate var hapticGenerator: ImpactGenerator + + fileprivate var _isOn = false { + didSet { + stateUpdated?(_isOn) + } + } + + // MARK: Private + + private func updateAccessibilityLabel() { + let value = _isOn ? NSLocalizedString("On", comment: "On") : NSLocalizedString("Off", comment: "Off") + + #if canImport(UIKit) + accessibilityValue = value + #elseif canImport(AppKit) + setAccessibilityValue(value) + #endif + } + +} + +// MARK: - ImpactGenerator + +protocol ImpactGenerator { + func generateImpact() +} + +#if os(iOS) +class HapticGenerator: ImpactGenerator { + + // MARK: Internal + + func generateImpact() { + impact.impactOccurred() + } + + // MARK: Fileprivate + + fileprivate let impact = UIImpactFeedbackGenerator(style: .light) +} +#else +// MARK: - NullHapticGenerator + +class NullHapticGenerator: ImpactGenerator { + func generateImpact() { } +} +#endif diff --git a/Pods/lottie-ios/Sources/Public/Controls/LottieButton.swift b/Pods/lottie-ios/Sources/Public/Controls/LottieButton.swift new file mode 100644 index 00000000..577f9db4 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/LottieButton.swift @@ -0,0 +1,123 @@ +// Created by Cal Stephens on 8/14/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +/// A wrapper which exposes Lottie's `AnimatedButton` to SwiftUI +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +public struct LottieButton: UIViewConfiguringSwiftUIView { + + // MARK: Lifecycle + + public init(animation: LottieAnimation?, action: @escaping () -> Void) { + self.animation = animation + self.action = action + } + + // MARK: Public + + public var body: some View { + AnimatedButton.swiftUIView { + let button = AnimatedButton(animation: animation, configuration: configuration) + button.performAction = action + return button + } + .configure { context in + // We check referential equality of the animation before updating as updating the + // animation has a side-effect of rebuilding the animation layer, and it would be + // prohibitive to do so on every state update. + if animation !== context.view.animationView.animation { + context.view.animationView.animation = animation + } + + #if os(macOS) + // Disable the intrinsic content size constraint on the inner animation view, + // or the Epoxy `SwiftUIMeasurementContainer` won't size this view correctly. + context.view.animationView.isVerticalContentSizeConstraintActive = false + context.view.animationView.isHorizontalContentSizeConstraintActive = false + #endif + } + .configurations(configurations) + } + + /// Returns a copy of this `LottieView` updated to have the given closure applied to its + /// represented `LottieAnimationView` whenever it is updated via the `updateUIView(…)` + /// or `updateNSView(…)` method. + public func configure(_ configure: @escaping (AnimatedButton) -> Void) -> Self { + var copy = self + copy.configurations.append { context in + configure(context.view) + } + return copy + } + + /// Returns a copy of this view with its `LottieConfiguration` updated to the given value. + public func configuration(_ configuration: LottieConfiguration) -> Self { + var copy = self + copy.configuration = configuration + + copy = copy.configure { view in + if view.animationView.configuration != configuration { + view.animationView.configuration = configuration + } + } + + return copy + } + + /// Returns a copy of this view configured to animate between the + /// given progress values when the given event is triggered + public func animate( + fromProgress: AnimationProgressTime, + toProgress: AnimationProgressTime, + on event: LottieControlEvent) + -> Self + { + configure { view in + // `setPlayRange` just modifies a dictionary, + // so we can just call it on every state update without diffing + view.setPlayRange(fromProgress: fromProgress, toProgress: toProgress, event: event) + } + } + + /// Returns a copy of this view configured to animate between the + /// given markers when the given event is triggered + public func animate( + fromMarker: String, + toMarker: String, + on event: LottieControlEvent) + -> Self + { + configure { view in + // `setPlayRange` just modifies a dictionary, + // so we can just call it on every state update without diffing + view.setPlayRange(fromMarker: fromMarker, toMarker: toMarker, event: event) + } + } + + /// Returns a copy of this view using the given value provider for the given keypath. + /// The value provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func valueProvider( + _ valueProvider: ValueProvider, + for keypath: AnimationKeypath) + -> Self + { + configure { view in + if (view.animationView.valueProviders[keypath] as? ValueProvider) != valueProvider { + view.animationView.setValueProvider(valueProvider, keypath: keypath) + } + } + } + + // MARK: Internal + + var configurations = [SwiftUIView.Configuration]() + + // MARK: Private + + private let animation: LottieAnimation? + private let action: () -> Void + private var configuration: LottieConfiguration = .shared +} +#endif diff --git a/Pods/lottie-ios/Sources/Public/Controls/LottieSwitch.swift b/Pods/lottie-ios/Sources/Public/Controls/LottieSwitch.swift new file mode 100644 index 00000000..ffb02695 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/LottieSwitch.swift @@ -0,0 +1,146 @@ +// Created by Cal Stephens on 8/11/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(SwiftUI) +import SwiftUI + +/// A wrapper which exposes Lottie's `AnimatedSwitch` to SwiftUI +@available(iOS 13.0, tvOS 13.0, macOS 10.15, *) +public struct LottieSwitch: UIViewConfiguringSwiftUIView { + + // MARK: Lifecycle + + public init(animation: LottieAnimation?) { + self.animation = animation + } + + // MARK: Public + + public var body: some View { + AnimatedSwitch.swiftUIView { + let animatedSwitch = AnimatedSwitch(animation: animation, configuration: configuration) + animatedSwitch.isOn = isOn?.wrappedValue ?? false + return animatedSwitch + } + .configure { context in + // We check referential equality of the animation before updating as updating the + // animation has a side-effect of rebuilding the animation layer, and it would be + // prohibitive to do so on every state update. + if animation !== context.view.animationView.animation { + context.view.animationView.animation = animation + } + + #if os(macOS) + // Disable the intrinsic content size constraint on the inner animation view, + // or the Epoxy `SwiftUIMeasurementContainer` won't size this view correctly. + context.view.animationView.isVerticalContentSizeConstraintActive = false + context.view.animationView.isHorizontalContentSizeConstraintActive = false + #endif + + if let isOn = isOn?.wrappedValue, isOn != context.view.isOn { + context.view.setIsOn(isOn, animated: true) + } + } + .configurations(configurations) + } + + /// Returns a copy of this `LottieView` updated to have the given closure applied to its + /// represented `LottieAnimationView` whenever it is updated via the `updateUIView(…)` + /// or `updateNSView(…)` method. + public func configure(_ configure: @escaping (AnimatedSwitch) -> Void) -> Self { + var copy = self + copy.configurations.append { context in + configure(context.view) + } + return copy + } + + /// Returns a copy of this view with its `LottieConfiguration` updated to the given value. + public func configuration(_ configuration: LottieConfiguration) -> Self { + var copy = self + copy.configuration = configuration + + copy = copy.configure { view in + if view.animationView.configuration != configuration { + view.animationView.configuration = configuration + } + } + + return copy + } + + /// Returns a copy of this view with the given `Binding` reflecting the `isOn` state of the switch. + public func isOn(_ binding: Binding) -> Self { + var copy = self + copy.isOn = binding + return copy.configure { view in + view.stateUpdated = { isOn in + DispatchQueue.main.async { + binding.wrappedValue = isOn + } + } + } + } + + /// Returns a copy of this view with the "on" animation configured + /// to start and end at the given progress values. + /// Defaults to playing the entire animation forwards (0...1). + public func onAnimation( + fromProgress onStartProgress: AnimationProgressTime, + toProgress onEndProgress: AnimationProgressTime) + -> Self + { + configure { view in + if onStartProgress != view.onStartProgress || onEndProgress != view.onEndProgress { + view.setProgressForState( + fromProgress: onStartProgress, + toProgress: onEndProgress, + forOnState: true) + } + } + } + + /// Returns a copy of this view with the "on" animation configured + /// to start and end at the given progress values. + /// Defaults to playing the entire animation backwards (1...0). + public func offAnimation( + fromProgress offStartProgress: AnimationProgressTime, + toProgress offEndProgress: AnimationProgressTime) + -> Self + { + configure { view in + if offStartProgress != view.offStartProgress || offEndProgress != view.offEndProgress { + view.setProgressForState( + fromProgress: offStartProgress, + toProgress: offEndProgress, + forOnState: false) + } + } + } + + /// Returns a copy of this view using the given value provider for the given keypath. + /// The value provider must be `Equatable` to avoid unnecessary state updates / re-renders. + public func valueProvider( + _ valueProvider: ValueProvider, + for keypath: AnimationKeypath) + -> Self + { + configure { view in + if (view.animationView.valueProviders[keypath] as? ValueProvider) != valueProvider { + view.animationView.setValueProvider(valueProvider, keypath: keypath) + } + } + } + + // MARK: Internal + + var configurations = [SwiftUIView.Configuration]() + + // MARK: Private + + private let animation: LottieAnimation? + private var configuration: LottieConfiguration = .shared + private var isOn: Binding? + +} +#endif diff --git a/Pods/lottie-ios/Sources/Public/Controls/LottieViewType.swift b/Pods/lottie-ios/Sources/Public/Controls/LottieViewType.swift new file mode 100644 index 00000000..363183f7 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/Controls/LottieViewType.swift @@ -0,0 +1,79 @@ +// Created by Cal Stephens on 8/11/23. +// Copyright © 2023 Airbnb Inc. All rights reserved. + +#if canImport(UIKit) +import UIKit + +/// The control base type for this platform. +/// - `UIControl` on iOS / tvOS and `NSControl` on macOS. +public typealias LottieControlType = UIControl + +/// The `State` type of `LottieControlType` +/// - `UIControl.State` on iOS / tvOS and `NSControl.StateValue` on macOS. +public typealias LottieControlState = UIControl.State + +/// The event type handled by the `LottieControlType` component for this platform. +/// - `UIControl.Event` on iOS / tvOS and `LottieNSControlEvent` on macOS. +public typealias LottieControlEvent = UIControl.Event + +extension LottieControlEvent { + var id: AnyHashable { + rawValue + } +} +#else +import AppKit + +/// The control base type for this platform. +/// - `UIControl` on iOS / tvOS and `NSControl` on macOS. +public typealias LottieControlType = NSControl + +/// The `State` type of `LottieControlType` +/// - `UIControl.State` on iOS / tvOS and `NSControl.StateValue` on macOS. +public typealias LottieControlState = LottieNSControlState + +/// AppKit equivalent of `UIControl.State` for `AnimatedControl` +public enum LottieNSControlState: UInt, RawRepresentable { + /// The normal, or default, state of a control where the control is enabled but neither selected nor highlighted. + case normal + /// The highlighted state of a control. + case highlighted +} + +/// The event type handled by the `LottieControlType` component for this platform. +/// - `UIControl.Event` on iOS / tvOS and `LottieNSControlEvent` on macOS. +public typealias LottieControlEvent = LottieNSControlEvent + +public struct LottieNSControlEvent: Equatable { + + // MARK: Lifecycle + + public init(_ event: NSEvent.EventType, inside: Bool) { + self.event = event + self.inside = inside + } + + // MARK: Public + + /// macOS equivalent to `UIControl.Event.touchDown` + public static let touchDown = LottieNSControlEvent(.leftMouseDown, inside: true) + + /// macOS equivalent to `UIControl.Event.touchUpInside` + public static let touchUpInside = LottieNSControlEvent(.leftMouseUp, inside: true) + + /// macOS equivalent to `UIControl.Event.touchUpInside` + public static let touchUpOutside = LottieNSControlEvent(.leftMouseUp, inside: false) + + /// The underlying `NSEvent.EventType` of this event, which is roughly equivalent to `UIControl.Event` + public var event: NSEvent.EventType + + /// Whether or not the mouse must be inside the control. + public var inside: Bool + + // MARK: Internal + + var id: AnyHashable { + [AnyHashable(event.rawValue), AnyHashable(inside)] + } +} +#endif diff --git a/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCache.swift b/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCache.swift new file mode 100644 index 00000000..1e7d00b1 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCache.swift @@ -0,0 +1,66 @@ +// +// LRUDotLottieCache.swift +// Lottie +// +// Created by Evandro Hoffmann on 20/10/22. +// + +import Foundation + +// MARK: - DotLottieCache + +/// A DotLottie Cache that will store lottie files up to `cacheSize`. +/// +/// Once `cacheSize` is reached, the least recently used lottie will be ejected. +/// The default size of the cache is 100. +public class DotLottieCache: DotLottieCacheProvider { + + // MARK: Lifecycle + + public init() { + cache.countLimit = Self.defaultCacheCountLimit + } + + // MARK: Public + + /// The global shared Cache. + public static let sharedCache = DotLottieCache() + + /// The size of the cache. + public var cacheSize = defaultCacheCountLimit { + didSet { + cache.countLimit = cacheSize + } + } + + /// Clears the Cache. + public func clearCache() { + cache.removeAllValues() + } + + public func file(forKey key: String) -> DotLottieFile? { + cache.value(forKey: key) + } + + public func setFile(_ lottie: DotLottieFile, forKey key: String) { + cache.setValue(lottie, forKey: key) + } + + // MARK: Private + + private static let defaultCacheCountLimit = 100 + + /// The underlying storage of this cache. + /// - We use the `LRUCache` library instead of `NSCache`, because `NSCache` + /// clears all cached values when the app is backgrounded instead of + /// only when the app receives a memory warning notification. + private var cache = LRUCache() + +} + +// MARK: Sendable + +// DotLottieCacheProvider has a Sendable requirement, but we can't +// redesign DotLottieCache to be properly Sendable without making breaking changes. +// swiftlint:disable:next no_unchecked_sendable +extension DotLottieCache: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift b/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift new file mode 100644 index 00000000..6a59cba2 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift @@ -0,0 +1,21 @@ +// +// DotLottieCacheProvider.swift +// Lottie +// +// Created by Evandro Hoffmann on 20/10/22. +// + +/// `DotLottieCacheProvider` is a protocol that describes a DotLottie Cache. +/// DotLottie Cache is used when loading `DotLottie` models. Using a DotLottie Cache +/// can increase performance when loading an animation multiple times. +/// +/// Lottie comes with a prebuilt LRU DotLottie Cache. +public protocol DotLottieCacheProvider: Sendable { + + func file(forKey: String) -> DotLottieFile? + + func setFile(_ lottie: DotLottieFile, forKey: String) + + func clearCache() + +} diff --git a/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieConfiguration.swift b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieConfiguration.swift new file mode 100644 index 00000000..2de4b746 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieConfiguration.swift @@ -0,0 +1,72 @@ +// +// DotLottieConfiguration.swift +// Lottie +// +// Created by Evandro Hoffmann on 19/10/22. +// + +// MARK: - DotLottieConfiguration + +/// The `DotLottieConfiguration` model holds the presets extracted from DotLottieAnimation +/// - The presets are used as input to setup `LottieAnimationView` before playing the animation. +public struct DotLottieConfiguration { + + // MARK: Public + + /// id of the animation + public var id: String + + /// Loop behavior of animation + public var loopMode: LottieLoopMode + + /// Playback speed of animation + public var speed: Double + + /// Animation Image Provider + public var imageProvider: AnimationImageProvider? { + dotLottieImageProvider + } + + // MARK: Internal + + /// The underlying `DotLottieImageProvider` used by this dotLottie animation + var dotLottieImageProvider: DotLottieImageProvider? +} + +// MARK: - DotLottieConfigurationComponents + +/// Components of the `DotLottieConfiguration` to apply to the `LottieAnimationView`. +/// - When using `LottieView`, if the component is selected to be applied it will +/// override any value provided via other `LottieView` APIs. +public struct DotLottieConfigurationComponents: OptionSet { + + // MARK: Lifecycle + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + // MARK: Public + + /// `DotLottieConfiguration.imageProvider` will be applied to the `LottieAnimationView` + /// - When using `LottieView`, the image provider from the dotLottie animation will override + /// the image provider applied manually using `LottieView.imageProvider(...)`. + public static let imageProvider = DotLottieConfigurationComponents(rawValue: 1 << 0) + + /// `DotLottieConfigurationMode.loopMode` will be applied to the `LottieAnimationView`. + /// - When using `LottieView`, the loop mode from the dotLottie animation will override + /// the loopMode applied by any playback method. + public static let loopMode = DotLottieConfigurationComponents(rawValue: 1 << 1) + + /// `DotLottieConfigurationMode.speed` will be applied to the `LottieAnimationView`. + /// - When using `LottieView`, the speed from the dotLottie animation will override + /// the speed applied manually using `LottieView.animationSpeed(...)`. + public static let animationSpeed = DotLottieConfigurationComponents(rawValue: 1 << 2) + + public static let all: DotLottieConfigurationComponents = [.imageProvider, .loopMode, .animationSpeed] + + public static let none: DotLottieConfigurationComponents = [] + + public let rawValue: Int + +} diff --git a/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFile.swift b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFile.swift new file mode 100644 index 00000000..d774d094 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFile.swift @@ -0,0 +1,154 @@ +// +// DotLottie.swift +// Lottie +// +// Created by Evandro Harrison Hoffmann on 27/06/2020. +// + +import Foundation + +// MARK: - DotLottieFile + +/// Detailed .lottie file structure +public final class DotLottieFile { + + // MARK: Lifecycle + + /// Loads `DotLottie` from `Data` object containing a compressed animation. + /// + /// - Parameters: + /// - data: Data of .lottie file + /// - filename: Name of .lottie file + /// - Returns: Deserialized `DotLottie`. Optional. + init(data: Data, filename: String) throws { + fileUrl = DotLottieUtils.tempDirectoryURL.appendingPathComponent(filename.asFilename()) + try decompress(data: data, to: fileUrl) + } + + // MARK: Public + + /// Definition for a single animation within a `DotLottieFile` + public struct Animation { + public let animation: LottieAnimation + public let configuration: DotLottieConfiguration + } + + /// List of `LottieAnimation` in the file + public private(set) var animations: [Animation] = [] + + // MARK: Internal + + /// Image provider for animations + private(set) var imageProvider: DotLottieImageProvider? + + /// Animations folder url + lazy var animationsUrl: URL = fileUrl.appendingPathComponent("\(DotLottieFile.animationsFolderName)") + + /// All files in animations folder + lazy var animationUrls: [URL] = FileManager.default.urls(for: animationsUrl) ?? [] + + /// Images folder url + lazy var imagesUrl: URL = fileUrl.appendingPathComponent("\(DotLottieFile.imagesFolderName)") + + /// All images in images folder + lazy var imageUrls: [URL] = FileManager.default.urls(for: imagesUrl) ?? [] + + /// The `LottieAnimation` and `DotLottieConfiguration` for the given animation ID in this file + func animation(for id: String? = nil) -> DotLottieFile.Animation? { + if let id { + return animations.first(where: { $0.configuration.id == id }) + } else { + return animations.first + } + } + + /// The `LottieAnimation` and `DotLottieConfiguration` for the given animation index in this file + func animation(at index: Int) -> DotLottieFile.Animation? { + guard index < animations.count else { return nil } + return animations[index] + } + + // MARK: Private + + private static let manifestFileName = "manifest.json" + private static let animationsFolderName = "animations" + private static let imagesFolderName = "images" + + private let fileUrl: URL + + /// Decompresses .lottie file from `URL` and saves to local temp folder + /// + /// - Parameters: + /// - url: url to .lottie file + /// - destinationURL: url to destination of decompression contents + private func decompress(from url: URL, to destinationURL: URL) throws { + try? FileManager.default.removeItem(at: destinationURL) + try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil) + try FileManager.default.unzipItem(at: url, to: destinationURL) + try loadContent() + try? FileManager.default.removeItem(at: destinationURL) + try? FileManager.default.removeItem(at: url) + } + + /// Decompresses .lottie file from `Data` and saves to local temp folder + /// + /// - Parameters: + /// - url: url to .lottie file + /// - destinationURL: url to destination of decompression contents + private func decompress(data: Data, to destinationURL: URL) throws { + let url = destinationURL.appendingPathExtension("lottie") + try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil) + try data.write(to: url) + try decompress(from: url, to: destinationURL) + } + + /// Loads file content to memory + private func loadContent() throws { + imageProvider = DotLottieImageProvider(filepath: imagesUrl) + + animations = try loadManifest().animations.map { dotLottieAnimation in + let animation = try dotLottieAnimation.animation(url: animationsUrl) + let configuration = DotLottieConfiguration( + id: dotLottieAnimation.id, + loopMode: dotLottieAnimation.loopMode, + speed: dotLottieAnimation.animationSpeed, + dotLottieImageProvider: imageProvider) + + return DotLottieFile.Animation( + animation: animation, + configuration: configuration) + } + } + + private func loadManifest() throws -> DotLottieManifest { + let path = fileUrl.appendingPathComponent(DotLottieFile.manifestFileName) + return try DotLottieManifest.load(from: path) + } +} + +extension String { + + // MARK: Fileprivate + + fileprivate func asFilename() -> String { + lastPathComponent().removingPathExtension() + } + + // MARK: Private + + private func lastPathComponent() -> String { + (self as NSString).lastPathComponent + } + + private func removingPathExtension() -> String { + (self as NSString).deletingPathExtension + } +} + +// MARK: - DotLottieFile + Sendable + +// Mark `DotLottieFile` as `@unchecked Sendable` to allow it to be used when strict concurrency is enabled. +// In the future, it may be necessary to make changes to the internal implementation of `DotLottieFile` +// to make it truly thread-safe. +// swiftlint:disable:next no_unchecked_sendable +extension DotLottieFile: @unchecked Sendable { } diff --git a/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFileHelpers.swift b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFileHelpers.swift new file mode 100644 index 00000000..bd9c09f3 --- /dev/null +++ b/Pods/lottie-ios/Sources/Public/DotLottie/DotLottieFileHelpers.swift @@ -0,0 +1,378 @@ +// +// DotLottieFileHelpers.swift +// Lottie +// +// Created by Evandro Hoffmann on 20/10/22. +// + +import Foundation + +extension DotLottieFile { + + public enum SynchronouslyBlockingCurrentThread { + /// Loads an DotLottie from a specific filepath synchronously. Returns a `Result` + /// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in. + /// + /// - Parameter filepath: The absolute filepath of the lottie to load. EG "/User/Me/starAnimation.lottie" + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + public static func loadedFrom( + filepath: String, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + -> Result + { + LottieLogger.shared.assert( + !Thread.isMainThread, + "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.") + + /// Check cache for lottie + if + let dotLottieCache, + let lottie = dotLottieCache.file(forKey: filepath) + { + return .success(lottie) + } + + do { + /// Decode the lottie. + let url = URL(fileURLWithPath: filepath) + let data = try Data(contentsOf: url) + let lottie = try DotLottieFile(data: data, filename: url.deletingPathExtension().lastPathComponent) + dotLottieCache?.setFile(lottie, forKey: filepath) + return .success(lottie) + } catch { + /// Decoding Error. + return .failure(error) + } + } + + /// Loads a DotLottie model from a bundle by its name synchronously. Returns a `Result` + /// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in. + /// + /// - Parameter name: The name of the lottie file without the lottie extension. EG "StarAnimation" + /// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main` + /// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional. + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + public static func named( + _ name: String, + bundle: Bundle = Bundle.main, + subdirectory: String? = nil, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + -> Result + { + LottieLogger.shared.assert( + !Thread.isMainThread, + "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.") + + /// Create a cache key for the lottie. + let cacheKey = bundle.bundlePath + (subdirectory ?? "") + "/" + name + + /// Check cache for lottie + if + let dotLottieCache, + let lottie = dotLottieCache.file(forKey: cacheKey) + { + return .success(lottie) + } + + do { + /// Decode animation. + let data = try bundle.dotLottieData(name, subdirectory: subdirectory) + let lottie = try DotLottieFile(data: data, filename: name) + dotLottieCache?.setFile(lottie, forKey: cacheKey) + return .success(lottie) + } catch { + /// Decoding error. + LottieLogger.shared.warn("Error when decoding lottie \"\(name)\": \(error)") + return .failure(error) + } + } + + /// Loads an DotLottie from a data synchronously. Returns a `Result` + /// + /// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in. + /// + /// - Parameters: + /// - data: The data(`Foundation.Data`) object to load DotLottie from + /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation" + public static func loadedFrom( + data: Data, + filename: String) + -> Result + { + LottieLogger.shared.assert( + !Thread.isMainThread, + "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.") + + do { + let dotLottieFile = try DotLottieFile(data: data, filename: filename) + return .success(dotLottieFile) + } catch { + return .failure(error) + } + } + } + + /// Loads a DotLottie model from a bundle by its name. Returns `nil` if a file is not found. + /// + /// - Parameter name: The name of the lottie file without the lottie extension. EG "StarAnimation" + /// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main` + /// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional. + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + @available(iOS 13.0, macOS 10.15, tvOS 13.0, *) + public static func named( + _ name: String, + bundle: Bundle = Bundle.main, + subdirectory: String? = nil, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + async throws -> DotLottieFile + { + try await withCheckedThrowingContinuation { continuation in + DotLottieFile.named(name, bundle: bundle, subdirectory: subdirectory, dotLottieCache: dotLottieCache) { result in + continuation.resume(with: result) + } + } + } + + /// Loads a DotLottie model from a bundle by its name. Returns `nil` if a file is not found. + /// + /// - Parameter name: The name of the lottie file without the lottie extension. EG "StarAnimation" + /// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main` + /// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional. + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + /// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional. + /// - Parameter handleResult: A closure to be called when the file has loaded. + public static func named( + _ name: String, + bundle: Bundle = Bundle.main, + subdirectory: String? = nil, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache, + dispatchQueue: DispatchQueue = .dotLottie, + handleResult: @escaping (Result) -> Void) + { + dispatchQueue.async { + let result = SynchronouslyBlockingCurrentThread.named( + name, + bundle: bundle, + subdirectory: subdirectory, + dotLottieCache: dotLottieCache) + + DispatchQueue.main.async { + handleResult(result) + } + } + } + + /// Loads an DotLottie from a specific filepath. + /// - Parameter filepath: The absolute filepath of the lottie to load. EG "/User/Me/starAnimation.lottie" + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + @available(iOS 13.0, macOS 10.15, tvOS 13.0, *) + public static func loadedFrom( + filepath: String, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + async throws -> DotLottieFile + { + try await withCheckedThrowingContinuation { continuation in + DotLottieFile.loadedFrom(filepath: filepath, dotLottieCache: dotLottieCache) { result in + continuation.resume(with: result) + } + } + } + + /// Loads an DotLottie from a specific filepath. + /// - Parameter filepath: The absolute filepath of the lottie to load. EG "/User/Me/starAnimation.lottie" + /// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional. + /// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional. + /// - Parameter handleResult: A closure to be called when the file has loaded. + public static func loadedFrom( + filepath: String, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache, + dispatchQueue: DispatchQueue = .dotLottie, + handleResult: @escaping (Result) -> Void) + { + dispatchQueue.async { + let result = SynchronouslyBlockingCurrentThread.loadedFrom( + filepath: filepath, + dotLottieCache: dotLottieCache) + + DispatchQueue.main.async { + handleResult(result) + } + } + } + + /// Loads a DotLottie model from the asset catalog by its name. Returns `nil` if a lottie is not found. + /// - Parameter name: The name of the lottie file in the asset catalog. EG "StarAnimation" + /// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main` + /// - Parameter dotLottieCache: A cache for holding loaded lottie files. Defaults to `LRUDotLottieCache.sharedCache` Optional. + @available(iOS 13.0, macOS 10.15, tvOS 13.0, *) + public static func asset( + named name: String, + bundle: Bundle = Bundle.main, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + async throws -> DotLottieFile + { + try await withCheckedThrowingContinuation { continuation in + DotLottieFile.asset(named: name, bundle: bundle, dotLottieCache: dotLottieCache) { result in + continuation.resume(with: result) + } + } + } + + /// Loads a DotLottie model from the asset catalog by its name. Returns `nil` if a lottie is not found. + /// - Parameter name: The name of the lottie file in the asset catalog. EG "StarAnimation" + /// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main` + /// - Parameter dotLottieCache: A cache for holding loaded lottie files. Defaults to `LRUDotLottieCache.sharedCache` Optional. + /// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional. + /// - Parameter handleResult: A closure to be called when the file has loaded. + public static func asset( + named name: String, + bundle: Bundle = Bundle.main, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache, + dispatchQueue: DispatchQueue = .dotLottie, + handleResult: @escaping (Result) -> Void) + { + dispatchQueue.async { + /// Create a cache key for the lottie. + let cacheKey = bundle.bundlePath + "/" + name + + /// Check cache for lottie + if + let dotLottieCache, + let lottie = dotLottieCache.file(forKey: cacheKey) + { + /// If found, return the lottie. + DispatchQueue.main.async { + handleResult(.success(lottie)) + } + return + } + + do { + /// Load data from Asset + let data = try Data(assetName: name, in: bundle) + + /// Decode lottie. + let lottie = try DotLottieFile(data: data, filename: name) + dotLottieCache?.setFile(lottie, forKey: cacheKey) + DispatchQueue.main.async { + handleResult(.success(lottie)) + } + } catch { + /// Decoding error. + DispatchQueue.main.async { + handleResult(.failure(error)) + } + } + } + } + + /// Loads a DotLottie animation asynchronously from the URL. + /// + /// - Parameter url: The url to load the animation from. + /// - Parameter animationCache: A cache for holding loaded animations. Defaults to `LRUAnimationCache.sharedCache`. Optional. + @available(iOS 13.0, macOS 10.15, tvOS 13.0, *) + public static func loadedFrom( + url: URL, + session: URLSession = .shared, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache) + async throws -> DotLottieFile + { + try await withCheckedThrowingContinuation { continuation in + DotLottieFile.loadedFrom(url: url, session: session, dotLottieCache: dotLottieCache) { result in + continuation.resume(with: result) + } + } + } + + /// Loads a DotLottie animation asynchronously from the URL. + /// + /// - Parameter url: The url to load the animation from. + /// - Parameter animationCache: A cache for holding loaded animations. Defaults to `LRUAnimationCache.sharedCache`. Optional. + /// - Parameter handleResult: A closure to be called when the animation has loaded. + public static func loadedFrom( + url: URL, + session: URLSession = .shared, + dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache, + handleResult: @escaping (Result) -> Void) + { + if let dotLottieCache, let lottie = dotLottieCache.file(forKey: url.absoluteString) { + handleResult(.success(lottie)) + } else { + let task = session.dataTask(with: url) { data, _, error in + do { + if let error { + throw error + } + guard let data else { + throw DotLottieError.noDataLoaded + } + let lottie = try DotLottieFile(data: data, filename: url.deletingPathExtension().lastPathComponent) + DispatchQueue.main.async { + dotLottieCache?.setFile(lottie, forKey: url.absoluteString) + handleResult(.success(lottie)) + } + } catch { + DispatchQueue.main.async { + handleResult(.failure(error)) + } + } + } + task.resume() + } + } + + /// Loads an DotLottie from a data asynchronously. + /// + /// - Parameters: + /// - data: The data(`Foundation.Data`) object to load DotLottie from + /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation" + /// - dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional. + /// - handleResult: A closure to be called when the file has loaded. + public static func loadedFrom( + data: Data, + filename: String, + dispatchQueue: DispatchQueue = .dotLottie, + handleResult: @escaping (Result) -> Void) + { + dispatchQueue.async { + do { + let dotLottie = try DotLottieFile(data: data, filename: filename) + DispatchQueue.main.async { + handleResult(.success(dotLottie)) + } + } catch { + DispatchQueue.main.async { + handleResult(.failure(error)) + } + } + } + } + + /// Loads an DotLottie from a data asynchronously. + /// + /// - Parameters: + /// - data: The data(`Foundation.Data`) object to load DotLottie from + /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation" + /// - dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional. + @available(iOS 13.0, macOS 10.15, tvOS 13.0, *) + public static func loadedFrom( + data: Data, + filename: String, + dispatchQueue: DispatchQueue = .dotLottie) + async throws -> DotLottieFile + { + try await withCheckedThrowingContinuation { continuation in + loadedFrom(data: data, filename: filename, dispatchQueue: dispatchQueue) { result in + continuation.resume(with: result) + } + } + } +} + +extension DispatchQueue { + /// A serial dispatch queue ensures that IO related to loading dot Lottie files don't overlap, + /// which can trigger file loading errors due to concurrent unzipping on a single archive. + public static let dotLottie = DispatchQueue( + label: "com.airbnb.lottie.dot-lottie", + qos: .userInitiated) +}