From 0ec6e852449b409aff61189edd7d675ad5829b7e Mon Sep 17 00:00:00 2001 From: wujunyang Date: Wed, 28 Sep 2016 15:01:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Podfile | 2 +- Podfile.lock | 8 +- Pods/Headers/Private/JSPatch/JPEngine.h | 1 - Pods/Headers/Public/JSPatch/JPEngine.h | 1 - Pods/JSPatch/README-CN.md | 238 - Pods/Manifest.lock | 8 +- Pods/Pods.xcodeproj/project.pbxproj | 11440 ++++++++-------- .../AFNetworking/AFNetworking.xcconfig | 2 +- .../Aspects/Aspects.xcconfig | 2 +- .../CYLTabBarController.xcconfig | 2 +- .../JSONModel/JSONModel.xcconfig | 2 +- .../JSPatch/JSPatch-dummy.m | 5 - .../JSPatch/JSPatch-prefix.pch | 4 - .../JSPatch/JSPatch.xcconfig | 5 - .../Masonry/Masonry.xcconfig | 2 +- .../Pods/Pods-acknowledgements.markdown | 31 +- .../Pods/Pods-acknowledgements.plist | 39 +- .../Pods/Pods-resources.sh | 6 - .../Pods/Pods.debug.xcconfig | 9 +- .../Pods/Pods.release.xcconfig | 9 +- .../ReactiveCocoa/ReactiveCocoa.xcconfig | 2 +- .../SDWebImage/SDWebImage.xcconfig | 2 +- .../XAspect/XAspect.xcconfig | 2 +- README.md | 34 +- jiaModuleDemo.xcodeproj/project.pbxproj | 967 +- jiaModuleDemo/App/AppDelegate.h | 1 + jiaModuleDemo/App/AppDelegate.m | 40 + .../JiaAnalytics/JiaAnalyticsConfigManager.h | 30 + .../JiaAnalytics/JiaAnalyticsConfigManager.m | 24 + .../JiaAnalytics/JiaAnalyticsHelper.h | 38 + .../JiaAnalytics/JiaAnalyticsHelper.m | 107 + .../XAspect-AnalyticsAppDelegate.m | 42 + .../BaseModule/JiaCore/JiaAppDelegate.h | 1 + .../BaseModule/JiaCore/JiaAppDelegate.m | 8 +- jiaModuleDemo/BaseModule/JiaCore/JiaCore.h | 28 + .../JiaCoreHelper/GVUserDefaults+JiaCore.h | 15 + .../JiaCoreHelper/GVUserDefaults+JiaCore.m | 13 + .../JiaCoreHelper/JiaCoreConfigManager.h | 16 +- .../JiaCoreHelper/JiaCoreConfigManager.m | 11 + .../JiaPathchHelper/JiaPathchHelper.h | 19 + .../JiaPathchHelper/JiaPathchHelper.m | 362 + .../JiaPathchHelper/JiaPathchModel.h | 32 + .../JiaPathchHelper/JiaPathchModel.m | 13 + .../FLEXArgumentInputColorView.h | 13 + .../FLEXArgumentInputColorView.m | 329 + .../FLEXArgumentInputDateView.h | 13 + .../FLEXArgumentInputDateView.m | 63 + .../FLEXArgumentInputFontView.h | 13 + .../FLEXArgumentInputFontView.m | 121 + .../FLEXArgumentInputFontsPickerView.h | 12 + .../FLEXArgumentInputFontsPickerView.m | 105 + .../FLEXArgumentInputJSONObjectView.h | 13 + .../FLEXArgumentInputJSONObjectView.m | 65 + .../FLEXArgumentInputNotSupportedView.h | 13 + .../FLEXArgumentInputNotSupportedView.m | 25 + .../FLEXArgumentInputNumberView.h | 13 + .../FLEXArgumentInputNumberView.m | 57 + .../FLEXArgumentInputStringView.h | 13 + .../FLEXArgumentInputStringView.m | 45 + .../FLEXArgumentInputStructView.h | 13 + .../FLEXArgumentInputStructView.m | 210 + .../FLEXArgumentInputSwitchView.h | 13 + .../FLEXArgumentInputSwitchView.m | 87 + .../FLEXArgumentInputTextView.h | 17 + .../FLEXArgumentInputTextView.m | 121 + .../FLEXArgumentInputView.h | 60 + .../FLEXArgumentInputView.m | 137 + .../FLEXArgumentInputViewFactory.h | 25 + .../FLEXArgumentInputViewFactory.m | 72 + .../Editing/FLEXDefaultEditorViewController.h | 17 + .../Editing/FLEXDefaultEditorViewController.m | 72 + .../FLEX/Editing/FLEXFieldEditorView.h | 18 + .../FLEX/Editing/FLEXFieldEditorView.m | 184 + .../Editing/FLEXFieldEditorViewController.h | 28 + .../Editing/FLEXFieldEditorViewController.m | 117 + .../Editing/FLEXIvarEditorViewController.h | 18 + .../Editing/FLEXIvarEditorViewController.m | 72 + .../Editing/FLEXMethodCallingViewController.h | 16 + .../Editing/FLEXMethodCallingViewController.m | 100 + .../FLEXPropertyEditorViewController.h | 18 + .../FLEXPropertyEditorViewController.m | 94 + .../FLEXExplorerViewController.h | 37 + .../FLEXExplorerViewController.m | 908 ++ .../FLEX/ExplorerInterface/FLEXWindow.h | 24 + .../FLEX/ExplorerInterface/FLEXWindow.m | 67 + .../JiaCore/JiaCoreTool/FLEX/FLEX.h | 9 + .../JiaCore/JiaCoreTool/FLEX/FLEXManager.h | 70 + .../DatabaseBrowser/FLEXDatabaseManager.h | 26 + .../FLEXMultiColumnTableView.h | 48 + .../FLEXMultiColumnTableView.m | 341 + .../FLEXRealmDatabaseManager.h | 14 + .../FLEXRealmDatabaseManager.m | 114 + .../DatabaseBrowser/FLEXRealmDefines.h | 46 + .../FLEXSQLiteDatabaseManager.h | 19 + .../FLEXSQLiteDatabaseManager.m | 190 + .../DatabaseBrowser/FLEXTableColumnHeader.h | 24 + .../DatabaseBrowser/FLEXTableColumnHeader.m | 60 + .../DatabaseBrowser/FLEXTableContentCell.h | 27 + .../DatabaseBrowser/FLEXTableContentCell.m | 66 + .../FLEXTableContentViewController.h | 16 + .../FLEXTableContentViewController.m | 184 + .../DatabaseBrowser/FLEXTableLeftCell.h | 17 + .../DatabaseBrowser/FLEXTableLeftCell.m | 35 + .../FLEXTableListViewController.h | 16 + .../FLEXTableListViewController.m | 136 + .../DatabaseBrowser}/LICENSE | 13 +- .../FLEXClassesTableViewController.h | 15 + .../FLEXClassesTableViewController.m | 140 + .../FLEXCookiesTableViewController.h | 13 + .../FLEXCookiesTableViewController.m | 71 + .../FLEXFileBrowserFileOperationController.h | 33 + .../FLEXFileBrowserFileOperationController.m | 142 + .../FLEXFileBrowserSearchOperation.h | 25 + .../FLEXFileBrowserSearchOperation.m | 123 + .../FLEXFileBrowserTableViewController.h | 17 + .../FLEXFileBrowserTableViewController.m | 351 + .../FLEXGlobalsTableViewController.h | 27 + .../FLEXGlobalsTableViewController.m | 306 + .../FLEXInstancesTableViewController.h | 16 + .../FLEXInstancesTableViewController.m | 130 + .../FLEXLibrariesTableViewController.h | 13 + .../FLEXLibrariesTableViewController.m | 177 + .../FLEXLiveObjectsTableViewController.h | 13 + .../FLEXLiveObjectsTableViewController.m | 208 + .../FLEXWebViewController.h | 18 + .../FLEXWebViewController.m | 127 + .../SystemLog/FLEXSystemLogMessage.h | 21 + .../SystemLog/FLEXSystemLogMessage.m | 55 + .../SystemLog/FLEXSystemLogTableViewCell.h | 23 + .../SystemLog/FLEXSystemLogTableViewCell.m | 128 + .../FLEXSystemLogTableViewController.h | 13 + .../FLEXSystemLogTableViewController.m | 192 + .../FLEX/Manager/FLEXManager+Private.h | 16 + .../JiaCoreTool/FLEX/Manager/FLEXManager.m | 360 + .../FLEX/Network/FLEXNetworkCurlLogger.h | 19 + .../FLEX/Network/FLEXNetworkCurlLogger.m | 42 + .../FLEXNetworkHistoryTableViewController.h | 13 + .../FLEXNetworkHistoryTableViewController.m | 360 + .../FLEX/Network/FLEXNetworkRecorder.h | 63 + .../FLEX/Network/FLEXNetworkRecorder.m | 262 + .../FLEXNetworkSettingsTableViewController.h | 13 + .../FLEXNetworkSettingsTableViewController.m | 186 + .../FLEX/Network/FLEXNetworkTransaction.h | 44 + .../FLEX/Network/FLEXNetworkTransaction.m | 80 + ...workTransactionDetailTableViewController.h | 17 + ...workTransactionDetailTableViewController.m | 465 + .../FLEXNetworkTransactionTableViewCell.h | 21 + .../FLEXNetworkTransactionTableViewCell.m | 180 + .../PonyDebugger/FLEXNetworkObserver.h | 29 + .../PonyDebugger/FLEXNetworkObserver.m | 1120 ++ .../FLEX/Network/PonyDebugger/LICENSE | 16 + .../FLEXArrayExplorerViewController.h | 13 + .../FLEXArrayExplorerViewController.m | 78 + .../FLEXClassExplorerViewController.h | 13 + .../FLEXClassExplorerViewController.m | 132 + .../FLEXDefaultsExplorerViewController.h | 13 + .../FLEXDefaultsExplorerViewController.m | 73 + .../FLEXDictionaryExplorerViewController.h | 13 + .../FLEXDictionaryExplorerViewController.m | 64 + .../FLEXGlobalsTableViewControllerEntry.h | 22 + .../FLEXGlobalsTableViewControllerEntry.m | 25 + .../FLEXImageExplorerViewController.h | 13 + .../FLEXImageExplorerViewController.m | 69 + .../FLEXLayerExplorerViewController.h | 13 + .../FLEXLayerExplorerViewController.m | 92 + .../FLEXObjectExplorerFactory.h | 17 + .../FLEXObjectExplorerFactory.m | 65 + .../FLEXObjectExplorerViewController.h | 51 + .../FLEXObjectExplorerViewController.m | 1033 ++ .../FLEXSetExplorerViewController.h | 13 + .../FLEXSetExplorerViewController.m | 64 + ...FLEXViewControllerExplorerViewController.h | 13 + ...FLEXViewControllerExplorerViewController.m | 96 + .../FLEXViewExplorerViewController.h | 13 + .../FLEXViewExplorerViewController.m | 217 + .../FLEX/Toolbar/FLEXExplorerToolbar.h | 49 + .../FLEX/Toolbar/FLEXExplorerToolbar.m | 226 + .../FLEX/Toolbar/FLEXToolbarItem.h | 17 + .../FLEX/Toolbar/FLEXToolbarItem.m | 133 + .../FLEX/Utility/FLEXHeapEnumerator.h | 17 + .../FLEX/Utility/FLEXHeapEnumerator.m | 96 + .../Utility/FLEXKeyboardHelpViewController.h | 13 + .../Utility/FLEXKeyboardHelpViewController.m | 44 + .../Utility/FLEXKeyboardShortcutManager.h | 24 + .../Utility/FLEXKeyboardShortcutManager.m | 306 + .../FLEX/Utility/FLEXMultilineTableViewCell.h | 17 + .../FLEX/Utility/FLEXMultilineTableViewCell.m | 55 + .../JiaCoreTool/FLEX/Utility/FLEXResources.h | 33 + .../JiaCoreTool/FLEX/Utility/FLEXResources.m | 167 + .../FLEX/Utility/FLEXRuntimeUtility.h | 59 + .../FLEX/Utility/FLEXRuntimeUtility.m | 708 + .../JiaCoreTool/FLEX/Utility/FLEXUtility.h | 52 + .../JiaCoreTool/FLEX/Utility/FLEXUtility.m | 428 + .../FLEXHierarchyTableViewCell.h | 18 + .../FLEXHierarchyTableViewCell.m | 106 + .../FLEXHierarchyTableViewController.h | 25 + .../FLEXHierarchyTableViewController.m | 207 + .../FLEXImagePreviewViewController.h | 15 + .../FLEXImagePreviewViewController.m | 86 + .../GVUserDefaults/GVUserDefaults.h | 15 + .../GVUserDefaults/GVUserDefaults.m | 279 + .../JSONModel/JSONModel/JSONModel.h | 321 - .../JSONModel/JSONModel/JSONModel.m | 1294 -- .../JSONModel/JSONModel/JSONModelArray.h | 60 - .../JSONModel/JSONModel/JSONModelArray.m | 145 - .../JSONModel/JSONModelClassProperty.h | 77 - .../JSONModel/JSONModelClassProperty.m | 48 - .../JSONModel/JSONModel/JSONModelError.h | 112 - .../JSONModel/JSONModel/JSONModelError.m | 93 - .../JSONModelCategories/NSArray+JSONModel.h | 40 - .../JSONModelCategories/NSArray+JSONModel.m | 28 - .../JiaCoreTool/JSONModel/JSONModelLib.h | 35 - .../JSONModel/JSONModelNetworking/JSONAPI.h | 90 - .../JSONModel/JSONModelNetworking/JSONAPI.m | 152 - .../JSONModelNetworking/JSONHTTPClient.h | 184 - .../JSONModelNetworking/JSONHTTPClient.m | 390 - .../JSONModel+networking.h | 66 - .../JSONModel+networking.m | 109 - .../JSONModelTransformations/JSONKeyMapper.h | 95 - .../JSONModelTransformations/JSONKeyMapper.m | 174 - .../JSONValueTransformer.h | 230 - .../JSONValueTransformer.m | 270 - .../JiaCore/JiaCoreTool}/JSPatch/JPEngine.h | 0 .../JiaCore/JiaCoreTool}/JSPatch/JPEngine.m | 57 +- .../JiaCore/JiaCoreTool}/JSPatch/JSPatch.js | 74 +- .../AFDownloadRequestOperation.h | 0 .../AFDownloadRequestOperation.m | 0 .../JiaNewWork}/JiaBaseRequest.h | 0 .../JiaNewWork}/JiaBaseRequest.m | 0 .../JiaNewWork/YTKNetwork/YTKBaseRequest.h | 0 .../JiaNewWork/YTKNetwork/YTKBaseRequest.m | 0 .../JiaNewWork/YTKNetwork/YTKBatchRequest.h | 0 .../JiaNewWork/YTKNetwork/YTKBatchRequest.m | 0 .../YTKNetwork/YTKBatchRequestAgent.h | 0 .../YTKNetwork/YTKBatchRequestAgent.m | 0 .../JiaNewWork/YTKNetwork/YTKChainRequest.h | 0 .../JiaNewWork/YTKNetwork/YTKChainRequest.m | 0 .../YTKNetwork/YTKChainRequestAgent.h | 0 .../YTKNetwork/YTKChainRequestAgent.m | 0 .../JiaNewWork/YTKNetwork/YTKNetwork.h | 0 .../JiaNewWork/YTKNetwork/YTKNetworkAgent.h | 0 .../JiaNewWork/YTKNetwork/YTKNetworkAgent.m | 0 .../JiaNewWork/YTKNetwork/YTKNetworkConfig.h | 0 .../JiaNewWork/YTKNetwork/YTKNetworkConfig.m | 0 .../JiaNewWork/YTKNetwork/YTKNetworkPrivate.h | 0 .../JiaNewWork/YTKNetwork/YTKNetworkPrivate.m | 0 .../JiaNewWork/YTKNetwork/YTKRequest.h | 0 .../JiaNewWork/YTKNetwork/YTKRequest.m | 0 .../JiaCore/JiaCoreTool/YYCache/YYCache.h | 206 + .../JiaCore/JiaCoreTool/YYCache/YYCache.m | 139 + .../JiaCore/JiaCoreTool/YYCache/YYDiskCache.h | 412 + .../JiaCore/JiaCoreTool/YYCache/YYDiskCache.m | 458 + .../JiaCore/JiaCoreTool/YYCache/YYKVStorage.h | 325 + .../JiaCore/JiaCoreTool/YYCache/YYKVStorage.m | 1069 ++ .../JiaCoreTool/YYCache/YYMemoryCache.h | 213 + .../JiaCoreTool/YYCache/YYMemoryCache.m | 505 + .../{ => JiaCore}/JiaMacros/JiaMacros.h | 4 +- .../JiaGT/XAspect-GeTuiAppDelegate.m | 2 + .../Controller/DesignerViewController.h | 2 +- .../Controller/DesignerViewController.m | 17 + .../Model/DesignerDetailModel.h | 13 + .../Model/DesignerDetailModel.m | 13 + .../Other/designerModulePrefixHeader.h | 1 + .../Other/jiaDesignerConfigManager.h | 2 + .../Service/DesignerServiceApi.m | 2 +- .../DesignerModule/View/DesignerHeaderView.h | 13 + .../DesignerModule/View/DesignerHeaderView.m | 13 + jiaModuleDemo/ProjectImage/10.png | Bin 0 -> 28639 bytes .../Controller/ProjectViewController.h | 3 +- .../Other/JiaProjectConfigManager.h | 13 + .../Other/JiaProjectConfigManager.m | 13 + .../ProjectModule/Other/projectModuleMacros.h | 13 + .../Other/projectModulePrefixHeader.h | 23 + .../Controller/UserViewController.h | 3 +- .../UserModule/Other/JiaUserConfigManager.h | 13 + .../UserModule/Other/JiaUserConfigManager.m | 13 + .../UserModule/Other/userModuleMacros.h | 13 + .../UserModule/Other/userModulePrefixHeader.h | 23 + 278 files changed, 26916 insertions(+), 10432 deletions(-) delete mode 120000 Pods/Headers/Private/JSPatch/JPEngine.h delete mode 120000 Pods/Headers/Public/JSPatch/JPEngine.h delete mode 100644 Pods/JSPatch/README-CN.md delete mode 100644 Pods/Target Support Files/JSPatch/JSPatch-dummy.m delete mode 100644 Pods/Target Support Files/JSPatch/JSPatch-prefix.pch delete mode 100644 Pods/Target Support Files/JSPatch/JSPatch.xcconfig create mode 100644 jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.h create mode 100644 jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.m create mode 100644 jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.h create mode 100644 jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.m create mode 100644 jiaModuleDemo/BaseModule/JiaAnalytics/XAspect-AnalyticsAppDelegate.m create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCore.h create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.h create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.m create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.h create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.m create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.h create mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEX.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEXManager.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m rename {Pods/JSPatch => jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser}/LICENSE (87%) mode change 100644 => 100755 create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager+Private.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/LICENSE create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelLib.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.m delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.h delete mode 100644 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.m rename {Pods/JSPatch => jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool}/JSPatch/JPEngine.h (100%) mode change 100644 => 100755 rename {Pods/JSPatch => jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool}/JSPatch/JPEngine.m (96%) mode change 100644 => 100755 rename {Pods/JSPatch => jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool}/JSPatch/JSPatch.js (88%) mode change 100644 => 100755 rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.m (100%) rename jiaModuleDemo/BaseModule/JiaCore/{JiaCoreHelper => JiaCoreTool/JiaNewWork}/JiaBaseRequest.h (100%) rename jiaModuleDemo/BaseModule/JiaCore/{JiaCoreHelper => JiaCoreTool/JiaNewWork}/JiaBaseRequest.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBaseRequest.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBaseRequest.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBatchRequest.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBatchRequest.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKChainRequest.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKChainRequest.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKChainRequestAgent.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKChainRequestAgent.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetwork.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkAgent.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkAgent.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkConfig.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkConfig.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkPrivate.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKNetworkPrivate.m (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKRequest.h (100%) rename jiaModuleDemo/BaseModule/{ => JiaCore/JiaCoreTool}/JiaNewWork/YTKNetwork/YTKRequest.m (100%) create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.m create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.h create mode 100755 jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.m rename jiaModuleDemo/BaseModule/{ => JiaCore}/JiaMacros/JiaMacros.h (97%) create mode 100644 jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.h create mode 100644 jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.m create mode 100644 jiaModuleDemo/DesignerModule/View/DesignerHeaderView.h create mode 100644 jiaModuleDemo/DesignerModule/View/DesignerHeaderView.m create mode 100644 jiaModuleDemo/ProjectImage/10.png create mode 100644 jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.h create mode 100644 jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.m create mode 100644 jiaModuleDemo/ProjectModule/Other/projectModuleMacros.h create mode 100644 jiaModuleDemo/ProjectModule/Other/projectModulePrefixHeader.h create mode 100644 jiaModuleDemo/UserModule/Other/JiaUserConfigManager.h create mode 100644 jiaModuleDemo/UserModule/Other/JiaUserConfigManager.m create mode 100644 jiaModuleDemo/UserModule/Other/userModuleMacros.h create mode 100644 jiaModuleDemo/UserModule/Other/userModulePrefixHeader.h diff --git a/Podfile b/Podfile index f68b6c5..02b5db6 100755 --- a/Podfile +++ b/Podfile @@ -7,8 +7,8 @@ pod 'ReactiveCocoa', '~> 2.5' pod 'SDWebImage', '~> 3.7.5' pod 'JSONModel', '~> 1.0.1' pod 'Masonry','~>0.6.1' -pod 'JSPatch' pod 'XAspect' pod 'CYLTabBarController' pod 'Aspects' pod 'GTSDK' +pod 'UMengAnalytics-NO-IDFA' \ No newline at end of file diff --git a/Podfile.lock b/Podfile.lock index 7e87418..f06309d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -24,9 +24,6 @@ PODS: - CYLTabBarController (1.6.0) - GTSDK (1.5.0) - JSONModel (1.0.2) - - JSPatch (1.1): - - JSPatch/Core (= 1.1) - - JSPatch/Core (1.1) - Masonry (0.6.4) - ReactiveCocoa (2.5): - ReactiveCocoa/UI (= 2.5) @@ -38,6 +35,7 @@ PODS: - SDWebImage (3.7.6): - SDWebImage/Core (= 3.7.6) - SDWebImage/Core (3.7.6) + - UMengAnalytics-NO-IDFA (4.1.1) - XAspect (1.0.5): - XAspect/Core (= 1.0.5) - XAspect/Macros (= 1.0.5) @@ -51,10 +49,10 @@ DEPENDENCIES: - CYLTabBarController - GTSDK - JSONModel (~> 1.0.1) - - JSPatch - Masonry (~> 0.6.1) - ReactiveCocoa (~> 2.5) - SDWebImage (~> 3.7.5) + - UMengAnalytics-NO-IDFA - XAspect SPEC CHECKSUMS: @@ -63,10 +61,10 @@ SPEC CHECKSUMS: CYLTabBarController: efbdd574772be17f17965acd7ee993f5972ff02f GTSDK: 4380de452178d8ba2a67189f10c6743d0f9536b9 JSONModel: 6ffcb4ffa3659c9e9a2e5d45d6c7705bab187c03 - JSPatch: ade285ad1d8f06146ed6054a39cef87509453299 Masonry: 281802d04d787ea2973179ee8bcb50500579ede2 ReactiveCocoa: e2db045570aa97c695e7aa97c2bcab222ae51f4a SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9 + UMengAnalytics-NO-IDFA: 1064992c1b7aaa22823179c0b33a664813fd7a85 XAspect: db50bf487f92dbb8557a7a5365556966c8493af8 COCOAPODS: 0.39.0 diff --git a/Pods/Headers/Private/JSPatch/JPEngine.h b/Pods/Headers/Private/JSPatch/JPEngine.h deleted file mode 120000 index 9bf4b6a..0000000 --- a/Pods/Headers/Private/JSPatch/JPEngine.h +++ /dev/null @@ -1 +0,0 @@ -../../../JSPatch/JSPatch/JPEngine.h \ No newline at end of file diff --git a/Pods/Headers/Public/JSPatch/JPEngine.h b/Pods/Headers/Public/JSPatch/JPEngine.h deleted file mode 120000 index 9bf4b6a..0000000 --- a/Pods/Headers/Public/JSPatch/JPEngine.h +++ /dev/null @@ -1 +0,0 @@ -../../../JSPatch/JSPatch/JPEngine.h \ No newline at end of file diff --git a/Pods/JSPatch/README-CN.md b/Pods/JSPatch/README-CN.md deleted file mode 100644 index 0031bb3..0000000 --- a/Pods/JSPatch/README-CN.md +++ /dev/null @@ -1,238 +0,0 @@ -# JSPatch - -JSPatch 可以让你用 JavaScript 书写原生 iOS APP。只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本语言的优势:为项目动态添加模块,或替换项目原生代码动态修复 bug。 - -项目仍在开发中,欢迎一起完善这个项目。 - -**注意**:完善的文档请移步 [Wiki](https://github.com/bang590/JSPatch/wiki/)。 - -## 示例 - -```objc -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - [JPEngine startEngine]; - NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"]; - NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; - [JPEngine evaluateScript:script]; - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - [self.window addSubview:[self genView]]; - [self.window makeKeyAndVisible]; - - return YES; -} - -- (UIView *)genView -{ - return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)]; -} - -@end -``` - -```js -// demo.js -require('UIView, UIColor, UILabel') -defineClass('AppDelegate', { - // replace the -genView method - genView: function() { - var view = self.ORIGgenView(); - view.setBackgroundColor(UIColor.greenColor()) - var label = UILabel.alloc().initWithFrame(view.frame()); - label.setText("JSPatch"); - label.setTextAlignment(1); - view.addSubview(label); - return view; - } -}); -``` - -可以使用 [JSPatch Convertor](https://github.com/bang590/JSPatchConvertor) 自动把 Objective-C 代码转为 JavaScript 代码。 - -## 安装 - -拷贝 `JSPatch/` 目录下的三个文件 `JSEngine.m` / `JSEngine.h` / `JSPatch.js` 到项目里即可。 - -## 使用 - -### Objective-C: -1. `#import "JPEngine.h"` -2. 调用`[JPEngine startEngine]` -3. 通过`[JPEngine evaluateScript:@""]`接口执行 JavaScript。 - -```objc -[JPEngine startEngine]; - -// 直接执行js -[JPEngine evaluateScript:@"\ - var alertView = require('UIAlertView').alloc().init();\ - alertView.setTitle('Alert');\ - alertView.setMessage('AlertView from js'); \ - alertView.addButtonWithTitle('OK');\ - alertView.show(); \ -"]; - -// 从网络拉回js脚本执行 -[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cnbang.net/test.js"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { - NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - [JPEngine evaluateScript:script]; -}]; - -// 执行本地js文件 -NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"js"]; -NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; -[JPEngine evaluateScript:script]; -``` - -### JavaScript: - -#### 基础使用方式 - -```js -// 调用require引入要使用的OC类 -require('UIView, UIColor, UISlider, NSIndexPath') - -// 调用类方法 -var redColor = UIColor.redColor(); - -// 调用实例方法 -var view = UIView.alloc().init(); -view.setNeedsLayout(); - -// set proerty -view.setBackgroundColor(redColor); - -// get property -var bgColor = view.backgroundColor(); - -// 多参数方法名用'_'隔开: -// OC:NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1]; -var indexPath = NSIndexPath.indexPathForRow_inSection(0, 1); - -// 方法名包含下划线'_',js用双下划线表示 -// OC: [JPObject _privateMethod]; -JPObject.__privateMethod() - -// 如果要把 `NSArray` / `NSString` / `NSDictionary` 转为对应的 JS 类型,使用 `.toJS()` 接口. -var arr = require('NSMutableArray').alloc().init() -arr.addObject("JS") -jsArr = arr.toJS() -console.log(jsArr.push("Patch").join('')) //output: JSPatch - -// 在JS用字典的方式表示 CGRect / CGSize / CGPoint / NSRange -var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100}); -var x = view.bounds().x; - -// block 从 JavaScript 传入 Objective-C 时,需要写上每个参数的类型。 -// OC Method: + (void)request:(void(^)(NSString *content, BOOL success))callback -require('JPObject').request(block("NSString *, BOOL", function(ctn, succ) { - if (succ) log(ctn) -})); - -// GCD -dispatch_after(function(1.0, function(){ - // do something -})) -dispatch_async_main(function(){ - // do something -}) -``` - -详细文档请参考wiki页面:[Base Usage](https://github.com/bang590/JSPatch/wiki/Base-usage) - - -#### 定义类/替换方法 - -用 `defineClass()` 定义 Objective-C 的类,对类和实例方法进行动态替换。 - -```objc -// OC -@implementation JPTableViewController -... -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSString *content = self.dataSource[[indexPath row]]; //may cause out of bound - JPViewController *ctrl = [[JPViewController alloc] initWithContent:content]; - [self.navigationController pushViewController:ctrl]; -} -- (NSArray *)dataSource -{ - return @[@"JSPatch", @"is"]; -} -- (void)customMethod -{ - NSLog(@"callCustom method") -} -@end -``` - -```objc -// JS -defineClass("JPTableViewController", { - // instance method definitions - tableView_didSelectRowAtIndexPath: function(tableView, indexPath) { - var row = indexPath.row() - if (self.dataSource().count() > row) { //fix the out of bound bug here - var content = self.dataSource().objectAtIndex(row); - var ctrl = JPViewController.alloc().initWithContent(content); - self.navigationController().pushViewController(ctrl); - } - }, - - dataSource: function() { - // get the original method by adding prefix 'ORIG' - var data = self.ORIGdataSource().toJS(); - return data.push('Good!'); - } -}, {}) -``` - -详细文档请参考wiki页面:[Usage of defineClass](https://github.com/bang590/JSPatch/wiki/Usage-of-defineClass) - - -#### 扩展 - -一些自定义的struct类型、C函数调用以及其他功能可以通过扩展实现,调用 `+addExtensions:` 可以加载扩展接口: - -```objc -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - [JPEngine startEngine]; - - //添加扩展 - [JPEngine addExtensions:@[@"JPInclude", @"JPCGTransform"]]; - - NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"]; - NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; - [JPEngine evaluateScript:script]; -} -``` - -```js -include('test.js') //`include()`方法在扩展 JPInclude.m 里提供 -var view = require('UIView').alloc().init() - -//struct CGAffineTransform 类型在 JPCGTransform.m 里提供支持 -view.setTransform({a:1, b:0, c:0, d:1, tx:0, ty:100}) -``` - -扩展可以在JS动态加载,更推荐这种加载方式,在需要用到时才加载: - -```js -require('JPEngine').addExtensions(['JPInclude', 'JPCGTransform']) - -// `include()` and `CGAffineTransform` is avaliable now. -``` - -可以通过新增扩展为自己项目里的 struct 类型以及C函数添加支持,详情请见wiki页面:[Adding new extensions](https://github.com/bang590/JSPatch/wiki/Adding-new-extensions) - - -## 运行环境 -- iOS 7+ -- JavaScriptCore.framework -- 支持 armv7/armv7s/arm64 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 7e87418..f06309d 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -24,9 +24,6 @@ PODS: - CYLTabBarController (1.6.0) - GTSDK (1.5.0) - JSONModel (1.0.2) - - JSPatch (1.1): - - JSPatch/Core (= 1.1) - - JSPatch/Core (1.1) - Masonry (0.6.4) - ReactiveCocoa (2.5): - ReactiveCocoa/UI (= 2.5) @@ -38,6 +35,7 @@ PODS: - SDWebImage (3.7.6): - SDWebImage/Core (= 3.7.6) - SDWebImage/Core (3.7.6) + - UMengAnalytics-NO-IDFA (4.1.1) - XAspect (1.0.5): - XAspect/Core (= 1.0.5) - XAspect/Macros (= 1.0.5) @@ -51,10 +49,10 @@ DEPENDENCIES: - CYLTabBarController - GTSDK - JSONModel (~> 1.0.1) - - JSPatch - Masonry (~> 0.6.1) - ReactiveCocoa (~> 2.5) - SDWebImage (~> 3.7.5) + - UMengAnalytics-NO-IDFA - XAspect SPEC CHECKSUMS: @@ -63,10 +61,10 @@ SPEC CHECKSUMS: CYLTabBarController: efbdd574772be17f17965acd7ee993f5972ff02f GTSDK: 4380de452178d8ba2a67189f10c6743d0f9536b9 JSONModel: 6ffcb4ffa3659c9e9a2e5d45d6c7705bab187c03 - JSPatch: ade285ad1d8f06146ed6054a39cef87509453299 Masonry: 281802d04d787ea2973179ee8bcb50500579ede2 ReactiveCocoa: e2db045570aa97c695e7aa97c2bcab222ae51f4a SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9 + UMengAnalytics-NO-IDFA: 1064992c1b7aaa22823179c0b33a664813fd7a85 XAspect: db50bf487f92dbb8557a7a5365556966c8493af8 COCOAPODS: 0.39.0 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 6c6a87f..c572355 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -10,41 +10,113 @@ 46 objects - 00061A7C9B119447394C1B790DC0125A + 00784913BB40755E9BD89DC8CB6F233A - children - - 4F64C8EDFA4698BD86F2A11C62FF9032 - 2B62DDFD0A35E5F65852939CEF828A9E - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.h name - no-arc + CYLPlusButton.h + path + CYLTabBarController/CYLPlusButton.h + sourceTree + <group> + + 00929B0F1375903B01DA333074381F17 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + JSONModelError.h + path + JSONModel/JSONModel/JSONModelError.h + sourceTree + <group> + + 009AC949FCDF3A0058063D295100D7C8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImageView+HighlightedWebCache.h + path + SDWebImage/UIImageView+HighlightedWebCache.h sourceTree <group> - 0036B867576A91F864CA856ED7A346BB + 00CB2427C5B89DD801B0054E86FE2520 fileRef - C60FDD97329B3F41A91733E7D1369A56 + 6586B4DBB4F7173C33D43A5A81458397 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 00CD0B0096519208337740D5BC28FE6D + 015873E0C53A730C64424B6EDA040750 - buildActionMask - 2147483647 - files - - 6371AF01D6F66B6A45C901711DB2419F - + fileRef + 14EE2BB2C6D784A106FF1D168C1FD25D isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile + settings + + ATTRIBUTES + + Private + + + + 0190945F9BF1EAB8CD7279A26AC7BCAD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACImmediateScheduler.h + path + ReactiveCocoa/RACImmediateScheduler.h + sourceTree + <group> + + 01B3D7E0E9D4C2A1A24152A732B8C72F + + isa + PBXTargetDependency + name + ReactiveCocoa + target + 9A935B6D3AACE527D4DF682DB3C53BDD + targetProxy + 1F9D0A038253F8A4A85191FE2BB38E05 + + 01E291E9D7F510001EF8E0F51C467C31 + + fileRef + 53D81312E4A85A6CFB6C3C06D619A81F + isa + PBXBuildFile - 0135CB45DDDBA452074962CC4FBD15C4 + 01F159ED6F5F238200CF3F0B936808FC includeInIndex 1 @@ -52,47 +124,68 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + NSURLConnection+RACSupport.m path - AFNetworking-dummy.m + ReactiveCocoa/NSURLConnection+RACSupport.m sourceTree <group> - 017C816C17DB67AE9F6826A6FE13364C + 023127DD998B06C63F956271B9999FB8 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - JSONHTTPClient.h + SDWebImagePrefetcher.m path - JSONModel/JSONModelNetworking/JSONHTTPClient.h + SDWebImage/SDWebImagePrefetcher.m sourceTree <group> - 02811C7B60F93138985F40306F45E68D + 02AAB748D205E13648BE463C0F7FE910 - fileRef - 4A84D33C0DB3F8586464A2B82975BC35 isa - PBXBuildFile + PBXTargetDependency + name + JSONModel + target + 09FA060F1A0492FB25232F489AC4E573 + targetProxy + 6B66FA500853F6DC68BA08E3336FC833 - 029945DE96FA76F2D1D65517B3C6C838 + 02B2F23E74F8BEB386D7563F64C1F808 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - libAspects.a + RACErrorSignal.h path - libAspects.a + ReactiveCocoa/RACErrorSignal.h sourceTree - BUILT_PRODUCTS_DIR + <group> + + 03306FD17D5572A086255ECDAC692D0D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACKVOTrampoline.m + path + ReactiveCocoa/RACKVOTrampoline.m + sourceTree + <group> 037C0CA694176A3C0915F62C9D20B3E6 @@ -107,50 +200,54 @@ sourceTree <group> - 039892CB5DDF40C2F2F7A64014E83136 + 039BE81A2AD49A82F59318AEE04DFF37 - fileRef - 4653CFBF8AD1185C23C763DAADD6F6DA - isa - PBXBuildFile - settings + baseConfigurationReference + 4E762F23EC34ED4A6FF3312D84E33A40 + buildSettings - ATTRIBUTES - - Public - + ENABLE_STRICT_OBJC_MSGSEND + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MACH_O_TYPE + staticlib + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PODS_ROOT + $(SRCROOT) + PRODUCT_NAME + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES - - 03A20335F57AA5151013ADC7CEE230EF - - fileRef - 85D2F186A70780E097FE9B4938FEA711 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + XCBuildConfiguration + name + Debug - 042A892BF73D36F9B88BD05E3CA301C0 + 04783261FB6729BD15B0FE2946512043 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UISwitch+RACSignalSupport.m + JSONModelClassProperty.h path - ReactiveCocoa/UISwitch+RACSignalSupport.m + JSONModel/JSONModel/JSONModelClassProperty.h sourceTree <group> - 0480BE93F654AD1A2D187F4B80831514 + 0483E8EC03F94EB38AE44D540D1103FD includeInIndex 1 @@ -159,37 +256,31 @@ lastKnownFileType sourcecode.c.h name - MASUtilities.h + RACChannel.h path - Masonry/MASUtilities.h + ReactiveCocoa/RACChannel.h sourceTree <group> - 04AF8D8C177C1967327A34A91AC5DC0A - - fileRef - CF6EFFA22C3751AB7F978D1903CA7BA8 - isa - PBXBuildFile - - 04D2900C9DBB15D9F8F5BAD7A256C442 + 04DD6B49D851C7B2911B803CD7BBB076 - fileRef - 1A5BE933196809B7B7E1AD67610EB412 + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + CYLPlusButton.m + path + CYLTabBarController/CYLPlusButton.m + sourceTree + <group> 04E0EFD308A39DA6783F9004C5689973 fileRef - 092313CD65C3ADE482E79E26E2506D58 + 20C5209E3167276E1F17E266DDB92675 isa PBXBuildFile settings @@ -200,21 +291,6 @@ - 04E49DCD6C8078833262469CB937AD94 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - JSONKeyMapper.m - path - JSONModel/JSONModelTransformations/JSONKeyMapper.m - sourceTree - <group> - 052A17875CB827423D627183396CEB60 buildSettings @@ -283,92 +359,99 @@ name Release - 05B6FCF2A3F84FBE5600B24177C5B284 + 05440307997E67C54848A5EC63BA113A - fileRef - 0F560B4734048E5F6E51CDF94FB54F23 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIKit+AFNetworking.h + path + UIKit+AFNetworking/UIKit+AFNetworking.h + sourceTree + <group> - 06ECFA846BF20459400D87E324316AD8 + 057F7CE354F1F79F8F5A3C146C834B82 - buildActionMask - 2147483647 - files - - ADAEC0B257466F2D1743C9E8B6FF1563 - B9292BFF0457A5BA88B32D4EF8F38AB3 - + includeInIndex + 1 isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 07A92093C5F89FAE84540DECC939FFDF - - fileRef - C9AE24C328D4A75275E3BD6C16C5A145 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Private - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFHTTPSessionManager.m + path + AFNetworking/AFHTTPSessionManager.m + sourceTree + <group> - 0840A76EC690C8025301D5B2587F04F9 + 059196CADDF986D00738A637A66671BD includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIBarButtonItem+RACCommandSupport.m + UIActionSheet+RACSignalSupport.h path - ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m + ReactiveCocoa/UIActionSheet+RACSignalSupport.h sourceTree <group> - 08615F925825849B44B6CCD3E6F0603E + 061105E57BB9E3E753AE0AF47837A809 fileRef - 855BDEFE7590AD1A95E842D65C82F5DD + 4CF65A701B1BE85EC147610D641309B5 isa PBXBuildFile - 08FC414E4468D8119EB2F0B1BA89EDB6 + 06D9B68E78A4ED4E68016ABE2E86289D - containerPortal - D41D8CD98F00B204E9800998ECF8427E - isa - PBXContainerItemProxy - proxyType + includeInIndex 1 - remoteGlobalIDString - 4F7ACF1421268A3CDFC9455CABF9A6D5 - remoteInfo - ReactiveCocoa + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + CYLTabBarController-prefix.pch + sourceTree + <group> - 0916C4FA894AA91746D3CD3ECBBCD738 + 072DBFB47B1B2723FC4055B85A65F9B9 + + fileRef + 94DFBADA302CB79810621D9C521AC4C0 + isa + PBXBuildFile + + 079683953F8BCC99F20AB057F852CB84 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference - name - libJSONModel.a + lastKnownFileType + sourcecode.c.h path - libJSONModel.a + Masonry-prefix.pch sourceTree - BUILT_PRODUCTS_DIR + <group> + + 07D3EEF4536A328E668F3376FE2BE336 + + fileRef + 56D2E074E8876B140C4BC52247941163 + isa + PBXBuildFile - 092313CD65C3ADE482E79E26E2506D58 + 080756BFAF462006CA1CB97A3EA1D7AA includeInIndex 1 @@ -377,13 +460,13 @@ lastKnownFileType sourcecode.c.h name - JSONValueTransformer.h + NSDictionary+RACSequenceAdditions.h path - JSONModel/JSONModelTransformations/JSONValueTransformer.h + ReactiveCocoa/NSDictionary+RACSequenceAdditions.h sourceTree <group> - 092886A752FADB6A5E9DB78DE80535D2 + 08183933167568F2C8781986F3FB112E includeInIndex 1 @@ -392,53 +475,79 @@ lastKnownFileType sourcecode.c.h name - UIImage+MultiFormat.h + RACSequence.h path - SDWebImage/UIImage+MultiFormat.h + ReactiveCocoa/RACSequence.h sourceTree <group> - 094A8CD944A7C5AC470D871229D258E0 + 083BA6BFEB763C731F02688780A11EB3 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - XAExtObjcMetamacros.h + NSOrderedSet+RACSequenceAdditions.m path - XAspect/Macros/XAExtObjcMetamacros.h + ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.m sourceTree <group> - 0952286E5EB19BEB47BAD67BEAEAF12A + 08AE94CCA410E8277B7818D0EFAE4965 - containerPortal - D41D8CD98F00B204E9800998ECF8427E + fileRef + 1E094BB001BC4B8DD6D3B8692B0D28C0 isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 53480ED0BE09FF49E34B1702D485CAAB - remoteInfo - Masonry + PBXBuildFile - 099CBCF0599B3B23AAD11286282DDB25 + 090AB1BA1AF90CA206C71ED5E4C1D50D fileRef - 7CFA7F5DB23ABC94ED59EF2F31831B28 + 675304FCB27570FCF0FC8E98745ED10C isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 099B3F21BB953E1498B45D64B9207150 + + children + + 8F52FED3FD52EFFAE58DE8B144084FD3 + CAEE1C9E82CCA7640A2F796D31EFE435 + 4DD08C0B21C162E6D324D90B91E741C2 + C46BCDBFB5F4C6A682212FB8371F8E9C + D0CC9582E84D7B5AE27051053ECA8719 + 13589ACA22C4AED47051D9D4FE80F76F + + isa + PBXGroup + name + NSURLConnection + sourceTree + <group> - 09A3D2D431763E68E628962ED536E86F + 09BE9771A40000839092B7A963CF4D77 fileRef - 7FB0B74829A41DA214F155A35AF931CE + A4BB0C7EADFAD6A1DD1BE9EC3DF0C0A3 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + 09FA060F1A0492FB25232F489AC4E573 @@ -461,43 +570,81 @@ productName JSONModel productReference - 0916C4FA894AA91746D3CD3ECBBCD738 + 94E3EC661536CD989F7D7BA46681D369 productType com.apple.product-type.library.static - 0AABB4C0959E7B394766F3CBA3B7BB18 + 0ABC93F6575931ED410C56908FE082AF - fileRef - 7212BA6189003B1C5E5C937F57187EB6 + includeInIndex + 1 isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACErrorSignal.m + path + ReactiveCocoa/RACErrorSignal.m + sourceTree + <group> - 0B6C5B152C38204C10136BCEB05D3EEA + 0AC2D3A503587DF2175D90EDCB256B34 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - libCYLTabBarController.a + UIWebView+AFNetworking.h path - libCYLTabBarController.a + UIKit+AFNetworking/UIWebView+AFNetworking.h sourceTree - BUILT_PRODUCTS_DIR + <group> + + 0AFD697C1D3464E6DD2AB0D8CCAEF042 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+RACKVOWrapper.m + path + ReactiveCocoa/NSObject+RACKVOWrapper.m + sourceTree + <group> + + 0B41456A54B117D1A529EC96F5BDC9A8 + + buildActionMask + 2147483647 + files + + 881947E477E1D144ED265DF7A998933B + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 0B8F9D22BE0302370E75B416C2572DBA + 0B6A537F797823355E6CD7B3D1AB6691 fileRef - 7FCE6FB5C357AB999AE8A17881F859BE + 5B13BC93E7096A8DFC3B2CA65F53D280 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + 0BD06C4DDA7B80C1742B09DDCF556762 @@ -512,28 +659,21 @@ sourceTree DEVELOPER_DIR - 0BF4AC0E7090CAC0D919A6E0A1A516A6 + 0BE788C3CB3F7E78E23D1D390D939DAB includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UITableViewHeaderFooterView+RACSignalSupport.h + NSEnumerator+RACSequenceAdditions.m path - ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.h + ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m sourceTree <group> - 0C11F8AFE41DAB4312639F7FBA9C7DF8 - - fileRef - 120EFB3237A2D5D7455745B6E282CBEE - isa - PBXBuildFile - 0C1D89EAE68EF4D4ABEDB611EC44AAB0 buildConfigurationList @@ -555,18 +695,11 @@ productName CYLTabBarController productReference - 0B6C5B152C38204C10136BCEB05D3EEA + D42786EB0B73506E279351FA1FCEE0B9 productType com.apple.product-type.library.static - 0CC98B5370BB5B9EB73E4A1856ACB18B - - fileRef - B793FFC7E3BBE870834BBCB42A153059 - isa - PBXBuildFile - - 0CD7F87AEA1C91DBDA95DE57AC9F7579 + 0CD13BB1A191EE2C413094C65571B015 includeInIndex 1 @@ -575,27 +708,13 @@ lastKnownFileType sourcecode.c.objc name - RACValueTransformer.m + UITableViewCell+RACSignalSupport.m path - ReactiveCocoa/RACValueTransformer.m + ReactiveCocoa/UITableViewCell+RACSignalSupport.m sourceTree <group> - 0CF802C3F0EB9A89CD9817E9B850BA86 - - fileRef - C93F8E93788AD6B216F8D684EEDB9FA7 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 0D12B91CB78BF7CD99A66A8D0AF6BD9A + 0D47C7A5E1BF67CDDE0D3DED4C2BF6C4 includeInIndex 1 @@ -604,116 +723,127 @@ lastKnownFileType sourcecode.c.h name - NSString+RACKeyPathUtilities.h + NSObject+RACSelectorSignal.h path - ReactiveCocoa/NSString+RACKeyPathUtilities.h + ReactiveCocoa/NSObject+RACSelectorSignal.h sourceTree <group> - 0D21AF65FBED97A433B38D6666F40AAA + 0E07CAC8A5C9858E30FF5E9AED1BD6AB includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - AFURLConnectionOperation.m + ReactiveCocoa.h path - AFNetworking/AFURLConnectionOperation.m + ReactiveCocoa/ReactiveCocoa.h sourceTree <group> - 0DB63366B7DC9D5E4E7C9F708755B486 + 0E58356CB71EB1AF387189271D790427 + + fileRef + C39AF15B4BFC1DD927679F15E9C317F3 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 0EB8B30A1CC6330B08C57D41E2B7133F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - CYLPlusButton.m + RACEagerSequence.h path - CYLTabBarController/CYLPlusButton.m + ReactiveCocoa/RACEagerSequence.h sourceTree <group> - 0DE232DA7DF9A5C4EDF146731CF8296A + 0EBA43F54C3667374FD70E17C4B437A2 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSObject+RACDeallocating.m + SDWebImageOperation.h path - ReactiveCocoa/NSObject+RACDeallocating.m + SDWebImage/SDWebImageOperation.h sourceTree <group> - 0DE5D74DF3D0A742266736E999B15D1D + 0EF1EFC6D17D4BD6CA61FB47D33E9E0A + fileRef + E798802252FBC085207B7EF5246FD5D4 isa - PBXTargetDependency - name - Masonry - target - 53480ED0BE09FF49E34B1702D485CAAB - targetProxy - 0952286E5EB19BEB47BAD67BEAEAF12A + PBXBuildFile - 0E22F1DDE5ED636BC8CF1792611481B4 + 0F8217A7033D4B1169408CA2DEBFA592 fileRef - 8E4095BD8D528280225FD16D85E8F091 + E798802252FBC085207B7EF5246FD5D4 isa PBXBuildFile - 0EDC6716609A31FDD62A5349137FE307 + 10399E8FB58B02A0100068ABC5DCE9FC - includeInIndex - 1 + fileRef + 6BA10D4286688F83720041C63E248375 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACImmediateScheduler.h - path - ReactiveCocoa/RACImmediateScheduler.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 0F560B4734048E5F6E51CDF94FB54F23 + 10834806BD7B412BC24F347361FA2C8E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - UITextView+RACSignalSupport.m + text.plist.xml path - ReactiveCocoa/UITextView+RACSignalSupport.m + Pods-acknowledgements.plist sourceTree <group> - 0F8217A7033D4B1169408CA2DEBFA592 + 123A1CA8C098ED1247364F1D52378DDF - fileRef - E798802252FBC085207B7EF5246FD5D4 isa - PBXBuildFile + PBXTargetDependency + name + CYLTabBarController + target + 0C1D89EAE68EF4D4ABEDB611EC44AAB0 + targetProxy + B91C1A689286738712B2FC6CD94C37C7 - 0FACEBDD5965A44361C975824A6C6DFB + 1263AF3F3C8A2E150F8ACB065166336C fileRef - 52BF3A8C015B33CB9A15012AEA9221A0 + 24A61D750860359356C16584EF89469C isa PBXBuildFile settings @@ -724,10 +854,26 @@ - 1012DE92B3434EE5A6FB5CAEA2DF2543 + 12773A76172DB52068DDEBBF905E0B2E + + children + + 24C40F9236B53C9C0BE08FC4770CBD38 + 3C854BF73FDA7E07DD3F21F6E7CA31D0 + + isa + PBXGroup + name + SDWebImage + path + SDWebImage + sourceTree + <group> + + 1281F232FEDBF2EA9B3C6B58A83A39AF fileRef - 1361CFA334DAB2F4511DFB1EBE9E5073 + B99E50A56C2E80EB7207069737D1225B isa PBXBuildFile settings @@ -738,71 +884,51 @@ - 102C0BF60B91AF4ADFE25AF4376A6F09 + 128993FF267CC0FA8EE6889C6AEC2EC3 fileRef - FC7FF831376FA8C9100E2C08023F477F + 19D02301BF02838213F24E7F8887821D isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 104AFF1DE2EE972BC6D3F0B9E74F0BAE - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - NSString+RACSupport.h - path - ReactiveCocoa/NSString+RACSupport.h - sourceTree - <group> - - 10834806BD7B412BC24F347361FA2C8E - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - text.plist.xml - path - Pods-acknowledgements.plist - sourceTree - <group> - - 1099625A707D1AEF3646D241CE56B6BE + 133F106C17EB7AC4CF864A83E353ADD4 + fileRef + 84C7FB4EDD986892F01177AECEB92FD1 isa - PBXTargetDependency - name - AFNetworking - target - 410B25DF16EA5C5B3E2698F74F9625FB - targetProxy - 549EB52110708F15C83113B534801B04 + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 10F92B4955961B1F2D4CFCFAAB99E858 + 13589ACA22C4AED47051D9D4FE80F76F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - CYLTabBarController.h + AFURLConnectionOperation.m path - CYLTabBarController/CYLTabBarController.h + AFNetworking/AFURLConnectionOperation.m sourceTree <group> - 111242BA7A0394F3BCD85271AFC4B014 + 13B475B4D0F4B0903F802187F4F2D2A8 fileRef - 4CC249A3418D897E66F56183AFCA84E5 + 75BD3BC18F7C32C1E34AD675CBF9745C isa PBXBuildFile settings @@ -813,7 +939,7 @@ - 120EFB3237A2D5D7455745B6E282CBEE + 143CDB1E69B14E49CA034A39F5194687 includeInIndex 1 @@ -822,61 +948,42 @@ lastKnownFileType sourcecode.c.objc name - NSObject+RACKVOWrapper.m + NSFileHandle+RACSupport.m path - ReactiveCocoa/NSObject+RACKVOWrapper.m + ReactiveCocoa/NSFileHandle+RACSupport.m sourceTree <group> - 128993FF267CC0FA8EE6889C6AEC2EC3 + 14804AF6F665292345A3617B99A3908C fileRef - 91BBF694E9001C762E8DB9185ABE3ADB + B0A088F025B46CF3549CF0EFF4FEE416 isa PBXBuildFile settings - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 + ATTRIBUTES + + Public + - 12B17C4E95BBF046F7AEA9604E00D203 - - fileRef - E798802252FBC085207B7EF5246FD5D4 - isa - PBXBuildFile - - 1361CFA334DAB2F4511DFB1EBE9E5073 + 14AD4534447CBC236698A31895D401F2 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACKVOProxy.h + NSDictionary+RACSequenceAdditions.m path - ReactiveCocoa/RACKVOProxy.h + ReactiveCocoa/NSDictionary+RACSequenceAdditions.m sourceTree <group> - 140834AA8BE1DC77A219D2210F946031 - - fileRef - F3E0BF3FC9B1D5D5AC7BD46E8C386867 - isa - PBXBuildFile - - 140B87BDAA052AF62B194A41BD3F5485 - - fileRef - 7FF4459D624EA5DA86B210B6FE69A8EA - isa - PBXBuildFile - - 1427ED6340412B09D2BF2A59633C7302 + 14D765B9A42437B82B77A38E5B9E8D4B includeInIndex 1 @@ -885,27 +992,13 @@ lastKnownFileType sourcecode.c.h name - RACQueueScheduler+Subclass.h + RACReplaySubject.h path - ReactiveCocoa/RACQueueScheduler+Subclass.h + ReactiveCocoa/RACReplaySubject.h sourceTree <group> - 14804AF6F665292345A3617B99A3908C - - fileRef - 7B10139C1E058D94E92D0617DF8E546E - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 14919C8D2FFE698835E4311BDCF86454 + 14EE2BB2C6D784A106FF1D168C1FD25D includeInIndex 1 @@ -914,31 +1007,31 @@ lastKnownFileType sourcecode.c.h name - RACMulticastConnection.h + RACScheduler+Private.h path - ReactiveCocoa/RACMulticastConnection.h + ReactiveCocoa/RACScheduler+Private.h sourceTree <group> - 14A13A3D04A19FF2940A9A03A5A51B3E + 153E3A7DEF14D7E494AFFA6073638EB6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UISwitch+RACSignalSupport.h + RACReplaySubject.m path - ReactiveCocoa/UISwitch+RACSignalSupport.h + ReactiveCocoa/RACReplaySubject.m sourceTree <group> - 14EB38F86565074EEF730EC50C9E1253 + 15D83D76F23B8E5018830A075363B6E7 fileRef - 4509DF6334860FC19F8A57F6345BF60C + 819F984CC9898B5312ECF9E98583F654 isa PBXBuildFile settings @@ -949,24 +1042,24 @@ - 14F36088FE7ABB760A3F2A77870DD50A + 15DA087E1E156C6B1655764224E69941 fileRef - 9B7D576C1C15271780A65921FD3B351D + B048FB3C43D6C6205466CC99604792E3 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 163E3EC7C5A7B47E57ECC6A6DB5C7EE9 + 168C493007BD91749209739D95E3A9DE fileRef - D45DBCF012C00712D545E78EA25DDD79 + E798802252FBC085207B7EF5246FD5D4 + isa + PBXBuildFile + + 16A189CC65DC66678D3D637ED8B5B5FF + + fileRef + 1F2F2AA47466EE9B72EB785A21775E71 isa PBXBuildFile settings @@ -975,25 +1068,17 @@ -DOS_OBJECT_USE_OBJC=0 - 166AF8E27F5F2151A8AF1B759147B106 + 16CDDCF190EAAC0E91E9C7867C5790A1 - includeInIndex - 1 + fileRef + E798802252FBC085207B7EF5246FD5D4 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACEXTScope.h - path - ReactiveCocoa/extobjc/RACEXTScope.h - sourceTree - <group> + PBXBuildFile - 16A189CC65DC66678D3D637ED8B5B5FF + 17D8C9D90B9DCDE1B8B9D5ECF8DADCEC fileRef - ABB1886E908810BEFE5C77EFD2AD647B + 74ACE91E1BB28EE8AE35E3B58C9D3A3A isa PBXBuildFile settings @@ -1002,7 +1087,7 @@ -DOS_OBJECT_USE_OBJC=0 - 16A3E780C0937600C7C09D0DB3CCBD34 + 1890C07A8BA8839AC3686951BF277AEB includeInIndex 1 @@ -1011,23 +1096,31 @@ lastKnownFileType sourcecode.c.objc name - RACCommand.m + UIProgressView+AFNetworking.m path - ReactiveCocoa/RACCommand.m + UIKit+AFNetworking/UIProgressView+AFNetworking.m sourceTree <group> - 16CDDCF190EAAC0E91E9C7867C5790A1 + 19666C0EDCA9726C17BF976A7F4A32E0 - fileRef - E798802252FBC085207B7EF5246FD5D4 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MASLayoutConstraint.h + path + Masonry/MASLayoutConstraint.h + sourceTree + <group> - 16DCBF02BEB906663B61BD04619BDB7F + 197CE9E4D4ABFA80559B3712ABB04B80 fileRef - F02B853176928C740B241F44B5FB6835 + 3D70BB8CA5FDEB02564B76BC77F516B8 isa PBXBuildFile settings @@ -1038,21 +1131,22 @@ - 173EE70C16AC5AD13EBDD0F34EF5F23F + 19D02301BF02838213F24E7F8887821D - fileRef - 4B9BFF5FC1917D3F67A2A654C2A7EA7E + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + JSONModelArray.m + path + JSONModel/JSONModel/JSONModelArray.m + sourceTree + <group> - 175855F4E67EE3757EA4DDFBF012D699 + 1A6F5266C23C619C54C0477DFE7283AB includeInIndex 1 @@ -1061,16 +1155,16 @@ lastKnownFileType sourcecode.c.h name - UISegmentedControl+RACSignalSupport.h + RACStream.h path - ReactiveCocoa/UISegmentedControl+RACSignalSupport.h + ReactiveCocoa/RACStream.h sourceTree <group> - 17D8C9D90B9DCDE1B8B9D5ECF8DADCEC + 1AA9B819449D239EA31ECFF6ECA1657C fileRef - 89C97B06CF69EC49E69271C0C029419A + 806C455763F0201F34934C508E0DC535 isa PBXBuildFile settings @@ -1079,25 +1173,25 @@ -DOS_OBJECT_USE_OBJC=0 - 1808C2B2A33B77042F352C363AC97BB4 + 1AECA3763F9718961E999D6D0D727222 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACSubscriber.m + CYLConstants.h path - ReactiveCocoa/RACSubscriber.m + CYLTabBarController/CYLConstants.h sourceTree <group> - 1882DE71E7C1D7BEEAE714D388A1A42C + 1B2194539D5324B090DFEA647F98AE97 fileRef - C7F82F3525440A2409D8442F2AEE6EB7 + D09AEC9BB3FEF6DE69C518EBB750C0CE isa PBXBuildFile settings @@ -1108,19 +1202,21 @@ - 18C54F73D160C5DE51EE76A34F4A2D28 + 1B6F846FB0301F1A743248404E457787 fileRef - 2B62DDFD0A35E5F65852939CEF828A9E + D1689D50FB7C92FF4B0E10234FEDE371 isa PBXBuildFile settings - COMPILER_FLAGS - -fno-objc-arc + ATTRIBUTES + + Public + - 1978942A4A36BCAE9997429376A5733C + 1CA299BEF0F2B330A92CFE5FD0759F9C includeInIndex 1 @@ -1129,79 +1225,75 @@ lastKnownFileType sourcecode.c.h name - NSString+RACSequenceAdditions.h + MKAnnotationView+RACSignalSupport.h path - ReactiveCocoa/NSString+RACSequenceAdditions.h + ReactiveCocoa/MKAnnotationView+RACSignalSupport.h sourceTree <group> - 19B9A09BC12D7BB8283B469DB729B2EC + 1CBDB47B210A0C2448C14A610BC6D4D6 fileRef - 5E3C273C72F0DFA9E5F91B3E089AB456 + B39D5AFCAA041CAB23BCBF0A2106C8F2 isa PBXBuildFile - - 1A5BE933196809B7B7E1AD67610EB412 - - includeInIndex - 1 + settings + + ATTRIBUTES + + Public + + + + 1D264E71F9CE1566934BD1E66B808EB5 + + fileRef + B6A22D5E9ECA1D372DBC0790D274EFAC isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACStream.h - path - ReactiveCocoa/RACStream.h - sourceTree - <group> + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 1A8FFA3542A05775083D1E3FD7E8D2A8 + 1D2B4BD756898088A194BDA60C8A935C - includeInIndex - 1 + fileRef + 22D08E3648451771043636DD7DEEE284 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UITextView+RACSignalSupport.h - path - ReactiveCocoa/UITextView+RACSignalSupport.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 1AD05E1CA714ECE615C8565333127E0D + 1D47ED097A3DAD61C001D6FD5485D3B6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACSubscriber+Private.h + RACBehaviorSubject.m path - ReactiveCocoa/RACSubscriber+Private.h + ReactiveCocoa/RACBehaviorSubject.m sourceTree <group> - 1BBD07BAE3377669513EA0D844BC268A + 1DC03790E6AB0AB5E040AE2B14363821 fileRef - A1624D65F362705800EAF879629A1641 + 9662B978A2BF20CC4D967B3E90515DFC isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 1BF33FD9958DE1C010305E6232266C1C + 1E094BB001BC4B8DD6D3B8692B0D28C0 includeInIndex 1 @@ -1209,15 +1301,17 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + RACDisposable.m path - JSPatch-dummy.m + ReactiveCocoa/RACDisposable.m sourceTree <group> - 1CBDB47B210A0C2448C14A610BC6D4D6 + 1E310D0CE3BE27EF253B6D822B0AEE5E fileRef - 2E07A2ED41CC4C210937008043C4B332 + 84A3EE0BF19E2B36FF89FEC07C01A761 isa PBXBuildFile settings @@ -1228,7 +1322,14 @@ - 1D391D61C0A9621E98CB7B5E8E1CBD16 + 1EE384BB828F1AE595D89DC73174B403 + + fileRef + 69ACA4208C1F51ECCB41C7D2864D303D + isa + PBXBuildFile + + 1F10A60D8ECF7A52FF2B6C11977CF151 includeInIndex 1 @@ -1237,13 +1338,13 @@ lastKnownFileType sourcecode.c.objc name - MASConstraint.m + SDWebImageManager.m path - Masonry/MASConstraint.m + SDWebImage/SDWebImageManager.m sourceTree <group> - 1DAE47CB93A8820B8E21C80C65B414FA + 1F2F2AA47466EE9B72EB785A21775E71 includeInIndex 1 @@ -1252,107 +1353,79 @@ lastKnownFileType sourcecode.c.objc name - NSArray+JSONModel.m + JSONModel+networking.m path - JSONModel/JSONModelCategories/NSArray+JSONModel.m + JSONModel/JSONModelNetworking/JSONModel+networking.m sourceTree <group> - 1DCD57EDA9162EAFE9AFEE83B1C8AC2A - - buildActionMask - 2147483647 - files - - 235BBCE3E441111ED80F9AD239D320F9 - 163E3EC7C5A7B47E57ECC6A6DB5C7EE9 - 50777D8BB7008011BB9890F81A5D5B0E - A9A22E6C211491BADD7081F9B81691DD - B2942371B91C653656D0F182C2DB7D53 - 0AABB4C0959E7B394766F3CBA3B7BB18 - 2606F3E90E090D5D1D5D3A49F967B9F4 - 5C24294E2772182CBABB00DE001FE0D9 - F7B307B12425313F4B5EC4656EF68EBF - 9FB21C3EC3C8703D0EE5F7C3CAD95374 - 558820DD61F95F6837416FDB64DD90A3 - 445D199E11BB3B076FA716953CC9D944 - 74A9563003AD0CD00CEAA62AB72D5DC5 - 9350A4E3963BA5156450824AE0841CD8 - 3EEE52AA52A838126D6E32685326602B - - isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 1E310D0CE3BE27EF253B6D822B0AEE5E + 1F61AF68D4FB00039F02EC30594AD211 fileRef - C912F1BE0FB8E0D9CE75EA8F718EA45E + BEC22C108316732DFAD5A8649D25F58F isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 1E3B8678BA98318DA3BDF11BBB8016C6 + 1F81C7BBC0A4A558A5B67954F8FED019 - includeInIndex - 1 + buildConfigurations + + 855F190A3AB2BFDB8F67F2FD637153D6 + 7C89D1A84817BE82CBF7CE79D861C7CD + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release isa - PBXFileReference - name - RACCompoundDisposableProvider.d - path - ReactiveCocoa/RACCompoundDisposableProvider.d - sourceTree - <group> + XCConfigurationList - 1E72E3F0683EF244BE60731D0FFABD52 + 1F9D0A038253F8A4A85191FE2BB38E05 - fileRef - 64D961BC28FF0980169D5D182D46C73B + containerPortal + D41D8CD98F00B204E9800998ECF8427E isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 9A935B6D3AACE527D4DF682DB3C53BDD + remoteInfo + ReactiveCocoa - 1EC1EDEFF2F3CEE160D4FD254D03DE25 + 1FC894FF194E4D3E40ADFB0D919A52B9 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIAlertView+RACSignalSupport.h + NSObject+RACDescription.m path - ReactiveCocoa/UIAlertView+RACSignalSupport.h + ReactiveCocoa/NSObject+RACDescription.m sourceTree <group> - 1F3A0C4393AAABF3702DDD35E4DEE0EF + 1FED0BE0BA4386F2AB014F07CBAA5E0A + children + + 6BF5EAEFA9CA9FA862AF2D37D8D5B7BC + 67B8D1029C75C73F1643114628229333 + 06D9B68E78A4ED4E68016ABE2E86289D + isa - PBXTargetDependency + PBXGroup name - XAspect - target - B995F6C491CD4491EFFB38B22D432FA4 - targetProxy - 9C12E5B34A71CDCAA71A5D3DFA7DC595 + Support Files + path + ../Target Support Files/CYLTabBarController + sourceTree + <group> - 1F50540DA7E31473386BCD577392B993 + 1FFDC86E9668A2B725A5E14834BC864F includeInIndex 1 @@ -1361,28 +1434,28 @@ lastKnownFileType sourcecode.c.h name - AFHTTPSessionManager.h + AFNetworkActivityIndicatorManager.h path - AFNetworking/AFHTTPSessionManager.h + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h sourceTree <group> - 1F721B4A74D3B50494ECAB26EB259DA1 + 206C04450ADF97A54B938ADB00EBBF1F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIActionSheet+RACSignalSupport.m + Masonry.h path - ReactiveCocoa/UIActionSheet+RACSignalSupport.m + Masonry/Masonry.h sourceTree <group> - 1F721BDF91E7B499EDC6BF592E2E3305 + 20ACC301DCCE2788E3FE2B25CB3121DB includeInIndex 1 @@ -1390,12 +1463,14 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + XACrystallization.h path - JSPatch-prefix.pch + XAspect/Core/XACrystallization.h sourceTree <group> - 1F81C7AFD5636DF6C51D2FAEC3D21BC3 + 20C5209E3167276E1F17E266DDB92675 includeInIndex 1 @@ -1404,89 +1479,81 @@ lastKnownFileType sourcecode.c.h name - RACEmptySequence.h + JSONValueTransformer.h path - ReactiveCocoa/RACEmptySequence.h + JSONModel/JSONModelTransformations/JSONValueTransformer.h sourceTree <group> - 1FD825150D8FF10423EFAD474091BF59 + 211D4EA06F5920376A069ACB55DF6006 fileRef - 49A20E37AD655BA2A4C0AEB7A7ACC747 + 8F52FED3FD52EFFAE58DE8B144084FD3 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 201CFBF48EDE533E3BAF73E0E64B9FA0 + 2141A690FDB7C142352CCAD5ECA39C0F - baseConfigurationReference - D68697C739DE55500A7B6FD1FCCF5990 - buildSettings + fileRef + 30A2D35F0E883F713C2AEB4AF8A47637 + isa + PBXBuildFile + settings - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/JSPatch/JSPatch-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - NO - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES + ATTRIBUTES + + Public + + + 216363526676D0071143855BB8AB1A57 + + fileRef + 03306FD17D5572A086255ECDAC692D0D isa - XCBuildConfiguration - name - Release + PBXBuildFile - 20C1FE36F555E0A5B2C83DEE6BEFE47F + 216E5A12ACFD64B84DC1A2E253336D9B - containerPortal - D41D8CD98F00B204E9800998ECF8427E + fileRef + E798802252FBC085207B7EF5246FD5D4 isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 09FA060F1A0492FB25232F489AC4E573 - remoteInfo - JSONModel + PBXBuildFile + + 227C6F50FF69BC84E0366FCB51E13FAB + + isa + PBXTargetDependency + name + Aspects + target + DBC9A0AF6D4571D059D2AF2422F2BD6E + targetProxy + 2319A854193AF121C1CD898FF31BA4E7 - 20D2248D4C8B8FEEA1CE8F92D8746EED + 22A9A674AB7DC5D2FF76B677B213DED1 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - MASCompositeConstraint.m + UIAlertView+AFNetworking.h path - Masonry/MASCompositeConstraint.m + UIKit+AFNetworking/UIAlertView+AFNetworking.h sourceTree <group> - 20E0B451FEA8C21D357EB3EB8620AAD2 - - fileRef - 9D467D19CBA8C5AAB22F37918099FBA6 - isa - PBXBuildFile - - 2101678EE1CAC9906F2C737F1FC9B939 + 22D08E3648451771043636DD7DEEE284 includeInIndex 1 @@ -1495,172 +1562,163 @@ lastKnownFileType sourcecode.c.h name - RACStringSequence.h + NSString+RACKeyPathUtilities.h path - ReactiveCocoa/RACStringSequence.h + ReactiveCocoa/NSString+RACKeyPathUtilities.h sourceTree <group> - 211D4EA06F5920376A069ACB55DF6006 + 2319A854193AF121C1CD898FF31BA4E7 - fileRef - D3C233514075711C6040EA1D4182F48F + containerPortal + D41D8CD98F00B204E9800998ECF8427E isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 216E5A12ACFD64B84DC1A2E253336D9B - - fileRef - E798802252FBC085207B7EF5246FD5D4 - isa - PBXBuildFile - - 21700C06D8FE72A135711E023B3EBC76 - - includeInIndex + PBXContainerItemProxy + proxyType 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - NSObject+RACPropertySubscribing.h - path - ReactiveCocoa/NSObject+RACPropertySubscribing.h - sourceTree - <group> - - 2270594E7C70F13CFAE56D01E4555BF3 - - fileRef - 5D251373B0F6F042640A5DFFE6594BF9 - isa - PBXBuildFile + remoteGlobalIDString + DBC9A0AF6D4571D059D2AF2422F2BD6E + remoteInfo + Aspects - 227AC65587EFD083286F0C1E386B251C + 23530EDB822FDDE0339E09D976220909 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACScopedDisposable.h + NSInvocation+RACTypeParsing.m path - ReactiveCocoa/RACScopedDisposable.h + ReactiveCocoa/NSInvocation+RACTypeParsing.m sourceTree <group> - 227C99ED20E9BAB5A772AB25937A7256 - - fileRef - CD843B00B812E8A0F72FE1FE9734BA27 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 23379D081E9ABB25B5C2841C3732BE3C + 24033AEA24A4232754B0FF455FDFA2E2 - includeInIndex - 1 + buildConfigurationList + ACBEBDA40B2AD70BCD4327B7E5D81D80 + buildPhases + + 0B41456A54B117D1A529EC96F5BDC9A8 + 30F57F7991C6559EAFA08D25FCF6556C + + buildRules + + dependencies + + 829DC7ED7E34A0152C4EDADFB8F3835D + 227C6F50FF69BC84E0366FCB51E13FAB + 123A1CA8C098ED1247364F1D52378DDF + 02AAB748D205E13648BE463C0F7FE910 + EFB818120A8A60620138DB3835BFAB85 + 01B3D7E0E9D4C2A1A24152A732B8C72F + ABF1D5A5AD9A387B49D77C61E11E8A6A + F6934BC9C81809F660C462C082D63614 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXNativeTarget name - RACBlockTrampoline.h - path - ReactiveCocoa/RACBlockTrampoline.h - sourceTree - <group> - - 235BBCE3E441111ED80F9AD239D320F9 - - fileRef - 7C273E9B543895B35DAF411ED5A56EE2 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + Pods + productName + Pods + productReference + 3D06057B737713403EA64DC89536AA1A + productType + com.apple.product-type.library.static - 239FB2B346B31E34E553402848248712 + 2466FC54A44F1DC257D1021AF7B4A8DD - includeInIndex - 1 + children + + FF1741BE56FD6460B06F37F6EABA351B + 4DFA6D7D6C9C1E2E556F38770032191D + 92F113ED05E1D254FF29489901ABEDA8 + A5AB135DAA1AA93F36BBD2DB2D796991 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - RACUnit.m + XAspect path - ReactiveCocoa/RACUnit.m + XAspect sourceTree <group> - 243C8D42E812E7176AD1B8E1922F13F0 + 249B69A2A3999EA1D14701B0FAAEB5EC includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSDictionary+RACSequenceAdditions.m + RACKVOProxy.h path - ReactiveCocoa/NSDictionary+RACSequenceAdditions.m + ReactiveCocoa/RACKVOProxy.h sourceTree <group> - 2473F9ABF7786DAADFBB9FA54E432852 + 24A61D750860359356C16584EF89469C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - JSONModel.m + UIBarButtonItem+RACCommandSupport.h path - JSONModel/JSONModel/JSONModel.m + ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h sourceTree <group> - 249A50DF25C576887DE7B90A3C06C0C5 + 24C40F9236B53C9C0BE08FC4770CBD38 - includeInIndex - 1 + children + + 97B266E91D2102E8906C8A6AA8F69F83 + 4621947EF9EE514EC0E7DEDEDC287B07 + 567A662A94B17F76035960CAC8926339 + DFA572E19AAB833058879FFCB2542CAB + 911C771FEAEFFD1AF5B2C468EA72DABB + 806C455763F0201F34934C508E0DC535 + C56A7AB7D7ED6C3346A3BF10ADBC8EFF + B4664FA8372B7CD58714C6A28F165B9E + 9C1253E47A1EA2670E5136F8216924DB + E6CA760B5394495E519115B0AB6C3DD9 + BB312BC3F8EB1727EBD62393D9CE870D + 52B172DACAD83B36862AE4FD13B2EA9B + 735843161B754292F8061E3F63C071C5 + 1F10A60D8ECF7A52FF2B6C11977CF151 + 0EBA43F54C3667374FD70E17C4B437A2 + B7829DA442DED671B644E2881F1925BE + 023127DD998B06C63F956271B9999FB8 + 734A04097CA3CF6720EE747B9D5D62A1 + B6A22D5E9ECA1D372DBC0790D274EFAC + B99E50A56C2E80EB7207069737D1225B + D26C82F0149EE994C17E003C3CA3C96C + 3173AA738305CC0BE07E6603709A8E19 + DAB25E48FD64C97812C36A5B69F837E3 + 009AC949FCDF3A0058063D295100D7C8 + B5281F66A21D235BBFBEB4D43FF85466 + DB88B0D560024D1484A08A232F03F53A + 95CAFC402263DD52A7417D95B73E9729 + 44442DF5806C05C072F5B6565F9E4C8B + 598B77BA5B514764BBDF71F12E23CA1C + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - RACScheduler.m - path - ReactiveCocoa/RACScheduler.m + Core sourceTree <group> - 24DACDB716D0D65FB76383CE0AD6B7CE + 267FD3AFADCF12800AF3DAB8E3B7C89D includeInIndex 1 @@ -1669,88 +1727,39 @@ lastKnownFileType sourcecode.c.h name - SDWebImageDownloaderOperation.h - path - SDWebImage/SDWebImageDownloaderOperation.h - sourceTree - <group> - - 2540DE235D6AB8FABDEE8086C064476A - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - NSLayoutConstraint+MASDebugAdditions.m + JSONModelLib.h path - Masonry/NSLayoutConstraint+MASDebugAdditions.m + JSONModel/JSONModelLib.h sourceTree <group> - 2577EAA643A58B7C32375D37068F9D3B - - explicitFileType - archive.ar - includeInIndex - 0 - isa - PBXFileReference - name - libSDWebImage.a - path - libSDWebImage.a - sourceTree - BUILT_PRODUCTS_DIR - - 2606F3E90E090D5D1D5D3A49F967B9F4 + 26BA5D9D9C21E0CD257557E262FB3E8A fileRef - FFFBC385AE074ECF5DEE7254C05D04D1 + EAFD9C93CC8085D2F07483DAD42AB781 isa PBXBuildFile settings - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 + ATTRIBUTES + + Public + - 262813BD98A538C26EB573D0E6847E90 - - containerPortal - D41D8CD98F00B204E9800998ECF8427E - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - FD1D53461DE538B7C8DFE0B76D857587 - remoteInfo - JSPatch - - 266B4A862FADF8F742BE61443E0BFFE4 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - NSOrderedSet+RACSequenceAdditions.h - path - ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.h - sourceTree - <group> - - 26BB4FEAB632089BB12D38E317DBB091 + 271EBE09FBE0D7A90772DC71895CAE9D fileRef - 854DB078283F3726E7263A22AB81F1C7 + 30B546A5FD13E84829437967FBD5FFDF isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + 272643F56613CA0D336AE3DBF19DC404 @@ -1765,7 +1774,7 @@ sourceTree <group> - 27315171369949FC91F6841DC8AE5C11 + 273AFE3662E49F40E4CF533147A8403B includeInIndex 1 @@ -1774,26 +1783,24 @@ lastKnownFileType sourcecode.c.h name - SDWebImageCompat.h + NSURLConnection+RACSupport.h path - SDWebImage/SDWebImageCompat.h + ReactiveCocoa/NSURLConnection+RACSupport.h sourceTree <group> - 2787CE701C0E32211602A41251973DB3 + 2749A6494ED1B95F537D65BD004F92FE - includeInIndex - 1 + buildActionMask + 2147483647 + files + + 0EF1EFC6D17D4BD6CA61FB47D33E9E0A + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - NSArray+MASShorthandAdditions.h - path - Masonry/NSArray+MASShorthandAdditions.h - sourceTree - <group> + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 27AE61FBDA1BAB9F55981834BF3927CD @@ -1808,18 +1815,18 @@ sourceTree DEVELOPER_DIR - 27B195A66BA2975721D58D7D73A4B764 + 27E4264B68067CFF369F4D19682FA599 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACReturnSignal.m + UIViewController+CYLTabBarControllerExtention.h path - ReactiveCocoa/RACReturnSignal.m + CYLTabBarController/UIViewController+CYLTabBarControllerExtention.h sourceTree <group> @@ -1840,7 +1847,7 @@ runOnlyForDeploymentPostprocessing 0 - 2829A21EC74C7D473B3F7D03296937B0 + 28B3735D05F98097DB382C1EF7AF13F5 includeInIndex 1 @@ -1848,36 +1855,41 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - NSUserDefaults+RACSupport.h path - ReactiveCocoa/NSUserDefaults+RACSupport.h + ReactiveCocoa-prefix.pch sourceTree <group> - 283E771991494A2B96E2BBCE637D6390 + 28D80F8E081C91AF857CB10D6B115758 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACSerialDisposable.m + AFURLSessionManager.h path - ReactiveCocoa/RACSerialDisposable.m + AFNetworking/AFURLSessionManager.h sourceTree <group> - 2841B4168F5F6452653DE47EDEC70B00 + 2905381350CEFFBFFA9BC8B5D027F190 fileRef - 3AEA1559B669E7636EA759427C752604 + DCA45A7F9A436DC2BEDAC0AD26C65BAB isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 2882B29F5EBCE5F56C70A9BA592A80C8 + 2907BD39C74E60F0FDD942123AF9D143 includeInIndex 1 @@ -1886,43 +1898,31 @@ lastKnownFileType sourcecode.c.h name - RACScheduler+Subclass.h + RACDelegateProxy.h path - ReactiveCocoa/RACScheduler+Subclass.h + ReactiveCocoa/RACDelegateProxy.h sourceTree <group> - 2905381350CEFFBFFA9BC8B5D027F190 + 295D6E1DBF9FAA857725CE5884BDEC83 - fileRef - 7BC207DADFD902C9E0F9E6C8749A426D + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 29184003153D7874E68992FCB4C8EDDB - - containerPortal - D41D8CD98F00B204E9800998ECF8427E - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 0C1D89EAE68EF4D4ABEDB611EC44AAB0 - remoteInfo - CYLTabBarController + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSSet+RACSequenceAdditions.m + path + ReactiveCocoa/NSSet+RACSequenceAdditions.m + sourceTree + <group> 2979E54C4AFD27076576E82ADEED2F00 fileRef - 380FDEAE4D9EF40B76E1C9F0BFF14E39 + 364B47625B5A6016FD04DF7BC35E31C4 isa PBXBuildFile settings @@ -1933,74 +1933,37 @@ - 2A096C86942CC895EA812CB46F269472 - - children - - 1F50540DA7E31473386BCD577392B993 - 2A41D496FE3E9576E4EDEAC9EC84A2CA - 2B7CFB5A6E4A5548C8B4DA17DA35B01C - 9FF7B15B9B58DC7A83404A0D9C5C54B0 - - isa - PBXGroup - name - NSURLSession - sourceTree - <group> - - 2A29B9901845547F2855DE837562CC10 - - fileRef - 1808C2B2A33B77042F352C363AC97BB4 - isa - PBXBuildFile - - 2A41D496FE3E9576E4EDEAC9EC84A2CA + 299011B619A00EBC8E4017C8C65D5AE0 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - AFHTTPSessionManager.m + RACEmptySequence.h path - AFNetworking/AFHTTPSessionManager.m + ReactiveCocoa/RACEmptySequence.h sourceTree <group> - 2A8C2C1BA962C825F2F8D04CDBB5649E - - fileRef - 69D3AFBA28E3FD4F7EA643CE40728F27 - isa - PBXBuildFile - - 2B5518F5D8E2D7C4F17B86BF27196257 - - fileRef - 318EB9DB0FE9C89496A38CE3FF6A616E - isa - PBXBuildFile - - 2B62DDFD0A35E5F65852939CEF828A9E + 29E728C49794360ABDC8BBF02D053E99 + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.objc name - RACObjCRuntime.m + libReactiveCocoa.a path - ReactiveCocoa/RACObjCRuntime.m + libReactiveCocoa.a sourceTree - <group> + BUILT_PRODUCTS_DIR - 2B675FE7BE27BF4A88FACDEC5C041CCC + 29F4E625003F95F249CAE42723A20CFC includeInIndex 1 @@ -2009,31 +1972,31 @@ lastKnownFileType sourcecode.c.objc name - RACTupleSequence.m + RACScopedDisposable.m path - ReactiveCocoa/RACTupleSequence.m + ReactiveCocoa/RACScopedDisposable.m sourceTree <group> - 2B7CFB5A6E4A5548C8B4DA17DA35B01C + 2A1D3F97B2BE40F6F3A8892047D86035 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFURLSessionManager.h + AFURLSessionManager.m path - AFNetworking/AFURLSessionManager.h + AFNetworking/AFURLSessionManager.m sourceTree <group> 2B8269A87473D9F1259E9BD98E7588D3 fileRef - EC440A5421781218D66C3DA94AAD9F7E + D4FA8C3887E2B0E18FAC76CD493A9DE4 isa PBXBuildFile settings @@ -2044,25 +2007,10 @@ - 2C397EF1FF5C3F34C812BCEFF39C429A - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACTestScheduler.h - path - ReactiveCocoa/RACTestScheduler.h - sourceTree - <group> - 2C5CBD3A72085FEB008264874E65D26A baseConfigurationReference - 62025C7C78033BDE974F2B6D80D47C55 + 741BF78A50444622EEC3602E1EBD1DD6 buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -2093,26 +2041,75 @@ name Release + 2C6212271F8703B449D650005C31AD0A + + fileRef + 1CA299BEF0F2B330A92CFE5FD0759F9C + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 2CBA7A14A1C2AF1E22C50E6CE482BD55 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSIndexSet+RACSequenceAdditions.h + path + ReactiveCocoa/NSIndexSet+RACSequenceAdditions.h + sourceTree + <group> + 2CC4F56F95BAD6706291C68A5E65EE84 fileRef - 375C7C6AFA6E0BD37F3EDB31BEF42F3C + D75A579A255FA3FD070FD33E85C6F24B isa PBXBuildFile 2CF66E8669A348C421E93F2F67C6A61E fileRef - 2A41D496FE3E9576E4EDEAC9EC84A2CA + 057F7CE354F1F79F8F5A3C146C834B82 isa PBXBuildFile - 2CF6C1779F523346732DDD5A481525C2 + 2CF9FBC4489F08B20D878E03F666B249 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Masonry-dummy.m + sourceTree + <group> + + 2D551CABFBF39AAF69CDA0EF999D0E18 fileRef - 6509BE6630BA341AA28BF274D5CFE776 + FF1741BE56FD6460B06F37F6EABA351B isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + 2D8E8EC45A3A1A1D94AE762CB5028504 @@ -2128,10 +2125,10 @@ isa XCConfigurationList - 2DE94C0E5BDE173486D89658787EC099 + 2DE89A588059B947410B1E0B2FB3605B fileRef - D128BA5BEE4A598E09EFC2652AE98D2C + B261D888D53B9D2390374ECFEC786B9B isa PBXBuildFile settings @@ -2142,7 +2139,47 @@ - 2DEF2C4BF657F898F81DEFF23D313EC6 + 2F0339239226224B0EBE362FBEC90A24 + + fileRef + C9D5B5CB412625215188D92B7A7383C6 + isa + PBXBuildFile + + 2F3459930FBF7274B61EE83899FC5703 + + fileRef + E798802252FBC085207B7EF5246FD5D4 + isa + PBXBuildFile + + 2F85D170E76C661AB0D9E9A8B206C78D + + fileRef + E798802252FBC085207B7EF5246FD5D4 + isa + PBXBuildFile + + 2FC06DD1461305DDFBAD5D3E9005BEF6 + + fileRef + 95CAFC402263DD52A7417D95B73E9729 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 3033C63AC334D346E9461D0942D8FB69 + + fileRef + 713D0E466D846A783F4E86DDEFC8BFD3 + isa + PBXBuildFile + + 30A2D35F0E883F713C2AEB4AF8A47637 includeInIndex 1 @@ -2151,26 +2188,13 @@ lastKnownFileType sourcecode.c.h name - UIView+WebCacheOperation.h + RACEXTRuntimeExtensions.h path - SDWebImage/UIView+WebCacheOperation.h - sourceTree - <group> - - 2DF80ED2E50ED5C37521FBA2B7A17D92 - - children - - 8E75EAD764BF726B7A61971ED67507DD - - isa - PBXGroup - name - Frameworks + ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.h sourceTree <group> - 2E07A2ED41CC4C210937008043C4B332 + 30B546A5FD13E84829437967FBD5FFDF includeInIndex 1 @@ -2179,31 +2203,31 @@ lastKnownFileType sourcecode.c.h name - AFSecurityPolicy.h + UIControl+RACSignalSupportPrivate.h path - AFNetworking/AFSecurityPolicy.h + ReactiveCocoa/UIControl+RACSignalSupportPrivate.h sourceTree <group> - 2E9908333E3087BD7341A44CD11F801A + 30C5085BB18CAB3AC2BF72421A1920E9 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - MASLayoutConstraint.m + RACTuple.h path - Masonry/MASLayoutConstraint.m + ReactiveCocoa/RACTuple.h sourceTree <group> - 2EA5EFA46CE39784B9AD700882444F0A + 30D84A6F9B2F3E016CCEAD524AD5EBFA fileRef - 43BC8AFBABA6F0B2F0335334231D6F8E + 49C02A3B831B982B78163EC10EF0D33E isa PBXBuildFile settings @@ -2214,36 +2238,33 @@ - 2F2C87C497B0D64D96372D87D03850BC - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - SDWebImagePrefetcher.m - path - SDWebImage/SDWebImagePrefetcher.m - sourceTree - <group> - - 2F85D170E76C661AB0D9E9A8B206C78D + 30F57F7991C6559EAFA08D25FCF6556C - fileRef - E798802252FBC085207B7EF5246FD5D4 + buildActionMask + 2147483647 + files + + 168C493007BD91749209739D95E3A9DE + isa - PBXBuildFile + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 3033C63AC334D346E9461D0942D8FB69 + 310ABB239CF60D033312438242D4AD2F - fileRef - 9C0B98B295B045EDBB4C4C830D101C6E + buildActionMask + 2147483647 + files + + 16CDDCF190EAAC0E91E9C7867C5790A1 + isa - PBXBuildFile + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 3036C5663F553FD2A22AD6B74961059A + 3173AA738305CC0BE07E6603709A8E19 includeInIndex 1 @@ -2252,20 +2273,13 @@ lastKnownFileType sourcecode.c.h name - UIImagePickerController+RACSignalSupport.h + UIImage+MultiFormat.h path - ReactiveCocoa/UIImagePickerController+RACSignalSupport.h + SDWebImage/UIImage+MultiFormat.h sourceTree <group> - 304CD204412EE5C882A771B88A801D44 - - fileRef - 411145FA9BE020CC0E000A036879ABB6 - isa - PBXBuildFile - - 30AA5F397CE54C4A547BA63A1D5E9DA6 + 319DA3C4AD1CA0D7724534142424E6B5 includeInIndex 1 @@ -2274,155 +2288,69 @@ lastKnownFileType sourcecode.c.objc name - UIImageView+WebCache.m + NSLayoutConstraint+MASDebugAdditions.m path - SDWebImage/UIImageView+WebCache.m + Masonry/NSLayoutConstraint+MASDebugAdditions.m sourceTree <group> - 30CAB99159D131299142A59ABE5461C4 + 32B858CF09199FB109685F306D190C38 - buildActionMask - 2147483647 - files + buildConfigurationList + 72FA5359D02494B65F8FA39A3EDB1105 + buildPhases - 173EE70C16AC5AD13EBDD0F34EF5F23F - FCE5C18C12E02BA55788BCC2D8D32BD1 - B85FBB6D7E49C61E5270EF4485F255AE - 14EB38F86565074EEF730EC50C9E1253 - 9A14AEF21660FE99D59C768B7CE7D3F1 - 3D04A99E9EA5FCC02667DA865C677191 - FAC1777451F4CF9AC6712170B22847B3 - A5DF5D2B2F2CD7CDFB5DBAAE572D0A1A - 79BFBE9732F0C0FAA510FD4F42952A23 - FED068C67D733208A64F4953026881B6 - CFA8A2398FEFAC14A69F9C3AAB3C89D5 - C8F81A30A1484015DEE5D84613C982B2 - 357567251FE98D3F1296E792EB5D22FE - D8F1A2BEF3DCA1DF604868EC71FEA1D4 - 0CF802C3F0EB9A89CD9817E9B850BA86 - 75BC3C18F37656F0FD2FD6ABC00E6BC1 - E317BE629C3618780960E1E95F206B06 - FEA4EB466A8EB01D17216878C9EFF90E - 5324DEF148D035F75420164C52255C88 - B57DA85175B1136F0C479F699E6789CC - 84AEF8CADF8AF9473815C761E9976E30 - ADC1897042CF15753B9EF3672B9ACE2F - C1453BDD59B774566354DEA20C02B55B - D40351ECDACAA431D087799077D87DF4 - DD66D5E4E2B231622D52276A052755BE - 227C99ED20E9BAB5A772AB25937A7256 - 14F36088FE7ABB760A3F2A77870DD50A - B4B399D6B6BD36800388C38DF514C523 - E3C50525D0EAEA67317369A02774E83E - 927CCA43EF2C9947DD889F8B13323E49 - 632A39BA3F9D70C0BD101E359A1AC231 - EF826E8CB4E61D957E5D6F6A4779DF30 - FBB0541077071EFAE01C2B06AB233CB5 - A47603AB3B3B2993FD5BADBB2590CA1C - 43E99EDD475D70A05A3140E0428E4B0E - 3542AA48A04B291C6FA8DC8E689991BC - 111242BA7A0394F3BCD85271AFC4B014 - 1BBD07BAE3377669513EA0D844BC268A - 847915BA4276EF30B713250A574C78A9 - 604CBAE3DC780CF18CB503A744D86B86 - A7B4D2FF6B848AD8A0E03D15242E63E1 - 310BBAA5DB868956EC40035DB5DB7816 - C46D032E779A9A0460C48DE7D7E2EF01 - FDAA52691B534B5F48185CA2B84BE0AE - 1012DE92B3434EE5A6FB5CAEA2DF2543 - E368EA7D0BE0C0B2133A5F5BFC232329 - A968BA1D626D3AA22F4A35EB75E659F1 - CF898DCC51D0B128217B1CB345014375 - 7603E1889EADD4D3C15E68C049444BE0 - 94303F2C3BD5644DE648E1B0658E5A47 - D583239E3286B94DA3F2CCCAC386E907 - 649FF807928997233B038A6E36B44EA6 - BBAA8D4BFEB1EF83EEFA9E8DC464EBE3 - 668B6BE66CAB748280DE10AF4F3B3459 - 2EA5EFA46CE39784B9AD700882444F0A - 07A92093C5F89FAE84540DECC939FFDF - 68A676CA9611F12A731685F671246F1B - 63B1F71E874C62729356BB6BA70B81BA - 3DCCC6A9D36EC0F64CC4D370155BDE20 - FC7D8F0AE042206281D80363E9920224 - 9258D8E7B9E9A8A1744B0ED65722787D - 6A5696ABF473C9BF45B27A0566F3EADD - 349F24A97365C916E240961F118A7DC9 - EFE24904C5DA3409D8B4583BE1DAB653 - AC5CD16DC4AE8ED5CACAA2518DA3073D - 04D2900C9DBB15D9F8F5BAD7A256C442 - F14DE15041F277E1CB02818F551857B5 - BFAE693DAAF8358EF4B63138D24773BB - 6DBF47AC3273F90C0F0DF4840AA26E76 - AC2DE229068B7B763CBD524DFD156E9F - A0282FCE5A0EA8EC2131588765DF88E9 - BD906B445A4095AD878131A63038A65C - D1906A0AD640EB43CE6915914B23AC53 - BE2BB54978E18C9CB0472402EB722F1D - F9575F63C631FB07CA73C4567D3D9DA0 - A35FCBFEC2F7C54730C1499320CBFDD7 - C34EC341C42C03679C4D189B4B545BD5 - 935C4A7A0B5836543F89569B896C92B8 - 98B2014378B7D9E855152692C8D12446 - 57ED99A6F43DEC496661366FE7289BE4 - AB1FC1B98EC87E9A74EE8930C501F619 - F0B02EB9DD33ACB53286BC5521FAFF14 - 0FACEBDD5965A44361C975824A6C6DFB - C5A3B5E4AF4CC833A8A862DCD5968428 - 16DCBF02BEB906663B61BD04619BDB7F - 1882DE71E7C1D7BEEAE714D388A1A42C - C2F80B454486352D3A1468370B9B67C2 - 929F930153EA56D0CF95872B3A4F857F - 3AF3D1036B7EB37320F5AAEECBFA33FD - BF805FEC28212F40516FE26B1BF8C372 - 1E72E3F0683EF244BE60731D0FFABD52 - D0C47D9B5493D9078FCA5F8E8A1AE4CD - 8A87C09FB34F52F2554A242ADA7DBEB2 - D4DE18E47EB116337574B300EF2DDA9E - ADC08A90E61AC49D87EDCD039A238A4C - 32D7E33715168757A6943D3AD8F75E33 - 3B1E22D2D4C556DFA06897C5E9B8CEC5 - 82FBF13B0E7469CDB0563DC89D54FC12 - 3A28400B15F6655653C4D09D2072D651 + DBBE26BB77A044E5F7DDE107F6D3B655 + E81F41420E62D41FCEE540A57838396E + DD26E7CE35356848D36F859800E4EC2C - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 + buildRules + + dependencies + + isa + PBXNativeTarget + name + SDWebImage + productName + SDWebImage + productReference + D05C466FB318D96070003E32C3FD0EFD + productType + com.apple.product-type.library.static - 30D377C733F30186EA2D73B73E56E053 + 3311C026F41413D4A8B6F47D772F5F63 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFURLConnectionOperation.h + MASLayoutConstraint.m path - AFNetworking/AFURLConnectionOperation.h + Masonry/MASLayoutConstraint.m sourceTree <group> - 310ABB239CF60D033312438242D4AD2F + 3315F33B1B77126B68CCFF1FAF187B0B - buildActionMask - 2147483647 - files - - 16CDDCF190EAAC0E91E9C7867C5790A1 - + includeInIndex + 1 isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXFileReference + lastKnownFileType + archive.ar + path + libGeTuiSdk-1.5.0.a + sourceTree + <group> - 310BBAA5DB868956EC40035DB5DB7816 + 331718BFB4A91CFFE026492905231562 fileRef - 0EDC6716609A31FDD62A5349137FE307 + 5C5A5F9BD67F2AD265A236C4C592107E isa PBXBuildFile settings @@ -2433,22 +2361,14 @@ - 318EB9DB0FE9C89496A38CE3FF6A616E + 335DCBC17D2469F228020EF6C7B41F7C - includeInIndex - 1 + fileRef + EB6683FC3260150506801302AD17C926 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIAlertView+RACSignalSupport.m - path - ReactiveCocoa/UIAlertView+RACSignalSupport.m - sourceTree - <group> + PBXBuildFile - 31BCD314D8CE512714D93706A0A3B3DC + 336B1E6E8484ECB8832FF08AF4325EBF includeInIndex 1 @@ -2456,21 +2376,12 @@ PBXFileReference lastKnownFileType sourcecode.c.objc - name - RACKVOChannel.m path - ReactiveCocoa/RACKVOChannel.m + JSONModel-dummy.m sourceTree <group> - 31E0E3D2D0FFD314985BC551FA85C163 - - fileRef - 1F721B4A74D3B50494ECAB26EB259DA1 - isa - PBXBuildFile - - 320C9608B1813EB3CCAD3DAE5D053886 + 3378C8AD2EF891AE0AF4915F6ACD4032 includeInIndex 1 @@ -2478,92 +2389,30 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - JSONModelArray.h path - JSONModel/JSONModel/JSONModelArray.h + JSONModel-prefix.pch sourceTree <group> - 3283ED0D6AC39771F2FB56070C414677 - - fileRef - 4C8663B3ABB37A09529A40E2BF230F84 - isa - PBXBuildFile - - 32D7E33715168757A6943D3AD8F75E33 - - fileRef - F739D150BC139BBFC781BC5FF683F53F - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 331718BFB4A91CFFE026492905231562 - - fileRef - FF42A8789D18FAD4AF9A46051584CD05 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 3338FCB398A34E05B12CFDE619BD88C4 - - isa - PBXTargetDependency - name - JSONModel - target - 09FA060F1A0492FB25232F489AC4E573 - targetProxy - 20C1FE36F555E0A5B2C83DEE6BEFE47F - - 335DCBC17D2469F228020EF6C7B41F7C - - fileRef - 45EFCB171CA7F7314B3171C0011DF29E - isa - PBXBuildFile - - 3381F12C163CA27DAB6C05AB64098D9E + 342B293E2F15B3DF835525E4183DAA8F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIDatePicker+RACSignalSupport.m + RACSubscriber+Private.h path - ReactiveCocoa/UIDatePicker+RACSignalSupport.m + ReactiveCocoa/RACSubscriber+Private.h sourceTree <group> - 344DB5E27F667A528595D40A52338169 - - fileRef - 5ECFF58439CAB75C3D9A52A722AD320B - isa - PBXBuildFile - - 349F24A97365C916E240961F118A7DC9 + 3541BDAEDC5B923485A0172D47B2CCFE fileRef - DA0FB964F98DBBB51E94B0A6C3A0AC9A + D9A184DCB54CBAF2585073657BF85DA2 isa PBXBuildFile settings @@ -2574,7 +2423,7 @@ - 34E3C23774C3F071C360A95E781D5C0A + 35C9733730903336A1E774698B6C7C4E includeInIndex 1 @@ -2583,16 +2432,16 @@ lastKnownFileType sourcecode.c.h name - RACUnarySequence.h + NSOrderedSet+RACSequenceAdditions.h path - ReactiveCocoa/RACUnarySequence.h + ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.h sourceTree <group> - 3542AA48A04B291C6FA8DC8E689991BC + 36352F2581739076A60FEB0E8E8E9317 fileRef - F3FB6F90335365FFF935B4FB91F5D94A + 78EE318D7701BC658F2ABDA07708B7C0 isa PBXBuildFile settings @@ -2603,142 +2452,43 @@ - 357567251FE98D3F1296E792EB5D22FE - - fileRef - C30865260F1AA88E2CCC8258DD8F5C5F - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 359D1ECCC89304F4A8F821C51121AF64 + 364B47625B5A6016FD04DF7BC35E31C4 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - JSPatch.js + NSLayoutConstraint+MASDebugAdditions.h path - JSPatch/JSPatch.js + Masonry/NSLayoutConstraint+MASDebugAdditions.h sourceTree <group> - 35F21F926D9A165521BF874A38D9FDB6 + 36916CF5DA1FE373970D2D502ED8C866 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIDatePicker+RACSignalSupport.h - path - ReactiveCocoa/UIDatePicker+RACSignalSupport.h - sourceTree - <group> - - 35FD08A7594776E99EBDB2276B282532 - - children - - BB5406E50F64CC1977954CD5228C8B81 - 9C0B98B295B045EDBB4C4C830D101C6E - C912F1BE0FB8E0D9CE75EA8F718EA45E - 42AA6E2A1E2F248A8025078B457ADE4F - - isa - PBXGroup - name - Serialization - sourceTree - <group> - - 3627EC5EB57BDEC23FA1FE15CE9B0B1D - - children - - E7B66D448FF3C7D3F5B049918A9BED7B - 43D7AFEEA1462E59880E023A7F5226BD - 0DB63366B7DC9D5E4E7C9F708755B486 - 7B10139C1E058D94E92D0617DF8E546E - E6EF7EE978A5191A9BB4FC5BDE0D60CC - 10F92B4955961B1F2D4CFCFAAB99E858 - 375C7C6AFA6E0BD37F3EDB31BEF42F3C - FCC32E4089B93933079F7040E4A7491E - 7105BBEE0C908BB9E862D6102DB7E3FF - E1567B114544F0E220C2D236D3A47E82 - - isa - PBXGroup + sourcecode.c.objc name - CYLTabBarController + RACPassthroughSubscriber.m path - CYLTabBarController + ReactiveCocoa/RACPassthroughSubscriber.m sourceTree <group> - 3690256E0F99DB05CD807419A1A05648 - - buildActionMask - 2147483647 - files - - BF940DBDB6B4DCCF226F6DC35983D307 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 36C43111876FF992816ECB7AF602E9D2 + 372DA6BA104FB86618A05E951C75A497 fileRef - EBA69E8FAA01CBD798D4F6C67B0DD981 + 7EECED4464BFD6C89FDB21CC4B759B0C isa PBXBuildFile - 37132430457D61938FCD620DE393009A - - buildConfigurationList - 529ED9818F1C7EC4B6A61D8863918EFD - buildPhases - - FD1A9D19CF02957A5C755BDED2F42F34 - 8518D32C8FB5FBA25CB73B3A13996882 - - buildRules - - dependencies - - 1099625A707D1AEF3646D241CE56B6BE - AB3B17E9CBA0E18485A5E995F953D701 - 8DE86437BD942A6415E7DFBCD3C2C526 - 3338FCB398A34E05B12CFDE619BD88C4 - 7DB3BF7529485C2C2A5FCEF174EA6C70 - 0DE5D74DF3D0A742266736E999B15D1D - FFCE83538E61E9B07A77FC1494D5DF55 - 5CB179AD935F8C7BA8F743AE0EDA93EF - 1F3A0C4393AAABF3702DDD35E4DEE0EF - - isa - PBXNativeTarget - name - Pods - productName - Pods - productReference - 94A83BD33AFCDC59F41573552F1D6EB7 - productType - com.apple.product-type.library.static - 375AE8DDF76E5AEE2565EDAB8B8FC134 isa @@ -2752,22 +2502,7 @@ sourceTree DEVELOPER_DIR - 375C7C6AFA6E0BD37F3EDB31BEF42F3C - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - CYLTabBarController.m - path - CYLTabBarController/CYLTabBarController.m - sourceTree - <group> - - 37CFFEB82DEEBCA425430E49FDB46660 + 37A576FA7C2A130D99739CBAA80BAED9 includeInIndex 1 @@ -2775,8 +2510,10 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + RACSubscriptionScheduler.h path - JSONModel-prefix.pch + ReactiveCocoa/RACSubscriptionScheduler.h sourceTree <group> @@ -2793,37 +2530,49 @@ sourceTree <group> - 380FDEAE4D9EF40B76E1C9F0BFF14E39 + 382C10F59BDBD1E36CCD0768F5C3B087 + + fileRef + DAB25E48FD64C97812C36A5B69F837E3 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 3853F138C9D4EEEC505839A6D27FEC0F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSLayoutConstraint+MASDebugAdditions.h + UIViewController+CYLTabBarControllerExtention.m path - Masonry/NSLayoutConstraint+MASDebugAdditions.h + CYLTabBarController/UIViewController+CYLTabBarControllerExtention.m sourceTree <group> - 3853D3CEFB1581CF31C6C033376581B0 + 3870E4A9BA248AFE88604FFA4A61195A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSArray+MASAdditions.h + NSArray+RACSequenceAdditions.m path - Masonry/NSArray+MASAdditions.h + ReactiveCocoa/NSArray+RACSequenceAdditions.m sourceTree <group> - 38F406988E1D01B50F475863B31EC199 + 387FB2EBE17C9CD07247829A3C8B6D08 includeInIndex 1 @@ -2832,16 +2581,23 @@ lastKnownFileType sourcecode.c.h name - NSData+RACSupport.h + CYLTabBarController.h path - ReactiveCocoa/NSData+RACSupport.h + CYLTabBarController/CYLTabBarController.h sourceTree <group> + 39372248B74BC3AF21AB234E0838B3BC + + fileRef + DCF1F57D0E6D06F4AC3305BF54A14BAF + isa + PBXBuildFile + 399AC825EE10F70364CE7B0AA89F466D fileRef - B95B6BF4B263D0E9857C5CE00A3DB020 + 22A9A674AB7DC5D2FF76B677B213DED1 isa PBXBuildFile settings @@ -2852,24 +2608,10 @@ - 3A28400B15F6655653C4D09D2072D651 - - fileRef - 1A8FFA3542A05775083D1E3FD7E8D2A8 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 3A2A3C95E1EDF73DEF947480F6B2FCC9 + 3A2A3C95E1EDF73DEF947480F6B2FCC9 baseConfigurationReference - 6265DE8669B72124D597C877F521FA7B + 4E743A1D8C07C485D1E25B2E8F69503B buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -2903,7 +2645,7 @@ 3A5B54373A45916EC8DE74D060DE5503 fileRef - D3B8C337C8BF6B62816B7E7428D90847 + F003CA8064D942B82B09DE63B338A506 isa PBXBuildFile settings @@ -2914,74 +2656,78 @@ - 3AEA1559B669E7636EA759427C752604 + 3AA0B279BB40445C34DF9A357B5A9C12 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSInvocation+RACTypeParsing.m + MASConstraintMaker.h path - ReactiveCocoa/NSInvocation+RACTypeParsing.m + Masonry/MASConstraintMaker.h sourceTree <group> - 3AF3D1036B7EB37320F5AAEECBFA33FD + 3B043BCCC298A6F3CB95244509270730 - fileRef - 53F994A22B989C221A117FAD0D6C9039 + containerPortal + D41D8CD98F00B204E9800998ECF8427E isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 53480ED0BE09FF49E34B1702D485CAAB + remoteInfo + Masonry - 3B1E22D2D4C556DFA06897C5E9B8CEC5 + 3B705B6A81E85F2054BA5735E280879E - fileRef - 0BF4AC0E7090CAC0D919A6E0A1A516A6 + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UISegmentedControl+RACSignalSupport.m + path + ReactiveCocoa/UISegmentedControl+RACSignalSupport.m + sourceTree + <group> - 3B2929828DB9DD7C1A10ED7F089791FB + 3B8F8E157C7BE1081371F7E5AA5ECFF1 children - C9E88E1C6561A96D7C24E59993CA1296 - 50664F7E572B80CBF4E6FC9A827360A3 - B1CFC19DA8F8AF57C03C8110502534C9 + 5D0A0AC7E297CCC9504DCCB7F98867C7 + C653B6CB5FCB8B5E170D0E8577D5FCA2 + F7CC25DAFD63A1A8FFE474BF9429135C isa PBXGroup name - Core + Support Files + path + ../Target Support Files/Aspects sourceTree <group> - 3C2E6C0F5DED45010DBF171911913419 + 3C430ECABF95D2A08E06D008578A4C1B - includeInIndex - 1 + children + + A063391B665F1B4ABA81E0820EFC0AB2 + isa - PBXFileReference - lastKnownFileType - text.xcconfig + PBXGroup + name + UMengAnalytics-NO-IDFA path - ReactiveCocoa.xcconfig + UMengAnalytics-NO-IDFA sourceTree <group> @@ -2992,36 +2738,39 @@ isa PBXBuildFile - 3D04A99E9EA5FCC02667DA865C677191 + 3C854BF73FDA7E07DD3F21F6E7CA31D0 - fileRef - D085A13B21A5418702B3BF087E39C0D4 + children + + 56F571FA2D6444BB3FBA0C111C67990D + BEC22C108316732DFAD5A8649D25F58F + E208C9A0257BF2A6BBCCC4D15C3B125F + isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXGroup + name + Support Files + path + ../Target Support Files/SDWebImage + sourceTree + <group> - 3D3FBF048AAC09B00D8CE7E148CABAEC + 3D06057B737713403EA64DC89536AA1A + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - UIImage+AFNetworking.h + libPods.a path - UIKit+AFNetworking/UIImage+AFNetworking.h + libPods.a sourceTree - <group> + BUILT_PRODUCTS_DIR - 3D661D03876F28D3286AE89027F93039 + 3D5E45149CD961B9BE684964D8BBEA84 includeInIndex 1 @@ -3030,36 +2779,46 @@ lastKnownFileType sourcecode.c.objc name - UIRefreshControl+AFNetworking.m + RACSubject.m path - UIKit+AFNetworking/UIRefreshControl+AFNetworking.m + ReactiveCocoa/RACSubject.m sourceTree <group> - 3D9C138CA58DB20B7958E752E277C061 + 3D70BB8CA5FDEB02564B76BC77F516B8 - fileRef - 27B195A66BA2975721D58D7D73A4B764 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACUnit.h + path + ReactiveCocoa/RACUnit.h + sourceTree + <group> - 3DADB29339AC082A3B5F6C32092EF483 + 3D8613FB9057E6157DB1D60E10E98E08 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc + name + RACDynamicSequence.m path - CYLTabBarController-prefix.pch + ReactiveCocoa/RACDynamicSequence.m sourceTree <group> - 3DCCC6A9D36EC0F64CC4D370155BDE20 + 3DA86A8697B214782BB21FA94F334451 fileRef - 227AC65587EFD083286F0C1E386B251C + A0A931A92557100FC57CB363E078049A isa PBXBuildFile settings @@ -3070,22 +2829,17 @@ - 3EEE52AA52A838126D6E32685326602B + 3E3E6AB4703E2F1384E6623B7E3A922F fileRef - 9BA172233D50DE6F6C742F0EEB20DB5E + CC26929FDB6C8949BC83255384E31E30 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 3F63C119F95A6735AE627BBB1BEBC4B1 + 3EE979D8676CD634215E3B57AE205BF8 fileRef - B56FF81792456265A5FF00925C85FE39 + 20ACC301DCCE2788E3FE2B25CB3121DB isa PBXBuildFile settings @@ -3096,10 +2850,30 @@ - 3F9FF0984677E78E3E38509B95F26CDA + 3F1A0CF4FA7F08FCA2A63E3C872EAF50 + + fileRef + B05A64156A3417B7CC4E3AF35C82A680 + isa + PBXBuildFile + + 3F25A1DC4B91D20E8556F88DB73F8752 + + containerPortal + D41D8CD98F00B204E9800998ECF8427E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 410B25DF16EA5C5B3E2698F74F9625FB + remoteInfo + AFNetworking + + 3F63C119F95A6735AE627BBB1BEBC4B1 fileRef - EC35FA32A2CD206519C0FF29685ECACC + 5ADC59D09BE50B8B735C967AF50CBE5F isa PBXBuildFile settings @@ -3110,83 +2884,86 @@ - 3FA351C84EA2D69232792EFB51B72FA2 + 3F71D2177669333731E820865DA2D231 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UITextField+RACSignalSupport.h + NSObject+RACLifting.m path - ReactiveCocoa/UITextField+RACSignalSupport.h + ReactiveCocoa/NSObject+RACLifting.m sourceTree <group> - 3FD55D0C258BBCEA9D5C4D4EB5A1683E + 407E04979D0276E5B91DC610CD6BACF7 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc + name + RACUnit.m path - AFNetworking-prefix.pch + ReactiveCocoa/RACUnit.m sourceTree <group> - 3FE45802A334D3A34D1E9801DF60855E + 408EA800BDFEB248F45E5F5E1AF8DFE7 fileRef - BCCA176AFF17EF4AA821307506265219 + 0BD06C4DDA7B80C1742B09DDCF556762 isa PBXBuildFile - 4069A76AF3FE40D2B67B378ADC73A274 + 40D595E6B087FCC985869CB435BD62BD - children - - 62F30D9AF07C2D503845301942FA9F9C - 45B60A0181BE24D31D4043D1238F85A3 - 017C816C17DB67AE9F6826A6FE13364C - 52913DD4BC5EAAD96971E4DD04EA8A88 - F92C693888AC9830EA897E087C7328CB - 04E49DCD6C8078833262469CB937AD94 - 582956321F29E8CB5D8D4000083FA273 - 2473F9ABF7786DAADFBB9FA54E432852 - AC683279CE140109D25DB1A0329F9E8F - ABB1886E908810BEFE5C77EFD2AD647B - 320C9608B1813EB3CCAD3DAE5D053886 - 91BBF694E9001C762E8DB9185ABE3ADB - 54AAF0ACDEE2311575C5E85802ADF939 - BABD49C2333852326929CEAEB6FE04E7 - AC5083844F2D2F9F51E1E80933EC149E - 89C97B06CF69EC49E69271C0C029419A - 8D702D0F1FBE57C1D1C6980E22C66EBE - 092313CD65C3ADE482E79E26E2506D58 - 69CC3D71377DFD142B605B31539E917D - 8AC588373A6FBA25589D84FC17D92C55 - 1DAE47CB93A8820B8E21C80C65B414FA - 59847A0669985B7EC9B450E732C176FB - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.h name - JSONModel + JSONKeyMapper.h path - JSONModel + JSONModel/JSONModelTransformations/JSONKeyMapper.h sourceTree <group> - 40C6841E8BEA23E62F758DF4AFB7EE44 + 40FF190AA7658FF244A9A23F56E8FE9C fileRef - 6DA0DC0C3DFC0404452E564B270EFFB6 + EDEE2194BAD340B988C97C63499C622E isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 41050362AD1BD1CA52A8EB240377B286 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + View+MASAdditions.h + path + Masonry/View+MASAdditions.h + sourceTree + <group> 410B25DF16EA5C5B3E2698F74F9625FB @@ -3209,11 +2986,11 @@ productName AFNetworking productReference - 6AC09D1314CA9AA3CDF4938347A11233 + 95425136DDE162827E8835D3A5B2A1D2 productType com.apple.product-type.library.static - 411145FA9BE020CC0E000A036879ABB6 + 41CBE05F873C848A0181E13D315F7FB8 includeInIndex 1 @@ -3222,9 +2999,24 @@ lastKnownFileType sourcecode.c.objc name - RACBlockTrampoline.m + MASViewConstraint.m path - ReactiveCocoa/RACBlockTrampoline.m + Masonry/MASViewConstraint.m + sourceTree + <group> + + 41E2651FF81F50331945FCCFD83DC429 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACDynamicSequence.h + path + ReactiveCocoa/RACDynamicSequence.h sourceTree <group> @@ -3242,38 +3034,24 @@ isa XCConfigurationList - 42AA6E2A1E2F248A8025078B457ADE4F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - AFURLResponseSerialization.m - path - AFNetworking/AFURLResponseSerialization.m - sourceTree - <group> - - 42F37DFACB2534ED1B8F85FA5BF203AD + 42E564DDE04DDE5B42FEE5225B1845BE - includeInIndex - 1 + fileRef + B162F15944278B58E9A5C9E1959A2601 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - path - Aspects.m - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + 432BD50F1E699EDF2EA007E850FFCEF7 fileRef - 5990D1386DBADFFF00C5F3FF1310B491 + A3F71E90C69029CDD15B2D2578518B92 isa PBXBuildFile settings @@ -3284,10 +3062,17 @@ - 43AB2DECC33D773B0C8F2F91C8A522EE + 4337EAADB137537429211C3878012386 + + fileRef + 92FEFBB1C20F0AAD1BC09DB2CC06F396 + isa + PBXBuildFile + + 434336354C7F955B06BB988AB713FBB6 fileRef - B916116B6285D76B6613F1A54BD1A543 + 2907BD39C74E60F0FDD942123AF9D143 isa PBXBuildFile settings @@ -3298,7 +3083,7 @@ - 43AE592AB85786B82334A90B22D6F242 + 44442DF5806C05C072F5B6565F9E4C8B includeInIndex 1 @@ -3307,28 +3092,27 @@ lastKnownFileType sourcecode.c.h name - SDImageCache.h + UIView+WebCacheOperation.h path - SDWebImage/SDImageCache.h + SDWebImage/UIView+WebCacheOperation.h sourceTree <group> - 43BC8AFBABA6F0B2F0335334231D6F8E + 44764AE93D55B202263D25B3E648AC7F - includeInIndex - 1 + fileRef + AE4F977AC92FF4C9A2655E4EA0803C87 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACReturnSignal.h - path - ReactiveCocoa/RACReturnSignal.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 43D7AFEEA1462E59880E023A7F5226BD + 44877DC0490619A24BD20531F6A0A5DE includeInIndex 1 @@ -3337,16 +3121,50 @@ lastKnownFileType sourcecode.c.h name - CYLPlusButton.h + NSInvocation+RACTypeParsing.h path - CYLTabBarController/CYLPlusButton.h + ReactiveCocoa/NSInvocation+RACTypeParsing.h sourceTree <group> - 43E99EDD475D70A05A3140E0428E4B0E + 454284B86E3004EC10A017C902C5CD16 + + baseConfigurationReference + 5D0A0AC7E297CCC9504DCCB7F98867C7 + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/Aspects/Aspects-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 45C73E425601114F4A8AC676E17AEF2E fileRef - F5B23A8DB947C061C43DFC4FFED383BE + 521802A1964EB7D5383F4DD9B5805FBE isa PBXBuildFile settings @@ -3357,32 +3175,21 @@ - 445AF6E24DDA22F5494D248F7332AF4F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - path - XAspect-prefix.pch - sourceTree - <group> - - 445D199E11BB3B076FA716953CC9D944 + 45DC8A4074CB9B15EE75825B8EC4325F fileRef - 4C4B9659BC5AC33C64193E5FE571EB83 + 44442DF5806C05C072F5B6565F9E4C8B isa PBXBuildFile settings - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 + ATTRIBUTES + + Public + - 44A71989FF866B0D82B280F97DD420DF + 4621947EF9EE514EC0E7DEDEDC287B07 includeInIndex 1 @@ -3391,73 +3198,13 @@ lastKnownFileType sourcecode.c.objc name - UIImagePickerController+RACSignalSupport.m - path - ReactiveCocoa/UIImagePickerController+RACSignalSupport.m - sourceTree - <group> - - 44D882ADFA06DC141944859F300FC170 - - buildConfigurationList - AA8DD7FA05C8337A8B8877E5619B71C7 - buildPhases - - 1DCD57EDA9162EAFE9AFEE83B1C8AC2A - 06ECFA846BF20459400D87E324316AD8 - 72052010D04CF675D6C01C79BF5887D6 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - SDWebImage - productName - SDWebImage - productReference - 2577EAA643A58B7C32375D37068F9D3B - productType - com.apple.product-type.library.static - - 44EC176E81593AA77DA1126913033AF8 - - children - - D3C233514075711C6040EA1D4182F48F - B7686B7D69B3E285F991DBF462667415 - 75D2D91A65315844BFD96735D194EBF1 - 8B78401B8A1F08A7098C7E892E45C5BA - 30D377C733F30186EA2D73B73E56E053 - 0D21AF65FBED97A433B38D6666F40AAA - - isa - PBXGroup - name - NSURLConnection - sourceTree - <group> - - 4501BB97D1C911881570F821973707C0 - - children - - C1AA148B9439B41219BDA56410A9B5C2 - 42F37DFACB2534ED1B8F85FA5BF203AD - CF76BF2C0371BD2AB3578F79BC94ADF5 - - isa - PBXGroup - name - Aspects + NSData+ImageContentType.m path - Aspects + SDWebImage/NSData+ImageContentType.m sourceTree <group> - 4509DF6334860FC19F8A57F6345BF60C + 46D65F7EB6FBC2C765A3D74191A5444B includeInIndex 1 @@ -3466,44 +3213,29 @@ lastKnownFileType sourcecode.c.h name - NSDictionary+RACSequenceAdditions.h - path - ReactiveCocoa/NSDictionary+RACSequenceAdditions.h - sourceTree - <group> - - 450B9099B6CD2D7B19B3701CCFECD6CC - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIImage+GIF.m + NSSet+RACSequenceAdditions.h path - SDWebImage/UIImage+GIF.m + ReactiveCocoa/NSSet+RACSequenceAdditions.h sourceTree <group> - 451A9850F23BFA1C02FB8FA6A179F06C + 46F4CB5B2D448A9DDF96CF039D108E8F fileRef - A40E3359EADB8FB3828D3E19487C9952 + 9C054D2305C720C0B99D1D5A7727F489 isa PBXBuildFile - 4525B4C9B4B93E98FF1393778F151A0C + 4728858CCB67CF8048116D7CBEA4484E baseConfigurationReference - CC2EF386E6EB31FC9BC5D90FD15B70B1 + 8C7CDB026EEE224CDFF0F69F0B9AAFD4 buildSettings ENABLE_STRICT_OBJC_MSGSEND YES GCC_PREFIX_HEADER - Target Support Files/SDWebImage/SDWebImage-prefix.pch + Target Support Files/XAspect/XAspect-prefix.pch IPHONEOS_DEPLOYMENT_TARGET 7.0 MTL_ENABLE_DEBUG_INFO @@ -3528,41 +3260,14 @@ name Release - 454284B86E3004EC10A017C902C5CD16 + 472A6BFCC6207D98F787649BDF44A1BE - baseConfigurationReference - A8C77BBDC031F4497C55AEC67342E6DD - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/Aspects/Aspects-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - + fileRef + C46BCDBFB5F4C6A682212FB8371F8E9C isa - XCBuildConfiguration - name - Debug + PBXBuildFile - 456F16D56E6A14837886973506955D7F + 4810F189AFC3DCD40A14FBCEF9833BAD includeInIndex 1 @@ -3571,28 +3276,27 @@ lastKnownFileType sourcecode.c.h name - UIControl+RACSignalSupportPrivate.h + XAFoundation.h path - ReactiveCocoa/UIControl+RACSignalSupportPrivate.h + XAspect/Macros/XAFoundation.h sourceTree <group> - 45B60A0181BE24D31D4043D1238F85A3 + 495F717651B12E6496C72D16BCC28C29 - includeInIndex - 1 + fileRef + 9C71D296FA604ABD75678BC8AC38C9E2 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - JSONAPI.m - path - JSONModel/JSONModelNetworking/JSONAPI.m - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 45C2BA9E4DE0353AB180CBA2980A3B28 + 49C02A3B831B982B78163EC10EF0D33E includeInIndex 1 @@ -3601,60 +3305,70 @@ lastKnownFileType sourcecode.c.h name - SDWebImageDownloader.h + UISwitch+RACSignalSupport.h path - SDWebImage/SDWebImageDownloader.h + ReactiveCocoa/UISwitch+RACSignalSupport.h sourceTree <group> - 45EFCB171CA7F7314B3171C0011DF29E + 4A47648C553C80402520D43163E5F22C + + fileRef + 00784913BB40755E9BD89DC8CB6F233A + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 4A48DB851E5BD64428601368F0296D83 - includeInIndex - 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + wrapper.framework name - MASConstraintMaker.m + UIKit.framework path - Masonry/MASConstraintMaker.m + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/UIKit.framework sourceTree - <group> + DEVELOPER_DIR - 461441BB0039FFBF9FFEC9A12FF0525F + 4A4DCF231CE4F0B8916A5FA4590C3343 fileRef - 6E824E86B7D5F406164E3D0C0999A900 + 87F282AB3C2677BD2D143D5020431ED2 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 4653CFBF8AD1185C23C763DAADD6F6DA + 4B95E10EB54BF9480A8CB857F0170925 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SDWebImageManager.h + UITableViewHeaderFooterView+RACSignalSupport.m path - SDWebImage/SDWebImageManager.h + ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.m sourceTree <group> - 472A6BFCC6207D98F787649BDF44A1BE - - fileRef - 8B78401B8A1F08A7098C7E892E45C5BA - isa - PBXBuildFile - - 47F793B36896F16B8BEBBD8C8E8F60AD + 4BDE97C783ED286933A60CAE9292B775 fileRef - 85F392C1372F726906BC2B879CFF3FC9 + 40D595E6B087FCC985869CB435BD62BD isa PBXBuildFile settings @@ -3665,21 +3379,14 @@ - 495F717651B12E6496C72D16BCC28C29 + 4BF97AA932B32DD81BD7DBD33CE76F27 fileRef - BB5406E50F64CC1977954CD5228C8B81 + FEC4EF4B8F6EAEA6E2829EE84BC8912A isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 499566C0E9CD3BD5D392DBEC16BAD137 + 4C0437E768B286949A1AF95182161D88 includeInIndex 1 @@ -3687,30 +3394,17 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + UIControl+RACSignalSupportPrivate.m path - SDWebImage-dummy.m - sourceTree - <group> - - 49A20E37AD655BA2A4C0AEB7A7ACC747 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACSequence.m - path - ReactiveCocoa/RACSequence.m + ReactiveCocoa/UIControl+RACSignalSupportPrivate.m sourceTree <group> - 4A47648C553C80402520D43163E5F22C + 4C2780FFB0867A7C9F3054CB8996258F fileRef - 43D7AFEEA1462E59880E023A7F5226BD + D5B6E64B7D12380EAD3FE18643DB1AF6 isa PBXBuildFile settings @@ -3721,23 +3415,25 @@ - 4A48DB851E5BD64428601368F0296D83 + 4C6474D7F773FABA0133ABC73E98E0BF + includeInIndex + 1 isa PBXFileReference lastKnownFileType - wrapper.framework + sourcecode.c.h name - UIKit.framework + XADebugMacros.h path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/UIKit.framework + XAspect/Macros/XADebugMacros.h sourceTree - DEVELOPER_DIR + <group> - 4A4DCF231CE4F0B8916A5FA4590C3343 + 4C8D561215C600D35D8DA7FAF3B73BAF fileRef - 2473F9ABF7786DAADFBB9FA54E432852 + 4621947EF9EE514EC0E7DEDEDC287B07 isa PBXBuildFile settings @@ -3746,7 +3442,7 @@ -DOS_OBJECT_USE_OBJC=0 - 4A84D33C0DB3F8586464A2B82975BC35 + 4CF65A701B1BE85EC147610D641309B5 includeInIndex 1 @@ -3755,13 +3451,13 @@ lastKnownFileType sourcecode.c.objc name - NSObject+RACDescription.m + RACDelegateProxy.m path - ReactiveCocoa/NSObject+RACDescription.m + ReactiveCocoa/RACDelegateProxy.m sourceTree <group> - 4B9BFF5FC1917D3F67A2A654C2A7EA7E + 4DD08C0B21C162E6D324D90B91E741C2 includeInIndex 1 @@ -3770,72 +3466,195 @@ lastKnownFileType sourcecode.c.h name - MKAnnotationView+RACSignalSupport.h + AFHTTPRequestOperationManager.h path - ReactiveCocoa/MKAnnotationView+RACSignalSupport.h + AFNetworking/AFHTTPRequestOperationManager.h + sourceTree + <group> + + 4DE36D4B16AB5BD257BDBA97DE1BD733 + + fileRef + CD1B1D9F29C1568866D360CAE9280B20 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 4DFA6D7D6C9C1E2E556F38770032191D + + children + + EE6697C2C766C11CC4AA6C8FFF3FF7F6 + F0218A60CF118E77C2F159926207C45A + EE0F99FB0D1509C0A7E03A68A8068CD7 + 20ACC301DCCE2788E3FE2B25CB3121DB + 6191584C259B4383F47D6A49A9D85E5C + 5C75502C38CBAEFC2F76A453F740ADDD + + isa + PBXGroup + name + Core sourceTree <group> - 4BBDEB6CE73B6137C47501419AF2777F + 4E0768EF582C32EC850A977B2BD5B80A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSNotificationCenter+RACSupport.m + RACMulticastConnection.h path - ReactiveCocoa/NSNotificationCenter+RACSupport.m + ReactiveCocoa/RACMulticastConnection.h sourceTree <group> - 4BDE97C783ED286933A60CAE9292B775 + 4E679CCF235A43902AFE269284BA7535 - fileRef - F92C693888AC9830EA897E087C7328CB + buildActionMask + 2147483647 + files + + 2C6212271F8703B449D650005C31AD0A + 42E564DDE04DDE5B42FEE5225B1845BE + C755153372C2D17AB51E52B671A4DDB9 + EC6BDF9C49C4873A125EA392C6EF9763 + EE6025199E346EEFB630B84F576E6276 + BDCE76BCF06764923721B3020CB74123 + F2E63C36BC0C65D1820A28127018031E + AF240C3E171360773D703C4D2C4DB676 + 92FDBD13A250744C170BC9A901A86E37 + A7F9385074DC5208E8095F7DF107298B + 842F3DEE88D6DCE5D1FA98AC555293A8 + FEC7C43491775ECA43A0C635A44E5C59 + EE43841F080329C982D3412E2685B88A + 99D84384CAC2C15621AB1A9FB052906A + 6D69F79DD850CB749BB1BAC136544A8B + 624D83EDE9EDC7F233F5990F01E3EF91 + C3336607D83BE9B77CEBE5E35A1D3F81 + 1D2B4BD756898088A194BDA60C8A935C + 2DE89A588059B947410B1E0B2FB3605B + 74FB10F38FF81777F07B011E6D876890 + 80B0636973B4F8BB830EBEB75D2920C9 + 93C1668F705927BFD1E9229C6A6BF521 + DBB5DF22BCB4A481B9015D798A013CAC + BA8CA89D16A3069C9C315ADA4C671E0C + 0E58356CB71EB1AF387189271D790427 + AAAA8779AE4198974DF5AEEBE7C5C0C3 + AAC3B58AD7A45FCEC3A1A08C5AD923D5 + BDFD9AF00C44DF99D52D6443D37A0A8E + 434336354C7F955B06BB988AB713FBB6 + B3F8334E6CE96A5F3E36C9573B6CB7A2 + 503C19DBCA210C65FE94B947B09992B8 + 26BA5D9D9C21E0CD257557E262FB3E8A + EE95B42B682BCB595D49554F8E78CA43 + C7CA239660C182F0D322D7C4F975BE91 + ECD2A148381C6717D8DCE2AA472F61A3 + 9DC84A01BBF97F58CF4DDF9AC5548B25 + B4DB0EFD9EB499E42020C73EA8B90052 + FC5F6569B5BBEC724A67613EACEEDBC7 + 2141A690FDB7C142352CCAD5ECA39C0F + 09BE9771A40000839092B7A963CF4D77 + 7F3AC1A845FDA6BDB97B7EFA12507D24 + 9871A570E364A1B6F0B48565A892F723 + BC8666627E83F9BBDD96BAEE1B7AA49E + 15D83D76F23B8E5018830A075363B6E7 + 5918D23F4A1E080496309C6B6398EAC8 + 133F106C17EB7AC4CF864A83E353ADD4 + 735C79180B9DF12451E642F5546F7159 + 5258C4959C23C64130BD37895312D85B + C7A1E2FAAB3E8C87F4662C50E1ECE8A4 + 45C73E425601114F4A8AC676E17AEF2E + CD602F03A80FCB1A17E67B40847E22C7 + E6689D7C50A50E004D66ADE32971AF81 + 984E76EAB6CAE9D02BA3FCBC602C6164 + AC94144A1A25D7A6C67D19F441265528 + 9A796393B3FAEF29DA709A3BCFC21BE6 + 015873E0C53A730C64424B6EDA040750 + E2711D48FE646C1F092908689D43A73E + CD2366082A94BCCDF499180B3F09427A + 44764AE93D55B202263D25B3E648AC7F + E0BF109179C0DCCF7E11BF91E9968783 + 13B475B4D0F4B0903F802187F4F2D2A8 + 884241E994424B56FF62E5E4C0EB0192 + 5382D084185070EBF15C412031DFAC0E + A7A0BE41621D3506C7DC9E8940621EF2 + D0E43668224843EC3D52533B49477C98 + FD5D5B84A17DE1F44687D8E5A3B723F4 + 4C2780FFB0867A7C9F3054CB8996258F + F371FF874C0053ED5B901B4CDC3B866B + A2C7C6D416B7AF12F7D61DB2EA26F8A0 + BFAAD2731711F0B848DEBAF029A8E4B7 + 36352F2581739076A60FEB0E8E8E9317 + E77493C63D3D9AE7391F2487AB3287E8 + 73FD0B0A878D9777A94B79FAD29288A2 + 3541BDAEDC5B923485A0172D47B2CCFE + 6132A9AAF5EE8317947FEF91770BAE9A + 0B6A537F797823355E6CD7B3D1AB6691 + 1B2194539D5324B090DFEA647F98AE97 + 197CE9E4D4ABFA80559B3712ABB04B80 + 40FF190AA7658FF244A9A23F56E8FE9C + BCBCC9FF9151BBAA22285657DC3D2CE3 + AAC25FA4FF2E080CF948027BF6FE8C4B + 757AB9A022318505C082F40A7593F219 + 1263AF3F3C8A2E150F8ACB065166336C + 6E29A32A796A3FA6689C81E4FABA8A8E + 3DA86A8697B214782BB21FA94F334451 + 9B99D49C0FD5F09E0F12961BDB4DAE91 + 271EBE09FBE0D7A90772DC71895CAE9D + D7A019D837A9FAF6218EBB1810634FAC + 00CB2427C5B89DD801B0054E86FE2520 + 1B6F846FB0301F1A743248404E457787 + 10399E8FB58B02A0100068ABC5DCE9FC + 7A14C29ABC66BCFA43F739CA14743E84 + 80BA7C1922DFC238B40790F5B9A54D5C + D3AF770B574C46F2B3BD7CF39C587477 + 30D84A6F9B2F3E016CCEAD524AD5EBFA + 090AB1BA1AF90CA206C71ED5E4C1D50D + 963D3CE7C312D6A3C4A39F4726EDDC13 + AD9C8C591110EFB2C25C9444CDED91BA + EAE30534210F4962CBCB9FAFF8B99B8D + isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 4BFF8DADBD1721BF5461F26BCA2F1E87 + 4E743A1D8C07C485D1E25B2E8F69503B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - NSObject+RACKVOWrapper.h + text.xcconfig path - ReactiveCocoa/NSObject+RACKVOWrapper.h + Masonry.xcconfig sourceTree <group> - 4C4B9659BC5AC33C64193E5FE571EB83 + 4E762F23EC34ED4A6FF3312D84E33A40 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - UIImage+MultiFormat.m + text.xcconfig path - SDWebImage/UIImage+MultiFormat.m + Pods.debug.xcconfig sourceTree <group> - 4C8663B3ABB37A09529A40E2BF230F84 + 4E88B7E7DCA9967A4633781A315EC83B includeInIndex 1 @@ -3844,13 +3663,13 @@ lastKnownFileType sourcecode.c.objc name - NSObject+RACLifting.m + RACDynamicSignal.m path - ReactiveCocoa/NSObject+RACLifting.m + ReactiveCocoa/RACDynamicSignal.m sourceTree <group> - 4CC249A3418D897E66F56183AFCA84E5 + 4ECCA2FD461EFA3B022347720B7A0237 includeInIndex 1 @@ -3859,28 +3678,55 @@ lastKnownFileType sourcecode.c.h name - RACEvent.h + UIRefreshControl+AFNetworking.h path - ReactiveCocoa/RACEvent.h + UIKit+AFNetworking/UIRefreshControl+AFNetworking.h sourceTree <group> - 4D1ABF333E068D7241F4565EA3D3D04E + 4F0CE6C217097838A813CBEB0BC26AC5 - explicitFileType - archive.ar - includeInIndex - 0 + fileRef + BB312BC3F8EB1727EBD62393D9CE870D isa - PBXFileReference - name - libReactiveCocoa.a - path - libReactiveCocoa.a - sourceTree - BUILT_PRODUCTS_DIR + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 4FA81B7382912B7432A92DB6F953724B + + fileRef + 009AC949FCDF3A0058063D295100D7C8 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 4FE7D89FE522F656FF6D8BD5B2D752B9 + + fileRef + 99B18091467DC619CAAB11E060AC1121 + isa + PBXBuildFile + + 4FEA23AC659B8A10AA41CD9E405DA4E9 + + fileRef + 997C4C3399F300AD66818E3A4C6D84EB + isa + PBXBuildFile - 4DC141C3FDE4F29B3B8F42FB8054EB4F + 502F02902D12F7F70B598E370585A968 includeInIndex 1 @@ -3888,24 +3734,42 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + RACQueueScheduler+Subclass.h path - SDWebImage-prefix.pch + ReactiveCocoa/RACQueueScheduler+Subclass.h sourceTree <group> - 4DE36D4B16AB5BD257BDBA97DE1BD733 + 503C19DBCA210C65FE94B947B09992B8 fileRef - BABD49C2333852326929CEAEB6FE04E7 + 41E2651FF81F50331945FCCFD83DC429 isa PBXBuildFile settings - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 + ATTRIBUTES + + Public + - 4E0F376ABE79D465A617B95C1475CD68 + 505A5567D1C7B697572D7905A96F79DC + + fileRef + 4C0437E768B286949A1AF95182161D88 + isa + PBXBuildFile + + 50B553DCB7DBF5C22B2AD520174C367B + + fileRef + 684B248578D78367990650D36F7F710B + isa + PBXBuildFile + + 5159B129DE1BC211151FDE6DE1D2B6CA includeInIndex 1 @@ -3914,13 +3778,20 @@ lastKnownFileType sourcecode.c.h name - XADebugMacros.h + RACEXTKeyPathCoding.h path - XAspect/Macros/XADebugMacros.h + ReactiveCocoa/extobjc/RACEXTKeyPathCoding.h sourceTree <group> - 4E0FFAB1DBFDD2724BA8FA304BD72F01 + 517FDB0BCAF1A6CF990B2AD5A6649613 + + fileRef + 632EBDB3CCB54217F760522A809A4EF6 + isa + PBXBuildFile + + 521802A1964EB7D5383F4DD9B5805FBE includeInIndex 1 @@ -3929,49 +3800,71 @@ lastKnownFileType sourcecode.c.h name - RACDelegateProxy.h + RACObjCRuntime.h path - ReactiveCocoa/RACDelegateProxy.h + ReactiveCocoa/RACObjCRuntime.h sourceTree <group> - 4E762F23EC34ED4A6FF3312D84E33A40 + 5258C4959C23C64130BD37895312D85B - includeInIndex - 1 + fileRef + A7F2287F2AE2FDF73582111450DFC9A3 isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - Pods.debug.xcconfig - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Private + + - 4F64C8EDFA4698BD86F2A11C62FF9032 + 52B172DACAD83B36862AE4FD13B2EA9B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACObjCRuntime.h + SDWebImageDownloaderOperation.m path - ReactiveCocoa/RACObjCRuntime.h + SDWebImage/SDWebImageDownloaderOperation.m sourceTree <group> - 4F7ACF1421268A3CDFC9455CABF9A6D5 + 52B9F1F399DEADDDFBE3F17BAA8D6D14 + + fileRef + DA02260E9C9DA18939EF3B57CA5D401E + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 531A0F2EDCCFD0F3B47BCD17DB5C5F85 + + fileRef + 671942142A25439F9D7DE7312A1E1C0E + isa + PBXBuildFile + + 53480ED0BE09FF49E34B1702D485CAAB buildConfigurationList - A4E19A682B06FFA7ECEC8CAB39B098FE + B6653DB75D219E078020C341A7D83ECE buildPhases - F9A104A960E0257D7A7BAF9AA133AF85 - DF49020A45AAD83B73F2B3E4BD4DB040 - 30CAB99159D131299142A59ABE5461C4 + DC8579C657135E3C32AB580A48C6D524 + FAB9E9D9BBDB93399D3C2B91469EC4B6 + 657D857047A6A935B5A2E9BD049194F2 buildRules @@ -3980,35 +3873,18 @@ isa PBXNativeTarget name - ReactiveCocoa + Masonry productName - ReactiveCocoa + Masonry productReference - 4D1ABF333E068D7241F4565EA3D3D04E + 8AA007B97AE5CC80ACC692D6E590CFFE productType com.apple.product-type.library.static - 4FA27C677A68BCAFA3A5A98CC397CAD6 - - children - - 3C2E6C0F5DED45010DBF171911913419 - 65885D26E021BDBB24AA0FD2FFF56189 - BAF078745485F21C76E8293BF6982CE7 - - isa - PBXGroup - name - Support Files - path - ../Target Support Files/ReactiveCocoa - sourceTree - <group> - - 4FF68D9DB123474D54A03C0997B32F5D + 5382D084185070EBF15C412031DFAC0E fileRef - 4E0F376ABE79D465A617B95C1475CD68 + D720F77CD503831B331597B657E86F13 isa PBXBuildFile settings @@ -4019,7 +3895,7 @@ - 50664F7E572B80CBF4E6FC9A827360A3 + 53D81312E4A85A6CFB6C3C06D619A81F includeInIndex 1 @@ -4028,20 +3904,20 @@ lastKnownFileType sourcecode.c.objc name - JPEngine.m + RACTestScheduler.m path - JSPatch/JPEngine.m + ReactiveCocoa/RACTestScheduler.m sourceTree <group> - 50777D8BB7008011BB9890F81A5D5B0E + 5457FCC2699281B5A4203BA1559F593F fileRef - 499566C0E9CD3BD5D392DBEC16BAD137 + A3D2C29F2D61DF4AF12B21F7956B3A8F isa PBXBuildFile - 510325018C1BA2426D1484BFAAFE04D5 + 546043D08C492E3C07CDE69F0C33381C includeInIndex 1 @@ -4050,58 +3926,61 @@ lastKnownFileType sourcecode.c.objc name - RACEagerSequence.m + RACSignal.m path - ReactiveCocoa/RACEagerSequence.m + ReactiveCocoa/RACSignal.m sourceTree <group> - 51DEAD099F5FEE7BE4DBD4CB7DDF0A0A + 561D1F2678923A0D9ECFB84315F1A18F includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + UIDatePicker+RACSignalSupport.h path - XAspect.xcconfig + ReactiveCocoa/UIDatePicker+RACSignalSupport.h sourceTree <group> - 52913DD4BC5EAAD96971E4DD04EA8A88 + 567A662A94B17F76035960CAC8926339 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - JSONHTTPClient.m + SDImageCache.h path - JSONModel/JSONModelNetworking/JSONHTTPClient.m + SDWebImage/SDImageCache.h sourceTree <group> - 529ED9818F1C7EC4B6A61D8863918EFD + 56D2E074E8876B140C4BC52247941163 - buildConfigurations - - 86A39E3CEB9ED0ED2B7151213732FC37 - 8F103981A804B41263FEBD30B4CD2CA5 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + includeInIndex + 1 isa - XCConfigurationList + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACStream.m + path + ReactiveCocoa/RACStream.m + sourceTree + <group> - 52B9F1F399DEADDDFBE3F17BAA8D6D14 + 56EF1BCF142EACE6F21E803872214B0C fileRef - 320C9608B1813EB3CCAD3DAE5D053886 + B65FD05A1FF795BB0A8F5E367367CD3A isa PBXBuildFile settings @@ -4112,25 +3991,38 @@ - 52BF3A8C015B33CB9A15012AEA9221A0 + 56F571FA2D6444BB3FBA0C111C67990D includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + text.xcconfig + path + SDWebImage.xcconfig + sourceTree + <group> + + 58FB72A327F803DBCC27E14D362FDBEF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - UIBarButtonItem+RACCommandSupport.h + UIImageView+AFNetworking.m path - ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h + UIKit+AFNetworking/UIImageView+AFNetworking.m sourceTree <group> - 5324DEF148D035F75420164C52255C88 + 5918D23F4A1E080496309C6B6398EAC8 fileRef - 1978942A4A36BCAE9997429376A5733C + 249B69A2A3999EA1D14701B0FAAEB5EC isa PBXBuildFile settings @@ -4141,32 +4033,7 @@ - 53480ED0BE09FF49E34B1702D485CAAB - - buildConfigurationList - B6653DB75D219E078020C341A7D83ECE - buildPhases - - DC8579C657135E3C32AB580A48C6D524 - FAB9E9D9BBDB93399D3C2B91469EC4B6 - 657D857047A6A935B5A2E9BD049194F2 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - Masonry - productName - Masonry - productReference - DA848D003DF56A71D62834E0CCFB76F1 - productType - com.apple.product-type.library.static - - 53C1A4C9F7C64CD396285B361DF3D54F + 596B174E46C0474CE36AEF416A2FAE51 includeInIndex 1 @@ -4175,61 +4042,57 @@ lastKnownFileType sourcecode.c.h name - NSObject+RACDescription.h + MASUtilities.h path - ReactiveCocoa/NSObject+RACDescription.h + Masonry/MASUtilities.h sourceTree <group> - 53F994A22B989C221A117FAD0D6C9039 + 5974F75F57FC1A6F3462B24D17473E06 + + buildConfigurations + + EE99B43C5929107E4A199A7A9D6089B7 + FC5CE4331073DAEE9787ECB2636651C2 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 598B77BA5B514764BBDF71F12E23CA1C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIGestureRecognizer+RACSignalSupport.h + UIView+WebCacheOperation.m path - ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.h + SDWebImage/UIView+WebCacheOperation.m sourceTree <group> - 5420E11F49B04AED7D232AE9D262AD06 + 5ADC59D09BE50B8B735C967AF50CBE5F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h + name + MASViewAttribute.h path - Aspects-dummy.m + Masonry/MASViewAttribute.h sourceTree <group> - 5457FCC2699281B5A4203BA1559F593F - - fileRef - C282CB59296F9F83EA17F38A745BA23B - isa - PBXBuildFile - - 549EB52110708F15C83113B534801B04 - - containerPortal - D41D8CD98F00B204E9800998ECF8427E - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 410B25DF16EA5C5B3E2698F74F9625FB - remoteInfo - AFNetworking - - 54AAF0ACDEE2311575C5E85802ADF939 + 5B13BC93E7096A8DFC3B2CA65F53D280 includeInIndex 1 @@ -4238,25 +4101,20 @@ lastKnownFileType sourcecode.c.h name - JSONModelClassProperty.h + RACTupleSequence.h path - JSONModel/JSONModel/JSONModelClassProperty.h + ReactiveCocoa/RACTupleSequence.h sourceTree <group> - 558820DD61F95F6837416FDB64DD90A3 + 5B6200D0F58FB8FC92A2A28A3D699336 fileRef - 450B9099B6CD2D7B19B3701CCFECD6CC + 01F159ED6F5F238200CF3F0B936808FC isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 55D160550DEE0C805734D9A79F8CECE6 + 5BC51F01B8E478B91F2685EC793E6CD1 includeInIndex 1 @@ -4265,27 +4123,13 @@ lastKnownFileType sourcecode.c.objc name - RACCompoundDisposable.m + RACObjCRuntime.m path - ReactiveCocoa/RACCompoundDisposable.m + ReactiveCocoa/RACObjCRuntime.m sourceTree <group> - 55DAF72F6CDEFB6BE0251EC4A55C1BEC - - fileRef - 66EA37CF5A484C13AC109BA581C4D752 - isa - PBXBuildFile - - 55F97BB22E50192EFDF5E1D465482B9E - - fileRef - 7E202116CC80048D57115A2A111CA5F4 - isa - PBXBuildFile - - 563CABE8034F56611588FFFEA8122352 + 5C5A5F9BD67F2AD265A236C4C592107E includeInIndex 1 @@ -4294,23 +4138,31 @@ lastKnownFileType sourcecode.c.h name - RACKVOTrampoline.h + ViewController+MASAdditions.h path - ReactiveCocoa/RACKVOTrampoline.h + Masonry/ViewController+MASAdditions.h sourceTree <group> - 5691B0310ACD8CBFDB2B3E910C6C06B5 + 5C75502C38CBAEFC2F76A453F740ADDD - fileRef - D7D7B6198C38BE29584CFDA470A53399 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + XAWeaveHandler.h + path + XAspect/Core/XAWeaveHandler.h + sourceTree + <group> - 56EF1BCF142EACE6F21E803872214B0C + 5CF0E043147B69E77976A2CCADFF18CA fileRef - C1AA148B9439B41219BDA56410A9B5C2 + 28D80F8E081C91AF857CB10D6B115758 isa PBXBuildFile settings @@ -4321,24 +4173,20 @@ - 578183BBC5F4AAE9926C9AB1455DD321 + 5D0A0AC7E297CCC9504DCCB7F98867C7 - children - - D68697C739DE55500A7B6FD1FCCF5990 - 1BF33FD9958DE1C010305E6232266C1C - 1F721BDF91E7B499EDC6BF592E2E3305 - + includeInIndex + 1 isa - PBXGroup - name - Support Files + PBXFileReference + lastKnownFileType + text.xcconfig path - ../Target Support Files/JSPatch + Aspects.xcconfig sourceTree <group> - 578C31DBF114F1EA33E6C262C5F91502 + 5D9FA175E7E5F50DDB22B36A5B885871 includeInIndex 1 @@ -4346,40 +4194,27 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + UIImage+AFNetworking.h path - GeTuiSdk.h + UIKit+AFNetworking/UIImage+AFNetworking.h sourceTree <group> - 578D1C106A818A784DB887C5D5125FD6 - - fileRef - A76CA59A5280BEFC768D4A6F041FDA5B - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 57ED99A6F43DEC496661366FE7289BE4 + 5E54407AA7E6693446CC7A339437CB42 - fileRef - FB7ED69A0A9F3DBA39CF3BA76B660EFF + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + XAspect-prefix.pch + sourceTree + <group> - 582956321F29E8CB5D8D4000083FA273 + 5E57C78F83934D86D9A5171C30083D59 includeInIndex 1 @@ -4388,13 +4223,20 @@ lastKnownFileType sourcecode.c.h name - JSONModel.h + RACCommand.h path - JSONModel/JSONModel/JSONModel.h + ReactiveCocoa/RACCommand.h sourceTree <group> - 589EBB3F3E6E3A6A611453A4DD915ED5 + 5E5BDE19D3FDF21E91EB1F315B0F88C2 + + fileRef + 0CD13BB1A191EE2C413094C65571B015 + isa + PBXBuildFile + + 5E5FF559E666649849CFF4F8D446629C includeInIndex 1 @@ -4403,13 +4245,13 @@ lastKnownFileType sourcecode.c.h name - UIKit+AFNetworking.h + JSONHTTPClient.h path - UIKit+AFNetworking/UIKit+AFNetworking.h + JSONModel/JSONModelNetworking/JSONHTTPClient.h sourceTree <group> - 594DDD0D23DB6F4D39E406074E9A1567 + 5F0E8469FC02AC540B330E4A7119D5D0 includeInIndex 1 @@ -4418,36 +4260,29 @@ lastKnownFileType sourcecode.c.h name - NSIndexSet+RACSequenceAdditions.h + UIActivityIndicatorView+AFNetworking.h path - ReactiveCocoa/NSIndexSet+RACSequenceAdditions.h + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h sourceTree <group> - 5974F75F57FC1A6F3462B24D17473E06 + 600D5E33B16CAFA6B4D014105B16A468 - buildConfigurations - - EE99B43C5929107E4A199A7A9D6089B7 - FC5CE4331073DAEE9787ECB2636651C2 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + fileRef + 9BBA8775E91B0040A8C8A4656D2129FA isa - XCConfigurationList + PBXBuildFile - 597979276424D679342EEF34BAA8A48E + 6049A572440E4821C1B10E30F5FF4737 baseConfigurationReference - 3C2E6C0F5DED45010DBF171911913419 + 56F571FA2D6444BB3FBA0C111C67990D buildSettings ENABLE_STRICT_OBJC_MSGSEND YES GCC_PREFIX_HEADER - Target Support Files/ReactiveCocoa/ReactiveCocoa-prefix.pch + Target Support Files/SDWebImage/SDWebImage-prefix.pch IPHONEOS_DEPLOYMENT_TARGET 7.0 MTL_ENABLE_DEBUG_INFO @@ -4472,94 +4307,90 @@ name Release - 59847A0669985B7EC9B450E732C176FB - - children - - 62025C7C78033BDE974F2B6D80D47C55 - 5C80CF6C279B57FBE47D8A75882EF395 - 37CFFEB82DEEBCA425430E49FDB46660 - - isa - PBXGroup - name - Support Files - path - ../Target Support Files/JSONModel - sourceTree - <group> - - 5986E21E36132C23558BE0EEBD75BF46 + 6132A9AAF5EE8317947FEF91770BAE9A fileRef - 44A71989FF866B0D82B280F97DD420DF + 30C5085BB18CAB3AC2BF72421A1920E9 isa PBXBuildFile - - 5990D1386DBADFFF00C5F3FF1310B491 - - includeInIndex - 1 + settings + + ATTRIBUTES + + Public + + + + 6191584C259B4383F47D6A49A9D85E5C + + includeInIndex + 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - View+MASShorthandAdditions.h + XAWeaveHandler.cpp path - Masonry/View+MASShorthandAdditions.h + XAspect/Core/XAWeaveHandler.cpp + sourceTree + <group> + + 624D83EDE9EDC7F233F5990F01E3EF91 + + fileRef + 35C9733730903336A1E774698B6C7C4E + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 62545A9E0285F51FC4E1E71F2CE6A80B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + XAspect-dummy.m sourceTree <group> - 5A765CA0E436261D1B45E2F0AD0616E5 + 6295F5F4E67533BFB194EF1AAF8E8B08 fileRef - 9581E07B4327B07E261039619772514D + CD00BA036E9C58CB9D3ECC5375F367C7 isa PBXBuildFile - 5AA41E85613DF2260863CC8B56190903 + 62D91FB88A5559C6B04ACF3CCA3796AF children - 94BF98E095A6D64AA692166F71B54F78 - 7C273E9B543895B35DAF411ED5A56EE2 - 43AE592AB85786B82334A90B22D6F242 - D45DBCF012C00712D545E78EA25DDD79 - 27315171369949FC91F6841DC8AE5C11 - 60AD14B2C64B23BBE722C88159592DC2 - 840210445DEB38A5E16BFBBC95DF7950 - 6B47FA1360ACA44E86F301D6E038EF72 - 45C2BA9E4DE0353AB180CBA2980A3B28 - 7212BA6189003B1C5E5C937F57187EB6 - 24DACDB716D0D65FB76383CE0AD6B7CE - FFFBC385AE074ECF5DEE7254C05D04D1 - 4653CFBF8AD1185C23C763DAADD6F6DA - B0A92416C167D4187401DEF3A8C4B76C - 85D2F186A70780E097FE9B4938FEA711 - EC35FA32A2CD206519C0FF29685ECACC - 2F2C87C497B0D64D96372D87D03850BC - 64CA7095AAA3F4A1748B3FB792869BFF - B1992E4E26237C5C7D9355F0F0839C3B - AE1818531080A2759F2C77A7CE0C1AC2 - 450B9099B6CD2D7B19B3701CCFECD6CC - 092886A752FADB6A5E9DB78DE80535D2 - 4C4B9659BC5AC33C64193E5FE571EB83 - 9BCEB299DB4F34611D33AD9873136C33 - 9E83A243500C744DC9C3F465FEC14AA8 - D839E838BF47A54E1A485B25A793BDC2 - 30AA5F397CE54C4A547BA63A1D5E9DA6 - 2DEF2C4BF657F898F81DEFF23D313EC6 - 9BA172233D50DE6F6C742F0EEB20DB5E + A6D7C2ED9D950AC69718588F473EF2E6 + D3A075C816DF5B9D3CAE6AC0B93F2421 + 66A7F236D0D13B7ED6B9498F9776C50C + DBB7FF057A3318B501E048A372AED490 + C6C5BF6955312BDF8635A74BEE022378 + CD12C168AC0109196544C25F747EB5FB + 79A948C37401544C9175ACA45E716E89 + 12773A76172DB52068DDEBBF905E0B2E + 3C430ECABF95D2A08E06D008578A4C1B + 2466FC54A44F1DC257D1021AF7B4A8DD isa PBXGroup name - Core + Pods sourceTree <group> - 5B057523D44C0B53B6DC7CB2D150F7D9 + 632EBDB3CCB54217F760522A809A4EF6 includeInIndex 1 @@ -4568,59 +4399,87 @@ lastKnownFileType sourcecode.c.objc name - RACDelegateProxy.m + RACQueueScheduler.m path - ReactiveCocoa/RACDelegateProxy.m + ReactiveCocoa/RACQueueScheduler.m sourceTree <group> - 5B5B00543EABECF5F8B93CAA833A5DFD + 643A819CF4BA2FDDC598F64874E3ECFF fileRef - 55D160550DEE0C805734D9A79F8CECE6 + 89A790115BD0BD08D94190C5C21ED4D9 isa PBXBuildFile - 5C24294E2772182CBABB00DE001FE0D9 + 647B51417A1660D36E7FAE3CB2A38F36 fileRef - B0A92416C167D4187401DEF3A8C4B76C + 295D6E1DBF9FAA857725CE5884BDEC83 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 5C80CF6C279B57FBE47D8A75882EF395 + 657D857047A6A935B5A2E9BD049194F2 + + buildActionMask + 2147483647 + files + + 99D8C610BC84BE231C5D3D280F3B12AF + B2B7C90BA9C4DBD9851C75AC801B0E8E + 2905381350CEFFBFFA9BC8B5D027F190 + EC6CCC98505D2067BC98B4E6223C9DF8 + C6EE194D232E9FE87097C0F1DF91B9FA + 9205037BA8C22574B33FC96C5EA829A3 + FF682E8B083BAEBBDF38C52D89D45E37 + 3F63C119F95A6735AE627BBB1BEBC4B1 + EB02AEF303313F801392DE8D90AFF0F7 + FD39EBE3398E1A99965AC003B273450D + A7D31BD1F3AD4ED4612467FAD332F388 + 2979E54C4AFD27076576E82ADEED2F00 + DD1F717B0527C71229B3339324E35E55 + 432BD50F1E699EDF2EA007E850FFCEF7 + 331718BFB4A91CFFE026492905231562 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 6586B4DBB4F7173C33D43A5A81458397 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h + name + UIGestureRecognizer+RACSignalSupport.h path - JSONModel-dummy.m + ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.h sourceTree <group> - 5CB179AD935F8C7BA8F743AE0EDA93EF + 662AAA15A4707A8339251AA4D47587E5 + includeInIndex + 1 isa - PBXTargetDependency + PBXFileReference + lastKnownFileType + sourcecode.c.h name - SDWebImage - target - 44D882ADFA06DC141944859F300FC170 - targetProxy - FE3016F8D24573180CF7C7D05212A264 + UISegmentedControl+RACSignalSupport.h + path + ReactiveCocoa/UISegmentedControl+RACSignalSupport.h + sourceTree + <group> - 5CF0E043147B69E77976A2CCADFF18CA + 668796CCFC4D513A16AF9E665E8613B2 fileRef - 2B7CFB5A6E4A5548C8B4DA17DA35B01C + B7829DA442DED671B644E2881F1925BE isa PBXBuildFile settings @@ -4631,37 +4490,58 @@ - 5D251373B0F6F042640A5DFFE6594BF9 + 66A7F236D0D13B7ED6B9498F9776C50C - includeInIndex - 1 + children + + 1AECA3763F9718961E999D6D0D727222 + 00784913BB40755E9BD89DC8CB6F233A + 04DD6B49D851C7B2911B803CD7BBB076 + B0A088F025B46CF3549CF0EFF4FEE416 + 865F109140A1EAAC154F6FBA05124DDE + 387FB2EBE17C9CD07247829A3C8B6D08 + D75A579A255FA3FD070FD33E85C6F24B + 27E4264B68067CFF369F4D19682FA599 + 3853F138C9D4EEEC505839A6D27FEC0F + 1FED0BE0BA4386F2AB014F07CBAA5E0A + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - RACDynamicSignal.m + CYLTabBarController path - ReactiveCocoa/RACDynamicSignal.m + CYLTabBarController sourceTree <group> - 5D5275EB18EFA5A701E1F459538C0A2A + 66E55C0B562121517F4002078C2657EA + + fileRef + E6CA760B5394495E519115B0AB6C3DD9 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 671942142A25439F9D7DE7312A1E1C0E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFNetworkReachabilityManager.h + UIGestureRecognizer+RACSignalSupport.m path - AFNetworking/AFNetworkReachabilityManager.h + ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.m sourceTree <group> - 5DAFD622EC60936915F8F6D3985D6D06 + 675304FCB27570FCF0FC8E98745ED10C includeInIndex 1 @@ -4670,20 +4550,13 @@ lastKnownFileType sourcecode.c.h name - RACGroupedSignal.h + UITableViewCell+RACSignalSupport.h path - ReactiveCocoa/RACGroupedSignal.h + ReactiveCocoa/UITableViewCell+RACSignalSupport.h sourceTree <group> - 5E0CF2719FFDAB581CA902645FE2B8BB - - fileRef - F99004E5FF8745BDDB86E40F96AA5831 - isa - PBXBuildFile - - 5E13D78FF94819C6E7505F3D8815AADA + 676BECC6AE0171F9136A69F624DEB759 includeInIndex 1 @@ -4692,28 +4565,26 @@ lastKnownFileType sourcecode.c.objc name - NSSet+RACSequenceAdditions.m + RACEvent.m path - ReactiveCocoa/NSSet+RACSequenceAdditions.m + ReactiveCocoa/RACEvent.m sourceTree <group> - 5E22AF3F9B92CAC73AD5CADB03042700 + 67B8D1029C75C73F1643114628229333 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - NSInvocation+RACTypeParsing.h + sourcecode.c.objc path - ReactiveCocoa/NSInvocation+RACTypeParsing.h + CYLTabBarController-dummy.m sourceTree <group> - 5E3C273C72F0DFA9E5F91B3E089AB456 + 681E3A5D090DDD7CBE298EC8851D4D12 includeInIndex 1 @@ -4722,28 +4593,28 @@ lastKnownFileType sourcecode.c.objc name - UIGestureRecognizer+RACSignalSupport.m + RACArraySequence.m path - ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.m + ReactiveCocoa/RACArraySequence.m sourceTree <group> - 5E89FB3E7EF1A2C158337CDA267C6DBE + 684B248578D78367990650D36F7F710B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - Masonry.h + RACStringSequence.m path - Masonry/Masonry.h + ReactiveCocoa/RACStringSequence.m sourceTree <group> - 5ECFF58439CAB75C3D9A52A722AD320B + 68549E42677EBBF9FE7FDD396A1BC2B3 includeInIndex 1 @@ -4752,252 +4623,186 @@ lastKnownFileType sourcecode.c.objc name - NSString+RACSupport.m + RACScheduler.m path - ReactiveCocoa/NSString+RACSupport.m + ReactiveCocoa/RACScheduler.m sourceTree <group> - 5F03075BBDCFBD20AB6923384CCF0858 + 685E945BBC662FF58B7BBD7398B679F4 - children - - 4B9BFF5FC1917D3F67A2A654C2A7EA7E - CE3774003D0ED90A82FC9C28440DCC94 - 6AFDB77C029A97F36029E1075C05A73B - 1F721B4A74D3B50494ECAB26EB259DA1 - 1EC1EDEFF2F3CEE160D4FD254D03DE25 - 318EB9DB0FE9C89496A38CE3FF6A616E - 52BF3A8C015B33CB9A15012AEA9221A0 - 0840A76EC690C8025301D5B2587F04F9 - F440593CC80B6F762E15F1ED231B4E19 - B793FFC7E3BBE870834BBCB42A153059 - F02B853176928C740B241F44B5FB6835 - 90225DC600376307F93B98526613466C - C7F82F3525440A2409D8442F2AEE6EB7 - 7CFA7F5DB23ABC94ED59EF2F31831B28 - 456F16D56E6A14837886973506955D7F - BCCA176AFF17EF4AA821307506265219 - 35F21F926D9A165521BF874A38D9FDB6 - 3381F12C163CA27DAB6C05AB64098D9E - 53F994A22B989C221A117FAD0D6C9039 - 5E3C273C72F0DFA9E5F91B3E089AB456 - 3036C5663F553FD2A22AD6B74961059A - 44A71989FF866B0D82B280F97DD420DF - 64D961BC28FF0980169D5D182D46C73B - 9B4079315421A87E5A1C764DEDA7C89B - 175855F4E67EE3757EA4DDFBF012D699 - F80F668A8F6E7D9DF4DDD32E7E99A09E - BE05843E2D30494B31AE9076742B8F06 - A19586CD7DCB89EA5B3DDA7483F0A718 - 7B37AAA08BAC43E0F6C4FF873F7E3273 - 6509BE6630BA341AA28BF274D5CFE776 - 14A13A3D04A19FF2940A9A03A5A51B3E - 042A892BF73D36F9B88BD05E3CA301C0 - F739D150BC139BBFC781BC5FF683F53F - 76284515223FB7A04FEFF4D49AF1E1D2 - 0BF4AC0E7090CAC0D919A6E0A1A516A6 - 72C4EE7AE7085C00CA1A9DCE3FC57C59 - 3FA351C84EA2D69232792EFB51B72FA2 - F3E0BF3FC9B1D5D5AC7BD46E8C386867 - 1A8FFA3542A05775083D1E3FD7E8D2A8 - 0F560B4734048E5F6E51CDF94FB54F23 - + fileRef + C759D8EE6C549CDFC482E9379D31EFB9 isa - PBXGroup - name - UI + PBXBuildFile + + 68F43AA8292D8A77222F96E23757EBB0 + + fileRef + 4E88B7E7DCA9967A4633781A315EC83B + isa + PBXBuildFile + + 6911BECA35E7518D864239B7E898EEF3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.script.sh + path + Pods-frameworks.sh sourceTree <group> - 5F6D57308FA578FEA1CA7A71481B91CA + 69ACA4208C1F51ECCB41C7D2864D303D - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - libJSPatch.a + UICollectionReusableView+RACSignalSupport.m path - libJSPatch.a + ReactiveCocoa/UICollectionReusableView+RACSignalSupport.m sourceTree - BUILT_PRODUCTS_DIR + <group> - 5FF2061AAC0FBD245CF04573AA4ADE56 + 6A382666DCE8BFAE7DFEC59B6C20509E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACTargetQueueScheduler.h + UIActionSheet+RACSignalSupport.m path - ReactiveCocoa/RACTargetQueueScheduler.h + ReactiveCocoa/UIActionSheet+RACSignalSupport.m sourceTree <group> - 604CBAE3DC780CF18CB503A744D86B86 + 6AF685B991DFAD51D1E7573EFFA6F6AF - fileRef - 166AF8E27F5F2151A8AF1B759147B106 + buildActionMask + 2147483647 + files + + 3C757A84FE4BBBE771B8C34732449358 + isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 60736EC54BE1D87D7A885F42DF4E8881 + 6B66FA500853F6DC68BA08E3336FC833 - children - - C2F679593251F2B5A69C3E1DA3FFA626 - 4501BB97D1C911881570F821973707C0 - 3627EC5EB57BDEC23FA1FE15CE9B0B1D - 7713EB3C0BB8ED587C881CD4F535F399 - 4069A76AF3FE40D2B67B378ADC73A274 - B3EA2063C2573EB1BF8FEDF682589413 - A75919C63C7C2CD096767B4D9FDB1E98 - A045C84F164672568EB40F90886FB6C8 - C24B2A8EF774E2F65A8CF2F8727C6DDE - 6FABC5D092036506A214283870ACBB0A - + containerPortal + D41D8CD98F00B204E9800998ECF8427E isa - PBXGroup - name - Pods - sourceTree - <group> + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 09FA060F1A0492FB25232F489AC4E573 + remoteInfo + JSONModel - 60AD14B2C64B23BBE722C88159592DC2 + 6BA10D4286688F83720041C63E248375 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SDWebImageCompat.m + UIRefreshControl+RACCommandSupport.h path - SDWebImage/SDWebImageCompat.m + ReactiveCocoa/UIRefreshControl+RACCommandSupport.h sourceTree <group> - 60BCD0BF9F9B39893E55466EBC20A273 + 6BED4DDD022C6F6F69A4E108741AB69C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc + name + ViewController+MASAdditions.m path - Masonry-prefix.pch + Masonry/ViewController+MASAdditions.m sourceTree <group> - 612D1A2852BEA130961DAD1917197A64 + 6BF5EAEFA9CA9FA862AF2D37D8D5B7BC includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - RACValueTransformer.h + text.xcconfig path - ReactiveCocoa/RACValueTransformer.h + CYLTabBarController.xcconfig sourceTree <group> - 617AFA0F321ECCAB547A8C3B986B7021 + 6CC4B79C1FEE1E7B3F2860ADA479D381 - baseConfigurationReference - CC2EF386E6EB31FC9BC5D90FD15B70B1 - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/SDWebImage/SDWebImage-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - + fileRef + 2A1D3F97B2BE40F6F3A8892047D86035 isa - XCBuildConfiguration - name - Debug + PBXBuildFile - 62025C7C78033BDE974F2B6D80D47C55 + 6CF371128BD01C378F8B6D67975C4BAF includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + JSONKeyMapper.m path - JSONModel.xcconfig + JSONModel/JSONModelTransformations/JSONKeyMapper.m sourceTree <group> - 6265DE8669B72124D597C877F521FA7B + 6CFD7DC1ED89F875CD7399DB254A722A includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + View+MASAdditions.m path - Masonry.xcconfig + Masonry/View+MASAdditions.m sourceTree <group> - 62F30D9AF07C2D503845301942FA9F9C + 6D5E390D425D49D2FA0F9AEA0203B94E - includeInIndex - 1 + fileRef + B54AD408F1721A01D775611A2BB31C2A isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - JSONAPI.h - path - JSONModel/JSONModelNetworking/JSONAPI.h - sourceTree - <group> + PBXBuildFile - 632A39BA3F9D70C0BD101E359A1AC231 + 6D69F79DD850CB749BB1BAC136544A8B fileRef - CD1044A204A17CE5F93A1D622654107A + 0D47C7A5E1BF67CDDE0D3DED4C2BF6C4 isa PBXBuildFile settings @@ -5008,32 +4813,10 @@ - 6371AF01D6F66B6A45C901711DB2419F - - fileRef - E798802252FBC085207B7EF5246FD5D4 - isa - PBXBuildFile - - 63958894F8A2B30EC7DC43706ED1A1CA - - explicitFileType - archive.ar - includeInIndex - 0 - isa - PBXFileReference - name - libXAspect.a - path - libXAspect.a - sourceTree - BUILT_PRODUCTS_DIR - - 63B1F71E874C62729356BB6BA70B81BA + 6E29A32A796A3FA6689C81E4FABA8A8E fileRef - E5AE29ED4BEFE8DAB244B278DDBC06CE + FDBBAAAFCF83B7732FCB13B9D0CD9A95 isa PBXBuildFile settings @@ -5044,36 +4827,37 @@ - 649FF807928997233B038A6E36B44EA6 + 6E3C0A6DD3A355BCDB7308E8DAF5BBBC fileRef - 1427ED6340412B09D2BF2A59633C7302 + 083BA6BFEB763C731F02688780A11EB3 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 64CA7095AAA3F4A1748B3FB792869BFF + 6EEA72BE015541ED3D178BEF9BB5788F - includeInIndex - 1 + buildActionMask + 2147483647 + files + + 85AC21BC7BD345D84F489F7A52D39E44 + D2718FB5214DA8A524CE735932323F82 + 4BDE97C783ED286933A60CAE9292B775 + F7B5D2658B77049DDEC0AAA88E6FCEA7 + B82A170962598E7EAE9A8752574B7B74 + 52B9F1F399DEADDDFBE3F17BAA8D6D14 + 740B64AC8CA44CDC54A3A2CCB396A0EB + F4D2A0918C2C064F1A16B4CA2D42089A + C591CE6B9FA1950409E543A70B3ECABE + 04E0EFD308A39DA6783F9004C5689973 + 8F11ABA0C553B18981097015226E5748 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIButton+WebCache.h - path - SDWebImage/UIButton+WebCache.h - sourceTree - <group> + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 64D961BC28FF0980169D5D182D46C73B + 6FEE79E9096E50FC8463117C1A92244A includeInIndex 1 @@ -5082,97 +4866,57 @@ lastKnownFileType sourcecode.c.h name - UIRefreshControl+RACCommandSupport.h + UIStepper+RACSignalSupport.h path - ReactiveCocoa/UIRefreshControl+RACCommandSupport.h + ReactiveCocoa/UIStepper+RACSignalSupport.h sourceTree <group> - 6509BE6630BA341AA28BF274D5CFE776 + 70155E0155171E5488D76943F2A0E0C5 - includeInIndex - 1 + fileRef + D6C7385C2B2E7DCC766B9AB7B0667CD1 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIStepper+RACSignalSupport.m - path - ReactiveCocoa/UIStepper+RACSignalSupport.m - sourceTree - <group> + PBXBuildFile - 653373DBD04FF1B2F6C342D54259312F + 706DD8FF096C234E8CA60A7C2853884B fileRef - 94BF98E095A6D64AA692166F71B54F78 + 04DD6B49D851C7B2911B803CD7BBB076 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 65499AC1710351B8E561AF69182FB0AE + 70725A3D27E3186C99D5E59262792240 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACSignal+Operations.h + MASViewAttribute.m path - ReactiveCocoa/RACSignal+Operations.h + Masonry/MASViewAttribute.m sourceTree <group> - 657D857047A6A935B5A2E9BD049194F2 - - buildActionMask - 2147483647 - files - - 99D8C610BC84BE231C5D3D280F3B12AF - B2B7C90BA9C4DBD9851C75AC801B0E8E - 2905381350CEFFBFFA9BC8B5D027F190 - EC6CCC98505D2067BC98B4E6223C9DF8 - C6EE194D232E9FE87097C0F1DF91B9FA - 9205037BA8C22574B33FC96C5EA829A3 - FF682E8B083BAEBBDF38C52D89D45E37 - 3F63C119F95A6735AE627BBB1BEBC4B1 - EB02AEF303313F801392DE8D90AFF0F7 - FD39EBE3398E1A99965AC003B273450D - A7D31BD1F3AD4ED4612467FAD332F388 - 2979E54C4AFD27076576E82ADEED2F00 - DD1F717B0527C71229B3339324E35E55 - 432BD50F1E699EDF2EA007E850FFCEF7 - 331718BFB4A91CFFE026492905231562 - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 65885D26E021BDBB24AA0FD2FFF56189 + 711BF74F0676B87A2838048351DE2206 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h + name + RACSignal+Operations.h path - ReactiveCocoa-dummy.m + ReactiveCocoa/RACSignal+Operations.h sourceTree <group> - 659B6927C788554CB763D95DD9F6DB5F + 713D0E466D846A783F4E86DDEFC8BFD3 includeInIndex 1 @@ -5181,34 +4925,30 @@ lastKnownFileType sourcecode.c.objc name - RACErrorSignal.m + AFURLRequestSerialization.m path - ReactiveCocoa/RACErrorSignal.m + AFNetworking/AFURLRequestSerialization.m sourceTree <group> - 668B6BE66CAB748280DE10AF4F3B3459 - - fileRef - FA4AF3EAA8C3A19405FB7B9B433420E9 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 66AA607A66B431C3CFA1C96A1BFC835F + 71D5AD4B97B2ECC6334D47154106A638 - fileRef - D5A3134C9C8FF8D3E667992F788A7878 + children + + E9BADEC7E474ADE375184CB25246C401 + 89A790115BD0BD08D94190C5C21ED4D9 + 28B3735D05F98097DB382C1EF7AF13F5 + isa - PBXBuildFile + PBXGroup + name + Support Files + path + ../Target Support Files/ReactiveCocoa + sourceTree + <group> - 66E5E1A295BA40E925541B25C4537640 + 721201CF6A2409961E43ECE1DDFC967D includeInIndex 1 @@ -5217,13 +4957,13 @@ lastKnownFileType sourcecode.c.objc name - AFSecurityPolicy.m + UIButton+RACCommandSupport.m path - AFNetworking/AFSecurityPolicy.m + ReactiveCocoa/UIButton+RACCommandSupport.m sourceTree <group> - 66EA37CF5A484C13AC109BA581C4D752 + 72EBC3B91782DFC648C33324DEF5FB15 includeInIndex 1 @@ -5231,48 +4971,41 @@ PBXFileReference lastKnownFileType sourcecode.c.objc - name - RACSignal+Operations.m path - ReactiveCocoa/RACSignal+Operations.m + AFNetworking-dummy.m sourceTree <group> - 684F328D84DB590851126DD1D1FA216F - - fileRef - A19586CD7DCB89EA5B3DDA7483F0A718 - isa - PBXBuildFile - - 68A676CA9611F12A731685F671246F1B + 72FA5359D02494B65F8FA39A3EDB1105 - fileRef - 2882B29F5EBCE5F56C70A9BA592A80C8 + buildConfigurations + + 768D5CAEB176483C02F75BDDF4AB0863 + 6049A572440E4821C1B10E30F5FF4737 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + XCConfigurationList - 6911BECA35E7518D864239B7E898EEF3 + 7312D5806639AF8561995B0A9F0C6672 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.script.sh + sourcecode.c.objc + name + RACTargetQueueScheduler.m path - Pods-frameworks.sh + ReactiveCocoa/RACTargetQueueScheduler.m sourceTree <group> - 6948B9FC8DCDBE2B7AD843CB44B933E6 + 734A04097CA3CF6720EE747B9D5D62A1 includeInIndex 1 @@ -5281,53 +5014,52 @@ lastKnownFileType sourcecode.c.h name - RACSubscriptingAssignmentTrampoline.h + UIButton+WebCache.h path - ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h + SDWebImage/UIButton+WebCache.h sourceTree <group> - 69CC3D71377DFD142B605B31539E917D + 735843161B754292F8061E3F63C071C5 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - JSONValueTransformer.m + SDWebImageManager.h path - JSONModel/JSONModelTransformations/JSONValueTransformer.m + SDWebImage/SDWebImageManager.h sourceTree <group> - 69D3AFBA28E3FD4F7EA643CE40728F27 + 735C79180B9DF12451E642F5546F7159 - includeInIndex - 1 + fileRef + CDAE64017A222509F608FA2BF5581A14 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - NSArray+RACSequenceAdditions.m - path - ReactiveCocoa/NSArray+RACSequenceAdditions.m - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 69E080A3E3655867E7296826684D9E27 + 7368F13141E5B9ADAD8D6E9BDCB90984 fileRef - 9BBDDF71F74B6BF4ABC9FEE4368B7CE5 + B563B9616A97A1BA104410BAC9A46D70 isa PBXBuildFile - 6A16AE4364E1411E0182AED9B95181E4 + 73FD0B0A878D9777A94B79FAD29288A2 fileRef - 9BCEB299DB4F34611D33AD9873136C33 + E37E92E243FD74EE0405FD37AEB53427 isa PBXBuildFile settings @@ -5338,10 +5070,10 @@ - 6A5696ABF473C9BF45B27A0566F3EADD + 740B64AC8CA44CDC54A3A2CCB396A0EB fileRef - 65499AC1710351B8E561AF69182FB0AE + 04783261FB6729BD15B0FE2946512043 isa PBXBuildFile settings @@ -5352,79 +5084,50 @@ - 6AC09D1314CA9AA3CDF4938347A11233 + 741BF78A50444622EEC3602E1EBD1DD6 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference - name - libAFNetworking.a + lastKnownFileType + text.xcconfig path - libAFNetworking.a + JSONModel.xcconfig sourceTree - BUILT_PRODUCTS_DIR - - 6AF685B991DFAD51D1E7573EFFA6F6AF - - buildActionMask - 2147483647 - files - - 3C757A84FE4BBBE771B8C34732449358 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 + <group> - 6AFDB77C029A97F36029E1075C05A73B + 74688FDEAD67A2999F1D34587BF6CC1D includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIActionSheet+RACSignalSupport.h + RACSignalSequence.m path - ReactiveCocoa/UIActionSheet+RACSignalSupport.h + ReactiveCocoa/RACSignalSequence.m sourceTree <group> - 6B47FA1360ACA44E86F301D6E038EF72 + 749BF5902E6E6891EF6ADC8A272817EC includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SDWebImageDecoder.m + RACEvent.h path - SDWebImage/SDWebImageDecoder.m + ReactiveCocoa/RACEvent.h sourceTree <group> - 6BC4B87350EBF064A54481585D49217D - - fileRef - D9D358458CED65BE821E001F12A5BAAF - isa - PBXBuildFile - - 6CC4B79C1FEE1E7B3F2860ADA479D381 - - fileRef - 9FF7B15B9B58DC7A83404A0D9C5C54B0 - isa - PBXBuildFile - - 6DA0DC0C3DFC0404452E564B270EFFB6 + 74ACE91E1BB28EE8AE35E3B58C9D3A3A includeInIndex 1 @@ -5433,185 +5136,190 @@ lastKnownFileType sourcecode.c.objc name - RACArraySequence.m + JSONModelError.m path - ReactiveCocoa/RACArraySequence.m + JSONModel/JSONModel/JSONModelError.m sourceTree <group> - 6DBF47AC3273F90C0F0DF4840AA26E76 + 74FB10F38FF81777F07B011E6D876890 fileRef - 1AD05E1CA714ECE615C8565333127E0D + 993BAA0FDA7062280D3005B655BC8388 isa PBXBuildFile settings ATTRIBUTES - Private + Public - 6E44AA3980A4EA3C258E38573C306B36 + 757AB9A022318505C082F40A7593F219 fileRef - 0DE232DA7DF9A5C4EDF146731CF8296A + CDDC6FA3D49D36AB2802BBDEFA5F6229 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 6E824E86B7D5F406164E3D0C0999A900 + 75BD3BC18F7C32C1E34AD675CBF9745C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - NSFileHandle+RACSupport.m - path - ReactiveCocoa/NSFileHandle+RACSupport.m - sourceTree - <group> - - 6EEA72BE015541ED3D178BEF9BB5788F - - buildActionMask - 2147483647 - files - - 85AC21BC7BD345D84F489F7A52D39E44 - D2718FB5214DA8A524CE735932323F82 - 4BDE97C783ED286933A60CAE9292B775 - F7B5D2658B77049DDEC0AAA88E6FCEA7 - B82A170962598E7EAE9A8752574B7B74 - 52B9F1F399DEADDDFBE3F17BAA8D6D14 - 740B64AC8CA44CDC54A3A2CCB396A0EB - F4D2A0918C2C064F1A16B4CA2D42089A - C591CE6B9FA1950409E543A70B3ECABE - 04E0EFD308A39DA6783F9004C5689973 - 8F11ABA0C553B18981097015226E5748 - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 6FABC5D092036506A214283870ACBB0A - - children - - A76CA59A5280BEFC768D4A6F041FDA5B - F675A8DDF41D4884C065D13E96007B65 - 8678110FA27548FEDD8C52F43C4E14DE - A5F1C550C9A786773B3D74637E17FBF0 - - isa - PBXGroup + sourcecode.c.h name - XAspect + RACSerialDisposable.h path - XAspect + ReactiveCocoa/RACSerialDisposable.h sourceTree <group> - 6FB3CFFEB44E4B8FCDDB27217F9D183D + 75FC5A679675C9B89843197C7D3171C5 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSIndexSet+RACSequenceAdditions.m + NSObject+RACLifting.h path - ReactiveCocoa/NSIndexSet+RACSequenceAdditions.m + ReactiveCocoa/NSObject+RACLifting.h sourceTree <group> - 7009EBE73A4C910697A4A21282089B06 + 7637FB30274DC6B03009AA159CE0A71B fileRef - 5E13D78FF94819C6E7505F3D8815AADA + EF3011E738122A0A380DCA81ECB7D10A isa PBXBuildFile - 7053FA23055952EFF57A2801B729A9CE + 768D5CAEB176483C02F75BDDF4AB0863 + + baseConfigurationReference + 56F571FA2D6444BB3FBA0C111C67990D + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/SDWebImage/SDWebImage-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 7693BDEA465D6C29949FE81042B49EA0 fileRef - 31BCD314D8CE512714D93706A0A3B3DC + 9A84EA35F2D3E77AC5001D80E576C6B4 isa PBXBuildFile - 706DD8FF096C234E8CA60A7C2853884B + 770AB12294B26508E28247BEC572575A + + fileRef + 82E7AC6E1DD676A02A27FA9E194066B0 + isa + PBXBuildFile + + 78449FCC01114171AA3CCB45C6666206 + + fileRef + 84FA53805A65251FC0CAB19D0585B085 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 78B4B0ED9E5D576E2CC167B19E15E2C4 fileRef - 0DB63366B7DC9D5E4E7C9F708755B486 + 4C6474D7F773FABA0133ABC73E98E0BF isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 7105BBEE0C908BB9E862D6102DB7E3FF + 78EE318D7701BC658F2ABDA07708B7C0 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIViewController+CYLTabBarControllerExtention.m + RACSubscriptingAssignmentTrampoline.h path - CYLTabBarController/UIViewController+CYLTabBarControllerExtention.m + ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h sourceTree <group> - 7165930A2A48BA178E2CFFDBEB5EF44F + 79A948C37401544C9175ACA45E716E89 children - 2E07A2ED41CC4C210937008043C4B332 - 66E5E1A295BA40E925541B25C4537640 + C993A0F96A6FAAEF55798FAB1E3D894C + A5073D16941EDD4CB431B45A76CEE34C + 71D5AD4B97B2ECC6334D47154106A638 + CDE3EFC66341F11D494C06362FB5F7F0 isa PBXGroup name - Security + ReactiveCocoa + path + ReactiveCocoa sourceTree <group> - 72052010D04CF675D6C01C79BF5887D6 - - buildActionMask - 2147483647 - files - - 653373DBD04FF1B2F6C342D54259312F - 84F10C258F259000E87C41346A59DF0F - A0503615C92C99E334D18915FE4EE893 - EF73143168A51F29EB621728AC617319 - 73B8B11A63522C4E451763F16F578223 - 75870094AFD05335240C309747B6E493 - 039892CB5DDF40C2F2F7A64014E83136 - 03A20335F57AA5151013ADC7CEE230EF - 3F9FF0984677E78E3E38509B95F26CDA - B2B30D15E8EE4B35D69F4DA1CF7B5D2F - A49AA631EEBC0BD569839ABE28E0EB23 - A8D7C578B6B68B5495F6FF5D31A59BAD - 6A16AE4364E1411E0182AED9B95181E4 - AECD5709B98654660022402C007A5FBB - 720612738291E1FB048A4A9490F92431 - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 720612738291E1FB048A4A9490F92431 + 7A14C29ABC66BCFA43F739CA14743E84 fileRef - 2DEF2C4BF657F898F81DEFF23D313EC6 + 662AAA15A4707A8339251AA4D47587E5 isa PBXBuildFile settings @@ -5622,7 +5330,22 @@ - 7212BA6189003B1C5E5C937F57187EB6 + 7A3EE7C0964DB86D3D08DDDF2F1EAF72 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UITextField+RACSignalSupport.h + path + ReactiveCocoa/UITextField+RACSignalSupport.h + sourceTree + <group> + + 7A4C14BBA7CAC02D27A295C3CA226CF1 includeInIndex 1 @@ -5631,23 +5354,31 @@ lastKnownFileType sourcecode.c.objc name - SDWebImageDownloader.m + RACValueTransformer.m path - SDWebImage/SDWebImageDownloader.m + ReactiveCocoa/RACValueTransformer.m sourceTree <group> - 7248B9BD088DBD52635462FD79DCE8E0 + 7A6BC89400594DE9E000159B75A95DD3 - fileRef - D5ACC55E5D76B8F4D99C462E4E394EA0 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACTuple.m + path + ReactiveCocoa/RACTuple.m + sourceTree + <group> - 72560F1BBE2BB763F4B17992EB9525B2 + 7C89D1A84817BE82CBF7CE79D861C7CD baseConfigurationReference - 3C2E6C0F5DED45010DBF171911913419 + E9BADEC7E474ADE375184CB25246C401 buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -5657,7 +5388,7 @@ IPHONEOS_DEPLOYMENT_TARGET 7.0 MTL_ENABLE_DEBUG_INFO - YES + NO OTHER_LDFLAGS OTHER_LIBTOOLFLAGS @@ -5676,162 +5407,109 @@ isa XCBuildConfiguration name - Debug + Release - 72C4EE7AE7085C00CA1A9DCE3FC57C59 + 7CD30ED4BF2E42E61802AA7A7FCCA86D includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UITableViewHeaderFooterView+RACSignalSupport.m + RACStream+Private.h path - ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.m + ReactiveCocoa/RACStream+Private.h sourceTree <group> - 734BEF397C9DA28B4B2D333301B13D20 + 7DA510557E0ACF4EA57AC39B20BB825C - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - path - XAspect-dummy.m - sourceTree - <group> - - 736EEB09A74B695F08491CBA8B52FF0F - - fileRef - EDFDFB257B49EF3F125E7706606F1B76 - isa - PBXBuildFile - - 73B8B11A63522C4E451763F16F578223 - - fileRef - 45C2BA9E4DE0353AB180CBA2980A3B28 + fileRef + 407E04979D0276E5B91DC610CD6BACF7 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 73D9BAC9052E44B48D7E6F4F9BD4E1DF + 7DB346D0F39D3F0E887471402A8071AB - includeInIndex - 1 + children + + BA6428E9F66FD5A23C0A2E06ED26CD2F + F4CDA5FA9197A41E0081E84F932906EB + 62D91FB88A5559C6B04ACF3CCA3796AF + D729A403EF8B197790AB0FCD68642870 + 037C0CA694176A3C0915F62C9D20B3E6 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACTupleSequence.h - path - ReactiveCocoa/RACTupleSequence.h + PBXGroup sourceTree <group> - 740B64AC8CA44CDC54A3A2CCB396A0EB + 7E5F1915B3A4DA3F809619F72949F326 fileRef - 54AAF0ACDEE2311575C5E85802ADF939 + A594D67EE669883807FBCA765E8B552D isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 7452892FA18756C935569E6F334C60D7 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - MASConstraintMaker.h - path - Masonry/MASConstraintMaker.h - sourceTree - <group> - 74A9563003AD0CD00CEAA62AB72D5DC5 + 7EB894EBB317D982B7B92A918749CCF8 - fileRef - 9E83A243500C744DC9C3F465FEC14AA8 - isa - PBXBuildFile - settings + baseConfigurationReference + 8C7CDB026EEE224CDFF0F69F0B9AAFD4 + buildSettings - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/XAspect/XAspect-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES - - 755228EBEDB3A61E5D08B3D96B94866F - - fileRef - AFA25CF4BA70362C1030B679756120BC isa - PBXBuildFile + XCBuildConfiguration + name + Debug - 75870094AFD05335240C309747B6E493 + 7EBD5076B9B45389A3EA4F80DDB7527D fileRef - 24DACDB716D0D65FB76383CE0AD6B7CE + ED7D2955A29AA5EF791E7EE4B001F536 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 758978F83428DA4D8B66E32E141B5885 + 7EECED4464BFD6C89FDB21CC4B759B0C includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - XAWeaveHandler.cpp + RACSubscriptingAssignmentTrampoline.m path - XAspect/Core/XAWeaveHandler.cpp + ReactiveCocoa/RACSubscriptingAssignmentTrampoline.m sourceTree <group> - 75BC3C18F37656F0FD2FD6ABC00E6BC1 - - fileRef - 266B4A862FADF8F742BE61443E0BFFE4 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 75D2D91A65315844BFD96735D194EBF1 + 7F032C0F9E4566CBAD7B1284E266B421 includeInIndex 1 @@ -5840,16 +5518,16 @@ lastKnownFileType sourcecode.c.h name - AFHTTPRequestOperationManager.h + NSArray+MASAdditions.h path - AFNetworking/AFHTTPRequestOperationManager.h + Masonry/NSArray+MASAdditions.h sourceTree <group> - 7603E1889EADD4D3C15E68C049444BE0 + 7F3AC1A845FDA6BDB97B7EFA12507D24 fileRef - 14919C8D2FFE698835E4311BDCF86454 + A565A9CD7A9918942D221C5F1F513775 isa PBXBuildFile settings @@ -5860,7 +5538,7 @@ - 76284515223FB7A04FEFF4D49AF1E1D2 + 7F5BCC339FDC6DAD6F47209EB375853A includeInIndex 1 @@ -5869,77 +5547,45 @@ lastKnownFileType sourcecode.c.objc name - UITableViewCell+RACSignalSupport.m - path - ReactiveCocoa/UITableViewCell+RACSignalSupport.m - sourceTree - <group> - - 764F684BDBDE99D982727FDAACEF4E56 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - View+MASAdditions.h - path - Masonry/View+MASAdditions.h - sourceTree - <group> - - 76B7C27071A6D22260FC2A2585F070BD - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - AFNetworkActivityIndicatorManager.h + UIButton+AFNetworking.m path - UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h + UIKit+AFNetworking/UIButton+AFNetworking.m sourceTree <group> - 7713EB3C0BB8ED587C881CD4F535F399 + 7FDE432BEF7E4CC2DD3C3D87CD8FF2BF children - 578C31DBF114F1EA33E6C262C5F91502 - 2DF80ED2E50ED5C37521FBA2B7A17D92 + B39D5AFCAA041CAB23BCBF0A2106C8F2 + E9BC93CF7243043504BABAE792DD43DA isa PBXGroup name - GTSDK - path - GTSDK + Security sourceTree <group> - 77BB46BF30AAC5AB432DA6C3A713CA77 + 806C455763F0201F34934C508E0DC535 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSURLConnection+RACSupport.h + SDWebImageCompat.m path - ReactiveCocoa/NSURLConnection+RACSupport.h + SDWebImage/SDWebImageCompat.m sourceTree <group> - 78449FCC01114171AA3CCB45C6666206 + 80B0636973B4F8BB830EBEB75D2920C9 fileRef - 5D5275EB18EFA5A701E1F459538C0A2A + 273AFE3662E49F40E4CF533147A8403B isa PBXBuildFile settings @@ -5950,25 +5596,10 @@ - 78A05F5CF4D02BC837A4B681217E6AE3 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIImageView+AFNetworking.m - path - UIKit+AFNetworking/UIImageView+AFNetworking.m - sourceTree - <group> - - 79BFBE9732F0C0FAA510FD4F42952A23 + 80BA7C1922DFC238B40790F5B9A54D5C fileRef - 7D54366BBEF328FFFE4BBC880BA20652 + F7AF88794E0B7118A5A846E9DBB7B270 isa PBXBuildFile settings @@ -5979,14 +5610,21 @@ - 79C87CB103AEE07E13CC34AC6471EA15 + 80FEFD0365FE84022A1A34BDEEC4CAC1 + + fileRef + 681E3A5D090DDD7CBE298EC8851D4D12 + isa + PBXBuildFile + + 81403CAF6C4C1D3DC8B199289C3A6F59 fileRef - 9B7D7D173492E46E3FFB0460E54F6116 + 6CFD7DC1ED89F875CD7399DB254A722A isa PBXBuildFile - 7A225968E7F6AB6C378FB62566296289 + 81551035D30538526F3A9F2D9B2E527C includeInIndex 1 @@ -5995,13 +5633,20 @@ lastKnownFileType sourcecode.c.objc name - NSEnumerator+RACSequenceAdditions.m + NSArray+JSONModel.m path - ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m + JSONModel/JSONModelCategories/NSArray+JSONModel.m sourceTree <group> - 7B10139C1E058D94E92D0617DF8E546E + 81599471BAB0420D54E1ADF8507A5113 + + fileRef + 2CF9FBC4489F08B20D878E03F666B249 + isa + PBXBuildFile + + 816C4B8A46C88A91F732149F9D473D31 includeInIndex 1 @@ -6009,14 +5654,12 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - CYLTabBar.h path - CYLTabBarController/CYLTabBar.h + AFNetworking-prefix.pch sourceTree <group> - 7B37AAA08BAC43E0F6C4FF873F7E3273 + 8186776A47C9D6ED6108AB91550A0989 includeInIndex 1 @@ -6025,13 +5668,13 @@ lastKnownFileType sourcecode.c.h name - UIStepper+RACSignalSupport.h + NSObject+RACPropertySubscribing.h path - ReactiveCocoa/UIStepper+RACSignalSupport.h + ReactiveCocoa/NSObject+RACPropertySubscribing.h sourceTree <group> - 7BC207DADFD902C9E0F9E6C8749A426D + 819F984CC9898B5312ECF9E98583F654 includeInIndex 1 @@ -6040,58 +5683,83 @@ lastKnownFileType sourcecode.c.h name - MASConstraint.h + RACKVOChannel.h path - Masonry/MASConstraint.h + ReactiveCocoa/RACKVOChannel.h sourceTree <group> - 7C0B6DF4BE36BA1A66A246C00CF08D4F + 829DC7ED7E34A0152C4EDADFB8F3835D + + isa + PBXTargetDependency + name + AFNetworking + target + 410B25DF16EA5C5B3E2698F74F9625FB + targetProxy + 3F25A1DC4B91D20E8556F88DB73F8752 + + 82E7AC6E1DD676A02A27FA9E194066B0 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSEnumerator+RACSequenceAdditions.h + RACChannel.m path - ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h + ReactiveCocoa/RACChannel.m sourceTree <group> - 7C273E9B543895B35DAF411ED5A56EE2 + 842F3DEE88D6DCE5D1FA98AC555293A8 + + fileRef + 9ED632B427AC3FAECB45343B6F534A01 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 84A3EE0BF19E2B36FF89FEC07C01A761 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSData+ImageContentType.m + AFURLResponseSerialization.h path - SDWebImage/NSData+ImageContentType.m + AFNetworking/AFURLResponseSerialization.h sourceTree <group> - 7CFA7F5DB23ABC94ED59EF2F31831B28 + 84C7FB4EDD986892F01177AECEB92FD1 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIControl+RACSignalSupport.m + RACKVOTrampoline.h path - ReactiveCocoa/UIControl+RACSignalSupport.m + ReactiveCocoa/RACKVOTrampoline.h sourceTree <group> - 7D54366BBEF328FFFE4BBC880BA20652 + 84FA53805A65251FC0CAB19D0585B085 includeInIndex 1 @@ -6100,39 +5768,77 @@ lastKnownFileType sourcecode.c.h name - NSNotificationCenter+RACSupport.h + AFNetworkReachabilityManager.h path - ReactiveCocoa/NSNotificationCenter+RACSupport.h + AFNetworking/AFNetworkReachabilityManager.h sourceTree <group> - 7DB346D0F39D3F0E887471402A8071AB + 8505AC4941A9B561D847933B53664111 - children - - BA6428E9F66FD5A23C0A2E06ED26CD2F - F4CDA5FA9197A41E0081E84F932906EB - 60736EC54BE1D87D7A885F42DF4E8881 - DB35818992FDC0EF557CED682DEE6AFE - 037C0CA694176A3C0915F62C9D20B3E6 + fileRef + 0BE788C3CB3F7E78E23D1D390D939DAB + isa + PBXBuildFile + + 851767040BDDEE2669237ECD7AAEBBF7 + + children + + 9C71D296FA604ABD75678BC8AC38C9E2 + 713D0E466D846A783F4E86DDEFC8BFD3 + 84A3EE0BF19E2B36FF89FEC07C01A761 + ECAAF2C7B7412B87A7732C9C164836F8 isa PBXGroup + name + Serialization sourceTree <group> - 7DB3BF7529485C2C2A5FCEF174EA6C70 + 854BC4449D8CAD0F2799B021D1914C3B + fileRef + A15DB0E110319ABE451544E637953ED3 isa - PBXTargetDependency + PBXBuildFile + + 855F190A3AB2BFDB8F67F2FD637153D6 + + baseConfigurationReference + E9BADEC7E474ADE375184CB25246C401 + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/ReactiveCocoa/ReactiveCocoa-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration name - JSPatch - target - FD1D53461DE538B7C8DFE0B76D857587 - targetProxy - 262813BD98A538C26EB573D0E6847E90 + Debug - 7E202116CC80048D57115A2A111CA5F4 + 85722D51A84ABD953A66C3E8115BF28E includeInIndex 1 @@ -6141,70 +5847,71 @@ lastKnownFileType sourcecode.c.objc name - RACStream.m + UIAlertView+AFNetworking.m path - ReactiveCocoa/RACStream.m + UIKit+AFNetworking/UIAlertView+AFNetworking.m sourceTree <group> - 7E8F683A3FAFE6F8AD716FDDF5F708CD + 859BD9C09F91D1B505846B7FDE8323BA includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACSequence.h + RACSubscriber.m path - ReactiveCocoa/RACSequence.h + ReactiveCocoa/RACSubscriber.m sourceTree <group> - 7F85DFA0BA8E5DF5155BF3912A24B2A0 + 85AC21BC7BD345D84F489F7A52D39E44 - buildActionMask - 2147483647 - files - - E90FE89EDA2F001944637A7C456AF004 - A7B8ECCAD3285C571FFAE1F87156FBF2 - + fileRef + EB7CA93484A64DA41DA995CDCDAAFE51 isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 7FB0B74829A41DA214F155A35AF931CE + 85E0615CAA269DD2D96AD52457D06D77 - includeInIndex - 1 + fileRef + 8C7D8CEB0B69C10DB79CACF33AD1897C isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACGroupedSignal.m - path - ReactiveCocoa/RACGroupedSignal.m - sourceTree - <group> + PBXBuildFile - 7FCE6FB5C357AB999AE8A17881F859BE + 86089ED3EBD01B3EE5D9AE7BB8365562 + + fileRef + 721201CF6A2409961E43ECE1DDFC967D + isa + PBXBuildFile + + 861D072B1AC17B39839086655FC21DB9 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - RACSignalProvider.d + NSObject+RACDeallocating.h path - ReactiveCocoa/RACSignalProvider.d + ReactiveCocoa/NSObject+RACDeallocating.h sourceTree <group> - 7FF4459D624EA5DA86B210B6FE69A8EA + 865F109140A1EAAC154F6FBA05124DDE includeInIndex 1 @@ -6213,69 +5920,65 @@ lastKnownFileType sourcecode.c.objc name - NSObject+RACPropertySubscribing.m + CYLTabBar.m path - ReactiveCocoa/NSObject+RACPropertySubscribing.m + CYLTabBarController/CYLTabBar.m sourceTree <group> - 804199840A93FA99DF0A79917ACFB1E5 + 86645448CC1E9477B8386BF0757F0896 - children - - 6265DE8669B72124D597C877F521FA7B - A265F50F2D64AC07AE11598EED4A181B - 60BCD0BF9F9B39893E55466EBC20A273 - + fileRef + 4B95E10EB54BF9480A8CB857F0170925 isa - PBXGroup - name - Support Files - path - ../Target Support Files/Masonry - sourceTree - <group> + PBXBuildFile - 80D702D144296236010345C7FF6C942F + 875DF12724A57083BDF2E8843FB9DCAA - includeInIndex - 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + wrapper.framework name - RACBehaviorSubject.h + UMMobClick.framework path - ReactiveCocoa/RACBehaviorSubject.h + umsdk_IOS_analyics_no-idfa_v4.1.1/UMMobClick.framework sourceTree <group> - 81403CAF6C4C1D3DC8B199289C3A6F59 + 876C2EF5FE318346CDCB4BFE25A9D5B2 fileRef - BC4AED5F728CE8A8F7E6DC06C1A20DE0 + CAEE1C9E82CCA7640A2F796D31EFE435 isa PBXBuildFile - 81599471BAB0420D54E1ADF8507A5113 + 87F282AB3C2677BD2D143D5020431ED2 - fileRef - A265F50F2D64AC07AE11598EED4A181B + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + JSONModel.m + path + JSONModel/JSONModel/JSONModel.m + sourceTree + <group> - 819E6615CF458C4E29F4D422C9AA1B23 + 881947E477E1D144ED265DF7A998933B fileRef - 5B057523D44C0B53B6DC7CB2D150F7D9 + 272643F56613CA0D336AE3DBF19DC404 isa PBXBuildFile - 82FBF13B0E7469CDB0563DC89D54FC12 + 884241E994424B56FF62E5E4C0EB0192 fileRef - 3FA351C84EA2D69232792EFB51B72FA2 + 711BF74F0676B87A2838048351DE2206 isa PBXBuildFile settings @@ -6286,83 +5989,121 @@ - 8313FA831D7925C254EBFC2A8EA1AD88 + 8870896F8AE8D1DA8EB01CBED4AC1C58 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACChannel.m + NSEnumerator+RACSequenceAdditions.h path - ReactiveCocoa/RACChannel.m + ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h sourceTree <group> - 840210445DEB38A5E16BFBBC95DF7950 + 893924D6C1772D528CBCCBA6EF73ECEC - includeInIndex - 1 + children + + 1FFDC86E9668A2B725A5E14834BC864F + EF14456F85CB3D05B276E8FDC8A98826 + 5F0E8469FC02AC540B330E4A7119D5D0 + 8DEBE35687E8091A51BD515F195DF8EC + 22A9A674AB7DC5D2FF76B677B213DED1 + 85722D51A84ABD953A66C3E8115BF28E + F003CA8064D942B82B09DE63B338A506 + 7F5BCC339FDC6DAD6F47209EB375853A + 5D9FA175E7E5F50DDB22B36A5B885871 + B941BEB290F39685CD1920FE7E9EE280 + 58FB72A327F803DBCC27E14D362FDBEF + 05440307997E67C54848A5EC63BA113A + E9A8C6608F60B3951DDFC8B2903D0603 + 1890C07A8BA8839AC3686951BF277AEB + 4ECCA2FD461EFA3B022347720B7A0237 + A15DB0E110319ABE451544E637953ED3 + 0AC2D3A503587DF2175D90EDCB256B34 + C6975705934F58AFCAACB89DB3EB294E + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - SDWebImageDecoder.h - path - SDWebImage/SDWebImageDecoder.h + UIKit sourceTree <group> - 840426794A49EC536ABBD91C1E41D0A2 + 898AEA184EF58065EB8EFB5AEA26B508 + + buildConfigurationList + 935F27201A07CFC945D61074D3F2CB8E + buildPhases + + FF5EA1C804C15099106D18CA52C58431 + EB9A65CF8C6373F340063FFCBD007F43 + CA9A3CC7011661524DF55E8069E2D4CC + + buildRules + + dependencies + + isa + PBXNativeTarget + name + XAspect + productName + XAspect + productReference + A44A50D0E07C187E301FFE14CE4F76F5 + productType + com.apple.product-type.library.static + + 89A790115BD0BD08D94190C5C21ED4D9 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIWebView+AFNetworking.h + sourcecode.c.objc path - UIKit+AFNetworking/UIWebView+AFNetworking.h + ReactiveCocoa-dummy.m sourceTree <group> - 847915BA4276EF30B713250A574C78A9 + 8A34BD33A8B98A15CED4C2A6BC8D9C93 - fileRef - A31E6D34EBC17EA2B06D90BE541AC79A + containerPortal + D41D8CD98F00B204E9800998ECF8427E isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 32B858CF09199FB109685F306D190C38 + remoteInfo + SDWebImage - 84AEF8CADF8AF9473815C761E9976E30 + 8AA007B97AE5CC80ACC692D6E590CFFE - fileRef - 77BB46BF30AAC5AB432DA6C3A713CA77 + explicitFileType + archive.ar + includeInIndex + 0 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + name + libMasonry.a + path + libMasonry.a + sourceTree + BUILT_PRODUCTS_DIR - 84F10C258F259000E87C41346A59DF0F + 8BDC0C656DCAA4376CB051A92C444366 fileRef - 43AE592AB85786B82334A90B22D6F242 + 734A04097CA3CF6720EE747B9D5D62A1 isa PBXBuildFile settings @@ -6373,42 +6114,20 @@ - 8518D32C8FB5FBA25CB73B3A13996882 - - buildActionMask - 2147483647 - files - - A0BBC09F7B8BA5A4CA9282BF9F312E73 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 854BC4449D8CAD0F2799B021D1914C3B - - fileRef - 3D661D03876F28D3286AE89027F93039 - isa - PBXBuildFile - - 854DB078283F3726E7263A22AB81F1C7 + 8C7CDB026EEE224CDFF0F69F0B9AAFD4 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - NSURLConnection+RACSupport.m + text.xcconfig path - ReactiveCocoa/NSURLConnection+RACSupport.m + XAspect.xcconfig sourceTree <group> - 855BDEFE7590AD1A95E842D65C82F5DD + 8C7D8CEB0B69C10DB79CACF33AD1897C includeInIndex 1 @@ -6417,304 +6136,93 @@ lastKnownFileType sourcecode.c.objc name - NSUserDefaults+RACSupport.m + UITextView+RACSignalSupport.m path - ReactiveCocoa/NSUserDefaults+RACSupport.m + ReactiveCocoa/UITextView+RACSignalSupport.m sourceTree <group> - 85AC21BC7BD345D84F489F7A52D39E44 + 8CCEC11DC188344B9433D786020A2620 fileRef - 62F30D9AF07C2D503845301942FA9F9C + 3B705B6A81E85F2054BA5735E280879E isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 85D2F186A70780E097FE9B4938FEA711 + 8D3D4280DFED7FCA6879718BE507C87E - includeInIndex - 1 + children + + 90D71BA451056A0F490DB6F75A35465E + E798802252FBC085207B7EF5246FD5D4 + 0BD06C4DDA7B80C1742B09DDCF556762 + 375AE8DDF76E5AEE2565EDAB8B8FC134 + F51EE27ECFD016DA35FD0B8868EC10B8 + 27AE61FBDA1BAB9F55981834BF3927CD + 4A48DB851E5BD64428601368F0296D83 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - SDWebImageOperation.h - path - SDWebImage/SDWebImageOperation.h + iOS sourceTree <group> - 85F392C1372F726906BC2B879CFF3FC9 + 8DEBE35687E8091A51BD515F195DF8EC includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - XAWeaveHandler.h + UIActivityIndicatorView+AFNetworking.m path - XAspect/Core/XAWeaveHandler.h - sourceTree - <group> - - 8678110FA27548FEDD8C52F43C4E14DE - - children - - 4E0F376ABE79D465A617B95C1475CD68 - 094A8CD944A7C5AC470D871229D258E0 - D128BA5BEE4A598E09EFC2652AE98D2C - B13C33D0C0315117BBAF70867F7E6C57 - - isa - PBXGroup - name - Macros - sourceTree - <group> - - 86A39E3CEB9ED0ED2B7151213732FC37 - - baseConfigurationReference - 4E762F23EC34ED4A6FF3312D84E33A40 - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MACH_O_TYPE - staticlib - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PODS_ROOT - $(SRCROOT) - PRODUCT_NAME - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - - isa - XCBuildConfiguration - name - Debug - - 876C2EF5FE318346CDCB4BFE25A9D5B2 - - fileRef - B7686B7D69B3E285F991DBF462667415 - isa - PBXBuildFile - - 89886EF7DB8AA45BB2742D78493C7522 - - children - - FAF1AB4051B3B9E753D50E9095D01044 - 69D3AFBA28E3FD4F7EA643CE40728F27 - 38F406988E1D01B50F475863B31EC199 - 9D63BAE391E0628AE26D7CC280015CB1 - 4509DF6334860FC19F8A57F6345BF60C - 243C8D42E812E7176AD1B8E1922F13F0 - 7C0B6DF4BE36BA1A66A246C00CF08D4F - 7A225968E7F6AB6C378FB62566296289 - D085A13B21A5418702B3BF087E39C0D4 - 6E824E86B7D5F406164E3D0C0999A900 - 594DDD0D23DB6F4D39E406074E9A1567 - 6FB3CFFEB44E4B8FCDDB27217F9D183D - 5E22AF3F9B92CAC73AD5CADB03042700 - 3AEA1559B669E7636EA759427C752604 - 7D54366BBEF328FFFE4BBC880BA20652 - 4BBDEB6CE73B6137C47501419AF2777F - C208817A5549140282E7150447CB076D - 0DE232DA7DF9A5C4EDF146731CF8296A - 53C1A4C9F7C64CD396285B361DF3D54F - 4A84D33C0DB3F8586464A2B82975BC35 - 4BFF8DADBD1721BF5461F26BCA2F1E87 - 120EFB3237A2D5D7455745B6E282CBEE - C30865260F1AA88E2CCC8258DD8F5C5F - 4C8663B3ABB37A09529A40E2BF230F84 - 21700C06D8FE72A135711E023B3EBC76 - 7FF4459D624EA5DA86B210B6FE69A8EA - C93F8E93788AD6B216F8D684EEDB9FA7 - 8E4095BD8D528280225FD16D85E8F091 - 266B4A862FADF8F742BE61443E0BFFE4 - AFA25CF4BA70362C1030B679756120BC - A7315DC7E23C786CCF26DCCDECE98C45 - 5E13D78FF94819C6E7505F3D8815AADA - 0D12B91CB78BF7CD99A66A8D0AF6BD9A - 9D467D19CBA8C5AAB22F37918099FBA6 - 1978942A4A36BCAE9997429376A5733C - D0115EFEA597359A1B8D1D0C51015C4C - 104AFF1DE2EE972BC6D3F0B9E74F0BAE - 5ECFF58439CAB75C3D9A52A722AD320B - 77BB46BF30AAC5AB432DA6C3A713CA77 - 854DB078283F3726E7263A22AB81F1C7 - 2829A21EC74C7D473B3F7D03296937B0 - 855BDEFE7590AD1A95E842D65C82F5DD - AEB9E43201C4A3C8CF078B10B1B2DC7E - 6DA0DC0C3DFC0404452E564B270EFFB6 - 80D702D144296236010345C7FF6C942F - B8BB79DE32405EE2DC4BEA14B1FA242F - 23379D081E9ABB25B5C2841C3732BE3C - 411145FA9BE020CC0E000A036879ABB6 - CD843B00B812E8A0F72FE1FE9734BA27 - 8313FA831D7925C254EBFC2A8EA1AD88 - 9B7D576C1C15271780A65921FD3B351D - 16A3E780C0937600C7C09D0DB3CCBD34 - CE01489CD5CF601457B6D2C5D1B00210 - 55D160550DEE0C805734D9A79F8CECE6 - 1E3B8678BA98318DA3BDF11BBB8016C6 - 4E0FFAB1DBFDD2724BA8FA304BD72F01 - 5B057523D44C0B53B6DC7CB2D150F7D9 - E7EDDB3648C282ABFA2F062CAD66BB26 - 8C598575EE88748ED3B64D6A1BE8EDA8 - CD1044A204A17CE5F93A1D622654107A - A40E3359EADB8FB3828D3E19487C9952 - ED2480D499308776B8E3932253E7C46A - 5D251373B0F6F042640A5DFFE6594BF9 - E0C332A92E8CD15A40F2CEA81ADEA5B3 - 510325018C1BA2426D1484BFAAFE04D5 - 1F81C7AFD5636DF6C51D2FAEC3D21BC3 - B8BEDDCAF0176CA17B822E7F3C17EB2E - F5B23A8DB947C061C43DFC4FFED383BE - D5ACC55E5D76B8F4D99C462E4E394EA0 - F3FB6F90335365FFF935B4FB91F5D94A - 659B6927C788554CB763D95DD9F6DB5F - 4CC249A3418D897E66F56183AFCA84E5 - DE2CF928F20C327DA4A335EB22BB2AB1 - A1624D65F362705800EAF879629A1641 - A31E6D34EBC17EA2B06D90BE541AC79A - EAC969C6C60F8BD2BF2FD30609AA034D - 166AF8E27F5F2151A8AF1B759147B106 - 5DAFD622EC60936915F8F6D3985D6D06 - 7FB0B74829A41DA214F155A35AF931CE - 0EDC6716609A31FDD62A5349137FE307 - FD7DDBDD0E5A72786C1A87D606D8334C - 982EC4210D0E11D4C222FE2EC9A04E3D - EDFDFB257B49EF3F125E7706606F1B76 - D6B6C0BAB71F40084CD19007816F5135 - 31BCD314D8CE512714D93706A0A3B3DC - 1361CFA334DAB2F4511DFB1EBE9E5073 - CF6EFFA22C3751AB7F978D1903CA7BA8 - 563CABE8034F56611588FFFEA8122352 - D5A3134C9C8FF8D3E667992F788A7878 - CA00DB45EEB83A2CC6ED12AD89126EB1 - 14919C8D2FFE698835E4311BDCF86454 - D7D7B6198C38BE29584CFDA470A53399 - D95489F071B1051AF42780E607BD9B29 - DB2950F7F98988B053479C722B92A536 - 9BBDDF71F74B6BF4ABC9FEE4368B7CE5 - E947279877DF8A82CF3C684C9A8D3F6D - C60FDD97329B3F41A91733E7D1369A56 - 1427ED6340412B09D2BF2A59633C7302 - FA4AF3EAA8C3A19405FB7B9B433420E9 - F99004E5FF8745BDDB86E40F96AA5831 - 43BC8AFBABA6F0B2F0335334231D6F8E - 27B195A66BA2975721D58D7D73A4B764 - E5AE29ED4BEFE8DAB244B278DDBC06CE - 249A50DF25C576887DE7B90A3C06C0C5 - C9AE24C328D4A75275E3BD6C16C5A145 - 2882B29F5EBCE5F56C70A9BA592A80C8 - 227AC65587EFD083286F0C1E386B251C - B2865411AB79B1B3B7A2750532B924F3 - 7E8F683A3FAFE6F8AD716FDDF5F708CD - 49A20E37AD655BA2A4C0AEB7A7ACC747 - D4A8C167B632453BE354070C0F51ABD6 - 283E771991494A2B96E2BBCE637D6390 - DA0FB964F98DBBB51E94B0A6C3A0AC9A - A4DD75475D1D94904BE126F618F34E42 - 65499AC1710351B8E561AF69182FB0AE - 66EA37CF5A484C13AC109BA581C4D752 - 7FCE6FB5C357AB999AE8A17881F859BE - A6700863B906BF25509A8103819B98F3 - FC7FF831376FA8C9100E2C08023F477F - 1A5BE933196809B7B7E1AD67610EB412 - 7E202116CC80048D57115A2A111CA5F4 - B544D885BF130D8DD726765A263C4C19 - 2101678EE1CAC9906F2C737F1FC9B939 - 978BA4AFEBBADAD1F2ED5B6FC1297A6F - E91C9516CFEAF53AA8B50A9B9F11B275 - 9B7D7D173492E46E3FFB0460E54F6116 - B1C3144078FB130BB89DA3467285B625 - 1808C2B2A33B77042F352C363AC97BB4 - 1AD05E1CA714ECE615C8565333127E0D - 6948B9FC8DCDBE2B7AD843CB44B933E6 - BF169F0D65145A9B7AC7E446C4A55706 - A7A73F10361D20AC0896BA56E538FF5B - B42262E7778E726F825B5C16311E64E2 - 5FF2061AAC0FBD245CF04573AA4ADE56 - 9581E07B4327B07E261039619772514D - 2C397EF1FF5C3F34C812BCEFF39C429A - D9D358458CED65BE821E001F12A5BAAF - C6AFC54A7B6BE1A53FCF12B72CFD340A - CBB902BE9B2970A11479B4A17CF73B1C - 73D9BAC9052E44B48D7E6F4F9BD4E1DF - 2B675FE7BE27BF4A88FACDEC5C041CCC - 34E3C23774C3F071C360A95E781D5C0A - EBA69E8FAA01CBD798D4F6C67B0DD981 - AB519031BC04B2F8D8CD7E010418BF54 - 239FB2B346B31E34E553402848248712 - 612D1A2852BEA130961DAD1917197A64 - 0CD7F87AEA1C91DBDA95DE57AC9F7579 - FB7ED69A0A9F3DBA39CF3BA76B660EFF - - isa - PBXGroup - name - Core + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m sourceTree <group> - 899DD76852C172803602DDE6ADA838CF + 8E520FFE0CB5746AFDD09A455008BE16 fileRef - 9B4079315421A87E5A1C764DEDA7C89B + 1AECA3763F9718961E999D6D0D727222 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 89C97B06CF69EC49E69271C0C029419A + 8EFCDE6DA263A175B2A6E96E943D1416 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - JSONModelError.m + NSNotificationCenter+RACSupport.h path - JSONModel/JSONModel/JSONModelError.m + ReactiveCocoa/NSNotificationCenter+RACSupport.h sourceTree <group> - 8A794E0ED3682DF3F2D84BB3350A297B + 8F1189C505527A9BA74E0CFFCD5092C6 fileRef - B8BB79DE32405EE2DC4BEA14B1FA242F + 7312D5806639AF8561995B0A9F0C6672 isa PBXBuildFile - 8A87C09FB34F52F2554A242ADA7DBEB2 + 8F11ABA0C553B18981097015226E5748 fileRef - BE05843E2D30494B31AE9076742B8F06 + AF5656A5796440E7FFA6019C05D4FBF3 isa PBXBuildFile settings @@ -6725,7 +6233,7 @@ - 8AC588373A6FBA25589D84FC17D92C55 + 8F52FED3FD52EFFAE58DE8B144084FD3 includeInIndex 1 @@ -6734,35 +6242,20 @@ lastKnownFileType sourcecode.c.h name - NSArray+JSONModel.h + AFHTTPRequestOperation.h path - JSONModel/JSONModelCategories/NSArray+JSONModel.h + AFNetworking/AFHTTPRequestOperation.h sourceTree <group> - 8B3DCAF43D573EA1DAB1CA36231FB5EF + 8FB794921D2D71380A2A0C0935D26E39 fileRef - 0CD7F87AEA1C91DBDA95DE57AC9F7579 + 859BD9C09F91D1B505846B7FDE8323BA isa PBXBuildFile - 8B78401B8A1F08A7098C7E892E45C5BA - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - AFHTTPRequestOperationManager.m - path - AFNetworking/AFHTTPRequestOperationManager.m - sourceTree - <group> - - 8C598575EE88748ED3B64D6A1BE8EDA8 + 8FEA57F71D7521DFC5241AA6617499DE includeInIndex 1 @@ -6771,16 +6264,16 @@ lastKnownFileType sourcecode.c.objc name - RACDisposable.m + RACSubscriptionScheduler.m path - ReactiveCocoa/RACDisposable.m + ReactiveCocoa/RACSubscriptionScheduler.m sourceTree <group> - 8C9AC8B980C08C278B8F12A9F87FC3BA + 903A0E1F82A29D285902CBB5A0828BE9 fileRef - FDF2348A859024AC05590AEE05594567 + 5D9FA175E7E5F50DDB22B36A5B885871 isa PBXBuildFile settings @@ -6791,26 +6284,20 @@ - 8D3D4280DFED7FCA6879718BE507C87E + 90D71BA451056A0F490DB6F75A35465E - children - - 90D71BA451056A0F490DB6F75A35465E - E798802252FBC085207B7EF5246FD5D4 - 0BD06C4DDA7B80C1742B09DDCF556762 - 375AE8DDF76E5AEE2565EDAB8B8FC134 - F51EE27ECFD016DA35FD0B8868EC10B8 - 27AE61FBDA1BAB9F55981834BF3927CD - 4A48DB851E5BD64428601368F0296D83 - isa - PBXGroup + PBXFileReference + lastKnownFileType + wrapper.framework name - iOS + CoreGraphics.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/CoreGraphics.framework sourceTree - <group> + DEVELOPER_DIR - 8D702D0F1FBE57C1D1C6980E22C66EBE + 911C771FEAEFFD1AF5B2C468EA72DABB includeInIndex 1 @@ -6819,24 +6306,41 @@ lastKnownFileType sourcecode.c.h name - JSONModelLib.h + SDWebImageCompat.h path - JSONModel/JSONModelLib.h + SDWebImage/SDWebImageCompat.h sourceTree <group> - 8DE86437BD942A6415E7DFBCD3C2C526 + 9205037BA8C22574B33FC96C5EA829A3 + fileRef + 206C04450ADF97A54B938ADB00EBBF1F isa - PBXTargetDependency - name - CYLTabBarController - target - 0C1D89EAE68EF4D4ABEDB611EC44AAB0 - targetProxy - 29184003153D7874E68992FCB4C8EDDB + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 92A346DDE83BD2A9B2D1F3A51C5CC7BE + + fileRef + F08553B1A91E401FF6877A9A61481C12 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 8E4095BD8D528280225FD16D85E8F091 + 92D2A49D15CEE5164F48E38340AD32AA includeInIndex 1 @@ -6845,16 +6349,32 @@ lastKnownFileType sourcecode.c.objc name - NSObject+RACSelectorSignal.m + AFNetworkReachabilityManager.m path - ReactiveCocoa/NSObject+RACSelectorSignal.m + AFNetworking/AFNetworkReachabilityManager.m sourceTree <group> - 8E520FFE0CB5746AFDD09A455008BE16 + 92F113ED05E1D254FF29489901ABEDA8 + + children + + 4C6474D7F773FABA0133ABC73E98E0BF + C9C6FB489BC99A38D3135EAB9F90F8F0 + 4810F189AFC3DCD40A14FBCEF9833BAD + F08553B1A91E401FF6877A9A61481C12 + + isa + PBXGroup + name + Macros + sourceTree + <group> + + 92FDBD13A250744C170BC9A901A86E37 fileRef - E7B66D448FF3C7D3F5B049918A9BED7B + 8EFCDE6DA263A175B2A6E96E943D1416 isa PBXBuildFile settings @@ -6865,55 +6385,39 @@ - 8E75EAD764BF726B7A61971ED67507DD + 92FEFBB1C20F0AAD1BC09DB2CC06F396 includeInIndex 1 isa PBXFileReference lastKnownFileType - archive.ar + sourcecode.c.objc + name + RACCommand.m path - libGeTuiSdk-1.5.0.a + ReactiveCocoa/RACCommand.m sourceTree <group> - 8F103981A804B41263FEBD30B4CD2CA5 + 935F27201A07CFC945D61074D3F2CB8E - baseConfigurationReference - 98C98CDFB3F20F2925F6CD1F141BB14F - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MACH_O_TYPE - staticlib - MTL_ENABLE_DEBUG_INFO - NO - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PODS_ROOT - $(SRCROOT) - PRODUCT_NAME - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - - isa - XCBuildConfiguration - name + buildConfigurations + + 7EB894EBB317D982B7B92A918749CCF8 + 4728858CCB67CF8048116D7CBEA4484E + + defaultConfigurationIsVisible + 0 + defaultConfigurationName Release + isa + XCConfigurationList - 8F11ABA0C553B18981097015226E5748 + 93C1668F705927BFD1E9229C6A6BF521 fileRef - 8AC588373A6FBA25589D84FC17D92C55 + E0A47213FE70FB695C6C933410638AF3 isa PBXBuildFile settings @@ -6924,78 +6428,79 @@ - 8F6FC9245F1F8D05DC3F3F4059A79FBA - - children - - 5D5275EB18EFA5A701E1F459538C0A2A - C2047EA48BA7AC3B9DFC7F25A4F61244 - - isa - PBXGroup - name - Reachability - sourceTree - <group> - - 8FF4ACBA69C04C52C770DBB4AAA0F442 + 94DFBADA302CB79810621D9C521AC4C0 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIRefreshControl+AFNetworking.h + NSObject+RACSelectorSignal.m path - UIKit+AFNetworking/UIRefreshControl+AFNetworking.h + ReactiveCocoa/NSObject+RACSelectorSignal.m sourceTree <group> - 90225DC600376307F93B98526613466C + 94DFC7CF85D85A79751DD1716BDF8087 - includeInIndex - 1 + fileRef + EE0F99FB0D1509C0A7E03A68A8068CD7 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXBuildFile + settings + + COMPILER_FLAGS + -fno-objc-arc + + + 94E3EC661536CD989F7D7BA46681D369 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference name - UICollectionReusableView+RACSignalSupport.m + libJSONModel.a path - ReactiveCocoa/UICollectionReusableView+RACSignalSupport.m + libJSONModel.a sourceTree - <group> + BUILT_PRODUCTS_DIR - 903A0E1F82A29D285902CBB5A0828BE9 + 95425136DDE162827E8835D3A5B2A1D2 - fileRef - 3D3FBF048AAC09B00D8CE7E148CABAEC + explicitFileType + archive.ar + includeInIndex + 0 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + name + libAFNetworking.a + path + libAFNetworking.a + sourceTree + BUILT_PRODUCTS_DIR - 90D71BA451056A0F490DB6F75A35465E + 95B5A6B242676F67C65EFF220348ACAE + includeInIndex + 1 isa PBXFileReference lastKnownFileType - wrapper.framework + sourcecode.c.h name - CoreGraphics.framework + RACPassthroughSubscriber.h path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/CoreGraphics.framework + ReactiveCocoa/RACPassthroughSubscriber.h sourceTree - DEVELOPER_DIR + <group> - 91BBF694E9001C762E8DB9185ABE3ADB + 95CAFC402263DD52A7417D95B73E9729 includeInIndex 1 @@ -7004,44 +6509,35 @@ lastKnownFileType sourcecode.c.objc name - JSONModelArray.m + UIImageView+WebCache.m path - JSONModel/JSONModel/JSONModelArray.m + SDWebImage/UIImageView+WebCache.m sourceTree <group> - 9205037BA8C22574B33FC96C5EA829A3 + 95E74A7FAB761D5592681007955A376A fileRef - 5E89FB3E7EF1A2C158337CDA267C6DBE + 3D8613FB9057E6157DB1D60E10E98E08 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 9258D8E7B9E9A8A1744B0ED65722787D + 95FF7E5BE776C8B96D4D4E6F5999820C fileRef - D4A8C167B632453BE354070C0F51ABD6 + 023127DD998B06C63F956271B9999FB8 isa PBXBuildFile settings - ATTRIBUTES - - Public - + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - 927CCA43EF2C9947DD889F8B13323E49 + 963D3CE7C312D6A3C4A39F4726EDDC13 fileRef - E7EDDB3648C282ABFA2F062CAD66BB26 + 9721AAD85135FB9BDDBE80BA4D11BF97 isa PBXBuildFile settings @@ -7052,24 +6548,54 @@ - 929F930153EA56D0CF95872B3A4F857F + 9662B978A2BF20CC4D967B3E90515DFC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACEXTRuntimeExtensions.m + path + ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.m + sourceTree + <group> + + 96F8C5242F337D002F64184A01C4E651 fileRef - 35F21F926D9A165521BF874A38D9FDB6 + 9A61F1BB44876994F5F53372B82B11C3 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - 9350A4E3963BA5156450824AE0841CD8 + 97138795855F6D9F51924BE978A8BE80 + + fileRef + BC124DA3E0AD75608C3477374BEBC17C + isa + PBXBuildFile + + 9721AAD85135FB9BDDBE80BA4D11BF97 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UITableViewHeaderFooterView+RACSignalSupport.h + path + ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.h + sourceTree + <group> + + 9779286FFE4DABF539E1B6D24816136C fileRef - 30AA5F397CE54C4A547BA63A1D5E9DA6 + 598B77BA5B514764BBDF71F12E23CA1C isa PBXBuildFile settings @@ -7078,10 +6604,32 @@ -DOS_OBJECT_USE_OBJC=0 - 935C4A7A0B5836543F89569B896C92B8 + 97B266E91D2102E8906C8A6AA8F69F83 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSData+ImageContentType.h + path + SDWebImage/NSData+ImageContentType.h + sourceTree + <group> + + 9838593D1811293CE2C175BCF4CD9448 + + fileRef + C932015425BD500D4A6083DB0623EC64 + isa + PBXBuildFile + + 984E76EAB6CAE9D02BA3FCBC602C6164 fileRef - AB519031BC04B2F8D8CD7E010418BF54 + DBDDA6567FA3773567DBA87ADDC396BB isa PBXBuildFile settings @@ -7092,10 +6640,10 @@ - 94303F2C3BD5644DE648E1B0658E5A47 + 9871A570E364A1B6F0B48565A892F723 fileRef - 4F64C8EDFA4698BD86F2A11C62FF9032 + 0190945F9BF1EAB8CD7279A26AC7BCAD isa PBXBuildFile settings @@ -7106,22 +6654,20 @@ - 94A83BD33AFCDC59F41573552F1D6EB7 + 98C98CDFB3F20F2925F6CD1F141BB14F - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference - name - libPods.a + lastKnownFileType + text.xcconfig path - libPods.a + Pods.release.xcconfig sourceTree - BUILT_PRODUCTS_DIR + <group> - 94BF98E095A6D64AA692166F71B54F78 + 993BAA0FDA7062280D3005B655BC8388 includeInIndex 1 @@ -7130,13 +6676,13 @@ lastKnownFileType sourcecode.c.h name - NSData+ImageContentType.h + NSString+RACSupport.h path - SDWebImage/NSData+ImageContentType.h + ReactiveCocoa/NSString+RACSupport.h sourceTree <group> - 9581E07B4327B07E261039619772514D + 997C4C3399F300AD66818E3A4C6D84EB includeInIndex 1 @@ -7145,27 +6691,13 @@ lastKnownFileType sourcecode.c.objc name - RACTargetQueueScheduler.m + RACKVOProxy.m path - ReactiveCocoa/RACTargetQueueScheduler.m + ReactiveCocoa/RACKVOProxy.m sourceTree <group> - 95B78BFC3D921957F8DD6A2CE3E0B499 - - fileRef - C9E88E1C6561A96D7C24E59993CA1296 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 978BA4AFEBBADAD1F2ED5B6FC1297A6F + 99B18091467DC619CAAB11E060AC1121 includeInIndex 1 @@ -7174,31 +6706,30 @@ lastKnownFileType sourcecode.c.objc name - RACStringSequence.m + NSData+RACSupport.m path - ReactiveCocoa/RACStringSequence.m + ReactiveCocoa/NSData+RACSupport.m sourceTree <group> - 982EC4210D0E11D4C222FE2EC9A04E3D + 99D84384CAC2C15621AB1A9FB052906A - includeInIndex - 1 + fileRef + 8186776A47C9D6ED6108AB91550A0989 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACIndexSetSequence.h - path - ReactiveCocoa/RACIndexSetSequence.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - 98B2014378B7D9E855152692C8D12446 + 99D8C610BC84BE231C5D3D280F3B12AF fileRef - 612D1A2852BEA130961DAD1917197A64 + FA2CEE153AF0EBF4A4AB72D050A175F2 isa PBXBuildFile settings @@ -7209,20 +6740,36 @@ - 98C98CDFB3F20F2925F6CD1F141BB14F + 99E82D6DC032555656E37AF2367B20D3 + + fileRef + 7F5BCC339FDC6DAD6F47209EB375853A + isa + PBXBuildFile + + 9A04E971065AF4281E43947994A53D07 + + fileRef + C6975705934F58AFCAACB89DB3EB294E + isa + PBXBuildFile + + 9A61F1BB44876994F5F53372B82B11C3 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + RACBlockTrampoline.m path - Pods.release.xcconfig + ReactiveCocoa/RACBlockTrampoline.m sourceTree <group> - 99B5A311B3C0954BB5C558F90B626D6F + 9A6734BD63244CEB683F00F0CBA3B221 includeInIndex 1 @@ -7231,44 +6778,23 @@ lastKnownFileType sourcecode.c.h name - MASCompositeConstraint.h + NSArray+MASShorthandAdditions.h path - Masonry/MASCompositeConstraint.h + Masonry/NSArray+MASShorthandAdditions.h sourceTree <group> - 99D8C610BC84BE231C5D3D280F3B12AF - - fileRef - 99B5A311B3C0954BB5C558F90B626D6F - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - 99E82D6DC032555656E37AF2367B20D3 - - fileRef - E0291E4ED72C93C2ABD2C1EA896D6261 - isa - PBXBuildFile - - 9A04E971065AF4281E43947994A53D07 + 9A6AE1EF2E94AEB6912BE845583E7D57 fileRef - B69F9892BE1074EA541607EE65E96594 + 4A48DB851E5BD64428601368F0296D83 isa PBXBuildFile - 9A14AEF21660FE99D59C768B7CE7D3F1 + 9A796393B3FAEF29DA709A3BCFC21BE6 fileRef - 7C0B6DF4BE36BA1A66A246C00CF08D4F + A351C49D0B7B5368D708075E1B790F7B isa PBXBuildFile settings @@ -7279,13 +6805,6 @@ - 9A6AE1EF2E94AEB6912BE845583E7D57 - - fileRef - 4A48DB851E5BD64428601368F0296D83 - isa - PBXBuildFile - 9A80637BC4F7665B84839294439F16ED buildActionMask @@ -7309,7 +6828,7 @@ runOnlyForDeploymentPostprocessing 0 - 9B4079315421A87E5A1C764DEDA7C89B + 9A84EA35F2D3E77AC5001D80E576C6B4 includeInIndex 1 @@ -7318,20 +6837,38 @@ lastKnownFileType sourcecode.c.objc name - UIRefreshControl+RACCommandSupport.m + RACSerialDisposable.m path - ReactiveCocoa/UIRefreshControl+RACCommandSupport.m + ReactiveCocoa/RACSerialDisposable.m sourceTree <group> - 9B47A1441B897F71505D8BE670B0940B + 9A935B6D3AACE527D4DF682DB3C53BDD - fileRef - F66268E5D5382C35C98197F3C4D51B98 + buildConfigurationList + 1F81C7BBC0A4A558A5B67954F8FED019 + buildPhases + + E713967A6600947084C4D66D3375C696 + 2749A6494ED1B95F537D65BD004F92FE + 4E679CCF235A43902AFE269284BA7535 + + buildRules + + dependencies + isa - PBXBuildFile + PBXNativeTarget + name + ReactiveCocoa + productName + ReactiveCocoa + productReference + 29E728C49794360ABDC8BBF02D053E99 + productType + com.apple.product-type.library.static - 9B7D576C1C15271780A65921FD3B351D + 9AB97AF7B67492F6587E29623D14D2A0 includeInIndex 1 @@ -7340,13 +6877,61 @@ lastKnownFileType sourcecode.c.h name - RACCommand.h + NSData+RACSupport.h path - ReactiveCocoa/RACCommand.h + ReactiveCocoa/NSData+RACSupport.h + sourceTree + <group> + + 9B47A1441B897F71505D8BE670B0940B + + fileRef + 85722D51A84ABD953A66C3E8115BF28E + isa + PBXBuildFile + + 9B5DB9EEDE586E53C458D04475A7E704 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + AFNetworking.xcconfig sourceTree <group> - 9B7D7D173492E46E3FFB0460E54F6116 + 9B67E3B325A1A44DCF58EFE8AE9CB0B1 + + fileRef + 97B266E91D2102E8906C8A6AA8F69F83 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 9B99D49C0FD5F09E0F12961BDB4DAE91 + + fileRef + B4C7F254D7D19D970B5743C513732CC4 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 9BBA8775E91B0040A8C8A4656D2129FA includeInIndex 1 @@ -7355,13 +6940,13 @@ lastKnownFileType sourcecode.c.objc name - RACSubject.m + RACCompoundDisposable.m path - ReactiveCocoa/RACSubject.m + ReactiveCocoa/RACCompoundDisposable.m sourceTree <group> - 9BA172233D50DE6F6C742F0EEB20DB5E + 9BEC7C577BD7C1695F7C1C594202AF22 includeInIndex 1 @@ -7370,13 +6955,13 @@ lastKnownFileType sourcecode.c.objc name - UIView+WebCacheOperation.m + NSNotificationCenter+RACSupport.m path - SDWebImage/UIView+WebCacheOperation.m + ReactiveCocoa/NSNotificationCenter+RACSupport.m sourceTree <group> - 9BBDDF71F74B6BF4ABC9FEE4368B7CE5 + 9C054D2305C720C0B99D1D5A7727F489 includeInIndex 1 @@ -7385,13 +6970,13 @@ lastKnownFileType sourcecode.c.objc name - RACPassthroughSubscriber.m + NSString+RACSequenceAdditions.m path - ReactiveCocoa/RACPassthroughSubscriber.m + ReactiveCocoa/NSString+RACSequenceAdditions.m sourceTree <group> - 9BCEB299DB4F34611D33AD9873136C33 + 9C1253E47A1EA2670E5136F8216924DB includeInIndex 1 @@ -7400,73 +6985,57 @@ lastKnownFileType sourcecode.c.h name - UIImageView+HighlightedWebCache.h + SDWebImageDownloader.h path - SDWebImage/UIImageView+HighlightedWebCache.h + SDWebImage/SDWebImageDownloader.h sourceTree <group> - 9C0B98B295B045EDBB4C4C830D101C6E + 9C71D296FA604ABD75678BC8AC38C9E2 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - AFURLRequestSerialization.m + AFURLRequestSerialization.h path - AFNetworking/AFURLRequestSerialization.m + AFNetworking/AFURLRequestSerialization.h sourceTree <group> - 9C12E5B34A71CDCAA71A5D3DFA7DC595 + 9CFBD27D336D1336CEF4F9C6F04A962F - containerPortal - D41D8CD98F00B204E9800998ECF8427E + fileRef + BAF07965D9BAAAA1592777CA8FC127D8 isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - B995F6C491CD4491EFFB38B22D432FA4 - remoteInfo - XAspect + PBXBuildFile - 9C7C6A30BC4D9CB07976524036ADC07F + 9CFE728FBC713C74EBC629AD8EECF6C7 - baseConfigurationReference - 51DEAD099F5FEE7BE4DBD4CB7DDF0A0A - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/XAspect/XAspect-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - NO - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - + children + + 4E743A1D8C07C485D1E25B2E8F69503B + 2CF9FBC4489F08B20D878E03F666B249 + 079683953F8BCC99F20AB057F852CB84 + isa - XCBuildConfiguration + PBXGroup name - Release + Support Files + path + ../Target Support Files/Masonry + sourceTree + <group> + + 9D41E9863C4F1DF2F07A5C5822C7D95A + + fileRef + 546043D08C492E3C07CDE69F0C33381C + isa + PBXBuildFile 9D44B0AD2D97CB2AA74B614C1E92EDCF @@ -7498,7 +7067,14 @@ runOnlyForDeploymentPostprocessing 0 - 9D467D19CBA8C5AAB22F37918099FBA6 + 9D5C4AB2353A5952E3441F5A73C640C4 + + fileRef + 7A4C14BBA7CAC02D27A295C3CA226CF1 + isa + PBXBuildFile + + 9D89814A5FE0AD9B4433D95DD47A1C52 includeInIndex 1 @@ -7507,13 +7083,27 @@ lastKnownFileType sourcecode.c.objc name - NSString+RACKeyPathUtilities.m + NSObject+RACPropertySubscribing.m path - ReactiveCocoa/NSString+RACKeyPathUtilities.m + ReactiveCocoa/NSObject+RACPropertySubscribing.m sourceTree <group> - 9D63BAE391E0628AE26D7CC280015CB1 + 9DC84A01BBF97F58CF4DDF9AC5548B25 + + fileRef + 02B2F23E74F8BEB386D7563F64C1F808 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + 9E05D3F78600BEB3A30E851F7FA55B3F includeInIndex 1 @@ -7522,13 +7112,13 @@ lastKnownFileType sourcecode.c.objc name - NSData+RACSupport.m + RACUnarySequence.m path - ReactiveCocoa/NSData+RACSupport.m + ReactiveCocoa/RACUnarySequence.m sourceTree <group> - 9D80E32A2AA1B3D7EF258957919E809A + 9E55B4F4BC7D691EF9EC345F4D64C441 includeInIndex 1 @@ -7537,58 +7127,38 @@ lastKnownFileType sourcecode.c.h name - MASLayoutConstraint.h + RACSignalSequence.h path - Masonry/MASLayoutConstraint.h + ReactiveCocoa/RACSignalSequence.h sourceTree <group> - 9E83A243500C744DC9C3F465FEC14AA8 + 9ED632B427AC3FAECB45343B6F534A01 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIImageView+HighlightedWebCache.m + NSObject+RACDescription.h path - SDWebImage/UIImageView+HighlightedWebCache.m + ReactiveCocoa/NSObject+RACDescription.h sourceTree <group> - 9FB21C3EC3C8703D0EE5F7C3CAD95374 + 9EDAD693C9217384E635AF76CF37F923 fileRef - B1992E4E26237C5C7D9355F0F0839C3B + 1FC894FF194E4D3E40ADFB0D919A52B9 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 9FF7B15B9B58DC7A83404A0D9C5C54B0 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - AFURLSessionManager.m - path - AFNetworking/AFURLSessionManager.m - sourceTree - <group> - A0282FCE5A0EA8EC2131588765DF88E9 + 9F350145B972381A96FD71D13547412B fileRef - 6948B9FC8DCDBE2B7AD843CB44B933E6 + 911C771FEAEFFD1AF5B2C468EA72DABB isa PBXBuildFile settings @@ -7599,66 +7169,32 @@ - A045C84F164672568EB40F90886FB6C8 - - children - - 89886EF7DB8AA45BB2742D78493C7522 - 00061A7C9B119447394C1B790DC0125A - 4FA27C677A68BCAFA3A5A98CC397CAD6 - 5F03075BBDCFBD20AB6923384CCF0858 - - isa - PBXGroup - name - ReactiveCocoa - path - ReactiveCocoa - sourceTree - <group> - - A0503615C92C99E334D18915FE4EE893 + 9FF01B0CCE7632491EA40CE567821790 fileRef - 27315171369949FC91F6841DC8AE5C11 + 52B172DACAD83B36862AE4FD13B2EA9B isa PBXBuildFile settings - ATTRIBUTES - - Public - + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - A0A220208A7665AAB0C35C49DA236BE6 + A063391B665F1B4ABA81E0820EFC0AB2 - buildActionMask - 2147483647 - files + children - 8C9AC8B980C08C278B8F12A9F87FC3BA - 43AB2DECC33D773B0C8F2F91C8A522EE - 4FF68D9DB123474D54A03C0997B32F5D - F3A88A208A89BB9D8FCE5A337ABFBC28 - 2DE94C0E5BDE173486D89658787EC099 - CC3CDEA4B94B6903CE0614F0A44F85EF - 578D1C106A818A784DB887C5D5125FD6 - 47F793B36896F16B8BEBBD8C8E8F60AD + 875DF12724A57083BDF2E8843FB9DCAA isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - A0BBC09F7B8BA5A4CA9282BF9F312E73 - - fileRef - E798802252FBC085207B7EF5246FD5D4 - isa - PBXBuildFile + PBXGroup + name + Frameworks + sourceTree + <group> - A1624D65F362705800EAF879629A1641 + A0A931A92557100FC57CB363E078049A includeInIndex 1 @@ -7667,13 +7203,13 @@ lastKnownFileType sourcecode.c.h name - RACEXTKeyPathCoding.h + UICollectionReusableView+RACSignalSupport.h path - ReactiveCocoa/extobjc/RACEXTKeyPathCoding.h + ReactiveCocoa/UICollectionReusableView+RACSignalSupport.h sourceTree <group> - A19586CD7DCB89EA5B3DDA7483F0A718 + A15DB0E110319ABE451544E637953ED3 includeInIndex 1 @@ -7682,42 +7218,44 @@ lastKnownFileType sourcecode.c.objc name - UISlider+RACSignalSupport.m + UIRefreshControl+AFNetworking.m path - ReactiveCocoa/UISlider+RACSignalSupport.m + UIKit+AFNetworking/UIRefreshControl+AFNetworking.m sourceTree <group> - A1A36D34413696BE466E2CA0AFF194DA + A18A8E90AA1D35FF9E94ADA176B10A5E includeInIndex 1 isa PBXFileReference lastKnownFileType - text.script.sh + sourcecode.c.objc + name + RACReturnSignal.m path - Pods-resources.sh + ReactiveCocoa/RACReturnSignal.m sourceTree <group> - A265F50F2D64AC07AE11598EED4A181B + A1A36D34413696BE466E2CA0AFF194DA includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + text.script.sh path - Masonry-dummy.m + Pods-resources.sh sourceTree <group> A28588D1CCB5253CF80509F30A1AF1A5 fileRef - C2020C1EB46409061C8BB7DF0E703EC9 + 5F0E8469FC02AC540B330E4A7119D5D0 isa PBXBuildFile settings @@ -7728,14 +7266,21 @@ - A28E2581565AA2BD5592D8B1880FFBBA + A2C7C6D416B7AF12F7D61DB2EA26F8A0 fileRef - F80F668A8F6E7D9DF4DDD32E7E99A09E + 342B293E2F15B3DF835525E4183DAA8F isa PBXBuildFile + settings + + ATTRIBUTES + + Private + + - A31E6D34EBC17EA2B06D90BE541AC79A + A351C49D0B7B5368D708075E1B790F7B includeInIndex 1 @@ -7744,27 +7289,28 @@ lastKnownFileType sourcecode.c.h name - RACEXTRuntimeExtensions.h + RACReturnSignal.h path - ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.h + ReactiveCocoa/RACReturnSignal.h sourceTree <group> - A35FCBFEC2F7C54730C1499320CBFDD7 + A3BB933DADD14CB8DBD473EC6BF17EDC - fileRef - 73D9BAC9052E44B48D7E6F4F9BD4E1DF + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACEmptySignal.h + path + ReactiveCocoa/RACEmptySignal.h + sourceTree + <group> - A40E3359EADB8FB3828D3E19487C9952 + A3D2C29F2D61DF4AF12B21F7956B3A8F includeInIndex 1 @@ -7773,108 +7319,75 @@ lastKnownFileType sourcecode.c.objc name - RACDynamicSequence.m + NSArray+MASAdditions.m path - ReactiveCocoa/RACDynamicSequence.m + Masonry/NSArray+MASAdditions.m sourceTree <group> - A4261CED5E5A7226F5FA65BCF8044BDE + A3F71E90C69029CDD15B2D2578518B92 - fileRef - 1E3B8678BA98318DA3BDF11BBB8016C6 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + View+MASShorthandAdditions.h + path + Masonry/View+MASShorthandAdditions.h + sourceTree + <group> - A44AF130E4C5313CD193D9BF68853026 + A44A50D0E07C187E301FFE14CE4F76F5 - fileRef - C954A8FAAF2F7A10B18F3F926D51557A + explicitFileType + archive.ar + includeInIndex + 0 isa - PBXBuildFile + PBXFileReference + name + libXAspect.a + path + libXAspect.a + sourceTree + BUILT_PRODUCTS_DIR - A47603AB3B3B2993FD5BADBB2590CA1C + A44AF130E4C5313CD193D9BF68853026 fileRef - 1F81C7AFD5636DF6C51D2FAEC3D21BC3 + 70725A3D27E3186C99D5E59262792240 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - A49AA631EEBC0BD569839ABE28E0EB23 + A4763E22F94FAA131C037ED0B6A1C59B fileRef - AE1818531080A2759F2C77A7CE0C1AC2 + CED3AC0CA2AA60DFE9D320BCDEC5B657 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - A4DD75475D1D94904BE126F618F34E42 + A4BB0C7EADFAD6A1DD1BE9EC3DF0C0A3 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACSignal.m + RACEXTScope.h path - ReactiveCocoa/RACSignal.m + ReactiveCocoa/extobjc/RACEXTScope.h sourceTree <group> - A4E19A682B06FFA7ECEC8CAB39B098FE - - buildConfigurations - - 72560F1BBE2BB763F4B17992EB9525B2 - 597979276424D679342EEF34BAA8A48E - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList - A4EE8D1BEE38B87066BAA1B09A047356 fileRef - 840426794A49EC536ABBD91C1E41D0A2 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - A51069A7F86CF1847F2D544C0777CD46 - - fileRef - FD7DDBDD0E5A72786C1A87D606D8334C - isa - PBXBuildFile - - A5DF5D2B2F2CD7CDFB5DBAAE572D0A1A - - fileRef - 5E22AF3F9B92CAC73AD5CADB03042700 + 0AC2D3A503587DF2175D90EDCB256B34 isa PBXBuildFile settings @@ -7885,24 +7398,21 @@ - A5F1C550C9A786773B3D74637E17FBF0 + A5073D16941EDD4CB431B45A76CEE34C children - 51DEAD099F5FEE7BE4DBD4CB7DDF0A0A - 734BEF397C9DA28B4B2D333301B13D20 - 445AF6E24DDA22F5494D248F7332AF4F + 521802A1964EB7D5383F4DD9B5805FBE + 5BC51F01B8E478B91F2685EC793E6CD1 isa PBXGroup name - Support Files - path - ../Target Support Files/XAspect + no-arc sourceTree <group> - A6700863B906BF25509A8103819B98F3 + A565A9CD7A9918942D221C5F1F513775 includeInIndex 1 @@ -7911,90 +7421,101 @@ lastKnownFileType sourcecode.c.h name - RACSignalSequence.h + RACGroupedSignal.h path - ReactiveCocoa/RACSignalSequence.h + ReactiveCocoa/RACGroupedSignal.h sourceTree <group> - A6DDB785D42C61A3E867E03E898635DC + A5809F61C5B6F19A814DFC29ECF82EB4 - fileRef - 72C4EE7AE7085C00CA1A9DCE3FC57C59 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + JSONAPI.m + path + JSONModel/JSONModelNetworking/JSONAPI.m + sourceTree + <group> - A7315DC7E23C786CCF26DCCDECE98C45 + A594D67EE669883807FBCA765E8B552D includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSSet+RACSequenceAdditions.h + NSUserDefaults+RACSupport.m path - ReactiveCocoa/NSSet+RACSequenceAdditions.h + ReactiveCocoa/NSUserDefaults+RACSupport.m sourceTree <group> - A75919C63C7C2CD096767B4D9FDB1E98 + A5AB135DAA1AA93F36BBD2DB2D796991 children - 99B5A311B3C0954BB5C558F90B626D6F - 20D2248D4C8B8FEEA1CE8F92D8746EED - 7BC207DADFD902C9E0F9E6C8749A426D - 1D391D61C0A9621E98CB7B5E8E1CBD16 - D0E0EAB42F50A63590B7CDC94C841DA8 - 7452892FA18756C935569E6F334C60D7 - 45EFCB171CA7F7314B3171C0011DF29E - 9D80E32A2AA1B3D7EF258957919E809A - 2E9908333E3087BD7341A44CD11F801A - 5E89FB3E7EF1A2C158337CDA267C6DBE - 0480BE93F654AD1A2D187F4B80831514 - B56FF81792456265A5FF00925C85FE39 - C954A8FAAF2F7A10B18F3F926D51557A - D178139F0687F97F4F446AE3F33251E1 - F66B78D4B47EE859EC50E73C16837FC7 - 3853D3CEFB1581CF31C6C033376581B0 - C282CB59296F9F83EA17F38A745BA23B - 2787CE701C0E32211602A41251973DB3 - 380FDEAE4D9EF40B76E1C9F0BFF14E39 - 2540DE235D6AB8FABDEE8086C064476A - 764F684BDBDE99D982727FDAACEF4E56 - BC4AED5F728CE8A8F7E6DC06C1A20DE0 - 5990D1386DBADFFF00C5F3FF1310B491 - FF42A8789D18FAD4AF9A46051584CD05 - E4FFFF5E9D9955E4515CDFBD7A7CD4CF - 804199840A93FA99DF0A79917ACFB1E5 + 8C7CDB026EEE224CDFF0F69F0B9AAFD4 + 62545A9E0285F51FC4E1E71F2CE6A80B + 5E54407AA7E6693446CC7A339437CB42 isa PBXGroup name - Masonry + Support Files path - Masonry + ../Target Support Files/XAspect sourceTree <group> - A76CA59A5280BEFC768D4A6F041FDA5B + A5C1035E8D6E58A45460F5B2CD955353 - includeInIndex - 1 + fileRef + 143CDB1E69B14E49CA034A39F5194687 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXBuildFile + + A6D7C2ED9D950AC69718588F473EF2E6 + + children + + D4FA8C3887E2B0E18FAC76CD493A9DE4 + 099B3F21BB953E1498B45D64B9207150 + CF725C0AF421A0B19A687A93D51EE210 + E558DB829F044906CCC96EE0CE60336F + 7FDE432BEF7E4CC2DD3C3D87CD8FF2BF + 851767040BDDEE2669237ECD7AAEBBF7 + EAF2198ED9386B68D3B65B66433B7733 + 893924D6C1772D528CBCCBA6EF73ECEC + + isa + PBXGroup name - XAspect.h + AFNetworking path - XAspect/XAspect.h + AFNetworking sourceTree <group> - A7A73F10361D20AC0896BA56E538FF5B + A6EA3EF30ED4BF71BDF6673EC96F2B4B + + fileRef + B4664FA8372B7CD58714C6A28F165B9E + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + A743224C6A1CA40D3FE0A1FDF4839D46 includeInIndex 1 @@ -8003,16 +7524,16 @@ lastKnownFileType sourcecode.c.h name - RACSubscriptionScheduler.h + JSONModel+networking.h path - ReactiveCocoa/RACSubscriptionScheduler.h + JSONModel/JSONModelNetworking/JSONModel+networking.h sourceTree <group> - A7B4D2FF6B848AD8A0E03D15242E63E1 + A7A0BE41621D3506C7DC9E8940621EF2 fileRef - 5DAFD622EC60936915F8F6D3985D6D06 + 9E55B4F4BC7D691EF9EC345F4D64C441 isa PBXBuildFile settings @@ -8023,17 +7544,42 @@ - A7B8ECCAD3285C571FFAE1F87156FBF2 + A7CA190A25309B882B049570D1E9CF3D - fileRef - 1BF33FD9958DE1C010305E6232266C1C + baseConfigurationReference + 98C98CDFB3F20F2925F6CD1F141BB14F + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MACH_O_TYPE + staticlib + MTL_ENABLE_DEBUG_INFO + NO + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PODS_ROOT + $(SRCROOT) + PRODUCT_NAME + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + isa - PBXBuildFile + XCBuildConfiguration + name + Release A7D31BD1F3AD4ED4612467FAD332F388 fileRef - 2787CE701C0E32211602A41251973DB3 + 9A6734BD63244CEB683F00F0CBA3B221 isa PBXBuildFile settings @@ -8044,23 +7590,25 @@ - A8C77BBDC031F4497C55AEC67342E6DD + A7F2287F2AE2FDF73582111450DFC9A3 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + RACMulticastConnection+Private.h path - Aspects.xcconfig + ReactiveCocoa/RACMulticastConnection+Private.h sourceTree <group> - A8D7C578B6B68B5495F6FF5D31A59BAD + A7F9385074DC5208E8095F7DF107298B fileRef - 092886A752FADB6A5E9DB78DE80535D2 + 861D072B1AC17B39839086655FC21DB9 isa PBXBuildFile settings @@ -8071,57 +7619,31 @@ - A968BA1D626D3AA22F4A35EB75E659F1 + A859E1AA4C4E3FE0653C98080FD4B758 fileRef - CA00DB45EEB83A2CC6ED12AD89126EB1 + 3870E4A9BA248AFE88604FFA4A61195A isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - A9A22E6C211491BADD7081F9B81691DD + A92E430F81BAEF7F14785C0EBA549E75 fileRef - 60AD14B2C64B23BBE722C88159592DC2 + AF8C2A5D6D0B444877FEDC80D2FF756B isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - AA8DD7FA05C8337A8B8877E5619B71C7 - - buildConfigurations - - 617AFA0F321ECCAB547A8C3B986B7021 - 4525B4C9B4B93E98FF1393778F151A0C - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList - AAF515E9CAE57C26AF1A3E51495FF779 + A96604F8EA6B9136A073E2DA05A29653 fileRef - 90225DC600376307F93B98526613466C + DE194BEF0D2CD53AFE4B2F0F4C3827EA isa PBXBuildFile - AB1FC1B98EC87E9A74EE8930C501F619 + AAAA8779AE4198974DF5AEEBE7C5C0C3 fileRef - 6AFDB77C029A97F36029E1075C05A73B + 0483E8EC03F94EB38AE44D540D1103FD isa PBXBuildFile settings @@ -8132,33 +7654,35 @@ - AB3B17E9CBA0E18485A5E995F953D701 + AAC25FA4FF2E080CF948027BF6FE8C4B + fileRef + 059196CADDF986D00738A637A66671BD isa - PBXTargetDependency - name - Aspects - target - DBC9A0AF6D4571D059D2AF2422F2BD6E - targetProxy - B7406BAC0B4267B78868DCB0D2687E12 + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - AB519031BC04B2F8D8CD7E010418BF54 + AAC3B58AD7A45FCEC3A1A08C5AD923D5 - includeInIndex - 1 + fileRef + 5E57C78F83934D86D9A5171C30083D59 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACUnit.h - path - ReactiveCocoa/RACUnit.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - ABB1886E908810BEFE5C77EFD2AD647B + AB2602C596347CDA82E4E4BE36223D64 includeInIndex 1 @@ -8167,16 +7691,16 @@ lastKnownFileType sourcecode.c.objc name - JSONModel+networking.m + RACGroupedSignal.m path - JSONModel/JSONModelNetworking/JSONModel+networking.m + ReactiveCocoa/RACGroupedSignal.m sourceTree <group> ABC9A1F8D86F932BEE6C28A8849048A6 fileRef - 04E49DCD6C8078833262469CB937AD94 + 6CF371128BD01C378F8B6D67975C4BAF isa PBXBuildFile settings @@ -8188,14 +7712,32 @@ ABD9C7E4737F28E48833F21BDAF6B477 fileRef - 7105BBEE0C908BB9E862D6102DB7E3FF + 3853F138C9D4EEEC505839A6D27FEC0F isa PBXBuildFile - AC2DE229068B7B763CBD524DFD156E9F + ABF1D5A5AD9A387B49D77C61E11E8A6A - fileRef - B1C3144078FB130BB89DA3467285B625 + isa + PBXTargetDependency + name + SDWebImage + target + 32B858CF09199FB109685F306D190C38 + targetProxy + 8A34BD33A8B98A15CED4C2A6BC8D9C93 + + AC9180896C090E0ED47E761151004746 + + fileRef + 153E3A7DEF14D7E494AFFA6073638EB6 + isa + PBXBuildFile + + AC94144A1A25D7A6C67D19F441265528 + + fileRef + 14D765B9A42437B82B77A38E5B9E8D4B isa PBXBuildFile settings @@ -8206,7 +7748,33 @@ - AC5083844F2D2F9F51E1E80933EC149E + ACBEBDA40B2AD70BCD4327B7E5D81D80 + + buildConfigurations + + 039BE81A2AD49A82F59318AEE04DFF37 + A7CA190A25309B882B049570D1E9CF3D + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + ACF42F60DB38312D939C3817F3AECE32 + + fileRef + E7EA101BDD489A4BED3B8F0F4066EC17 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + AD4AA56235609BBDEF9FD234D26DFD1E includeInIndex 1 @@ -8215,27 +7783,34 @@ lastKnownFileType sourcecode.c.h name - JSONModelError.h + NSFileHandle+RACSupport.h path - JSONModel/JSONModel/JSONModelError.h + ReactiveCocoa/NSFileHandle+RACSupport.h sourceTree <group> - AC5CD16DC4AE8ED5CACAA2518DA3073D + AD9C8C591110EFB2C25C9444CDED91BA fileRef - B544D885BF130D8DD726765A263C4C19 + 7A3EE7C0964DB86D3D08DDDF2F1EAF72 isa PBXBuildFile settings ATTRIBUTES - Private + Public - AC683279CE140109D25DB1A0329F9E8F + AE0606BF4AC02591B760F465EB8EDB9A + + fileRef + BAFCA3FA18B85A757257C7522C957A2B + isa + PBXBuildFile + + AE4F977AC92FF4C9A2655E4EA0803C87 includeInIndex 1 @@ -8244,49 +7819,35 @@ lastKnownFileType sourcecode.c.h name - JSONModel+networking.h + RACScopedDisposable.h path - JSONModel/JSONModelNetworking/JSONModel+networking.h + ReactiveCocoa/RACScopedDisposable.h sourceTree <group> - ACF42F60DB38312D939C3817F3AECE32 - - fileRef - 52913DD4BC5EAAD96971E4DD04EA8A88 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - ADAEC0B257466F2D1743C9E8B6FF1563 + AE607E682415FAA160B33C7C13A8475B fileRef - E798802252FBC085207B7EF5246FD5D4 + 8DEBE35687E8091A51BD515F195DF8EC isa PBXBuildFile - ADC08A90E61AC49D87EDCD039A238A4C + AED2BAD1D43745DD69F82C134A985AB3 fileRef - 14A13A3D04A19FF2940A9A03A5A51B3E + A5809F61C5B6F19A814DFC29ECF82EB4 isa PBXBuildFile settings - ATTRIBUTES - - Public - + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - ADC1897042CF15753B9EF3672B9ACE2F + AF240C3E171360773D703C4D2C4DB676 fileRef - 2829A21EC74C7D473B3F7D03296937B0 + 44877DC0490619A24BD20531F6A0A5DE isa PBXBuildFile settings @@ -8297,14 +7858,7 @@ - AE0DA3B70021F67AB7543B247F1754DD - - fileRef - 6FB3CFFEB44E4B8FCDDB27217F9D183D - isa - PBXBuildFile - - AE1818531080A2759F2C77A7CE0C1AC2 + AF5656A5796440E7FFA6019C05D4FBF3 includeInIndex 1 @@ -8313,38 +7867,23 @@ lastKnownFileType sourcecode.c.h name - UIImage+GIF.h + NSArray+JSONModel.h path - SDWebImage/UIImage+GIF.h + JSONModel/JSONModelCategories/NSArray+JSONModel.h sourceTree <group> - AE607E682415FAA160B33C7C13A8475B + AF59ACE080C0107D3AE7C9A885BB49F5 fileRef - F9CA04A1AC1A5119C264BFE9667EE809 + 9E05D3F78600BEB3A30E851F7FA55B3F isa PBXBuildFile - AEB9E43201C4A3C8CF078B10B1B2DC7E - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACArraySequence.h - path - ReactiveCocoa/RACArraySequence.h - sourceTree - <group> - - AEBDFAF53661B68583504130E00C7AE9 + AF60285AA341AD6671EC96486117A816 fileRef - BF8E7560208D1238F6A4223E9701F1D5 + 5BC51F01B8E478B91F2685EC793E6CD1 isa PBXBuildFile settings @@ -8353,40 +7892,44 @@ -fno-objc-arc - AECD5709B98654660022402C007A5FBB + AF62B956405F7734F5A9B8F3FD4B1B96 fileRef - D839E838BF47A54E1A485B25A793BDC2 + 6BED4DDD022C6F6F69A4E108741AB69C isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - AED2BAD1D43745DD69F82C134A985AB3 + AF8C2A5D6D0B444877FEDC80D2FF756B - fileRef - 45B60A0181BE24D31D4043D1238F85A3 + includeInIndex + 1 isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIAlertView+RACSignalSupport.m + path + ReactiveCocoa/UIAlertView+RACSignalSupport.m + sourceTree + <group> - AF62B956405F7734F5A9B8F3FD4B1B96 + B048FB3C43D6C6205466CC99604792E3 - fileRef - E4FFFF5E9D9955E4515CDFBD7A7CD4CF + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImagePickerController+RACSignalSupport.m + path + ReactiveCocoa/UIImagePickerController+RACSignalSupport.m + sourceTree + <group> - AFA25CF4BA70362C1030B679756120BC + B05A64156A3417B7CC4E3AF35C82A680 includeInIndex 1 @@ -8395,31 +7938,31 @@ lastKnownFileType sourcecode.c.objc name - NSOrderedSet+RACSequenceAdditions.m + NSString+RACKeyPathUtilities.m path - ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.m + ReactiveCocoa/NSString+RACKeyPathUtilities.m sourceTree <group> - B0A92416C167D4187401DEF3A8C4B76C + B0A088F025B46CF3549CF0EFF4FEE416 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SDWebImageManager.m + CYLTabBar.h path - SDWebImage/SDWebImageManager.m + CYLTabBarController/CYLTabBar.h sourceTree <group> B114DE31A770E7A8D0FC345F47973314 fileRef - 10F92B4955961B1F2D4CFCFAAB99E858 + 387FB2EBE17C9CD07247829A3C8B6D08 isa PBXBuildFile settings @@ -8433,48 +7976,18 @@ B12AD2EE044D6F7424F75F1506B516B2 fileRef - 66E5E1A295BA40E925541B25C4537640 + E9BC93CF7243043504BABAE792DD43DA isa PBXBuildFile - B13C33D0C0315117BBAF70867F7E6C57 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - XAObjcMetaprogramming.h - path - XAspect/Macros/XAObjcMetaprogramming.h - sourceTree - <group> - - B153305CAB6057ABEA1D38F1ED6C3FB3 + B13972E4A1736403D94A273BA539CFED fileRef - 249A50DF25C576887DE7B90A3C06C0C5 + 1D47ED097A3DAD61C001D6FD5485D3B6 isa PBXBuildFile - B1992E4E26237C5C7D9355F0F0839C3B - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIButton+WebCache.m - path - SDWebImage/UIButton+WebCache.m - sourceTree - <group> - - B1C3144078FB130BB89DA3467285B625 + B162F15944278B58E9A5C9E1959A2601 includeInIndex 1 @@ -8483,77 +7996,38 @@ lastKnownFileType sourcecode.c.h name - RACSubscriber.h + NSArray+RACSequenceAdditions.h path - ReactiveCocoa/RACSubscriber.h - sourceTree - <group> - - B1CFC19DA8F8AF57C03C8110502534C9 - - children - - 359D1ECCC89304F4A8F821C51121AF64 - - isa - PBXGroup - name - Resources + ReactiveCocoa/NSArray+RACSequenceAdditions.h sourceTree <group> - B2865411AB79B1B3B7A2750532B924F3 + B261D888D53B9D2390374ECFEC786B9B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACScopedDisposable.m + NSString+RACSequenceAdditions.h path - ReactiveCocoa/RACScopedDisposable.m + ReactiveCocoa/NSString+RACSequenceAdditions.h sourceTree <group> - B2942371B91C653656D0F182C2DB7D53 - - fileRef - 6B47FA1360ACA44E86F301D6E038EF72 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - B2B30D15E8EE4B35D69F4DA1CF7B5D2F - - fileRef - 64CA7095AAA3F4A1748B3FB792869BFF - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - B2B5DEC33B644F946C59F656AAAA8146 fileRef - B32C2D35515F69C3DF162EF759489EEE + EF14456F85CB3D05B276E8FDC8A98826 isa PBXBuildFile B2B7C90BA9C4DBD9851C75AC801B0E8E fileRef - D0E0EAB42F50A63590B7CDC94C841DA8 + F2EFF7F54E643FC6C7E72B5372091F26 isa PBXBuildFile settings @@ -8567,25 +8041,10 @@ B2F7F45FDBEC10A913006AA8951AF781 fileRef - E6EF7EE978A5191A9BB4FC5BDE0D60CC + 865F109140A1EAAC154F6FBA05124DDE isa PBXBuildFile - B32C2D35515F69C3DF162EF759489EEE - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - AFNetworkActivityIndicatorManager.m - path - UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m - sourceTree - <group> - B37F0F91F85060E28F1DAAB522DC7EC1 buildSettings @@ -8659,12 +8118,20 @@ name Debug - B3836EC94CD274E785D8B0302683757D + B39D5AFCAA041CAB23BCBF0A2106C8F2 - fileRef - B2865411AB79B1B3B7A2750532B924F3 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFSecurityPolicy.h + path + AFNetworking/AFSecurityPolicy.h + sourceTree + <group> B3D1D13E0C6553800746CB8FD61CF946 @@ -8687,41 +8154,75 @@ sourceTree <group> - B3EA2063C2573EB1BF8FEDF682589413 + B3F8334E6CE96A5F3E36C9573B6CB7A2 - children - - 3B2929828DB9DD7C1A10ED7F089791FB - 578183BBC5F4AAE9926C9AB1455DD321 - + fileRef + BE1F430ADF45E969576002079ED2FD3C isa - PBXGroup - name - JSPatch - path - JSPatch - sourceTree - <group> - - B42262E7778E726F825B5C16311E64E2 - - includeInIndex - 1 + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + B406B28EA904ABBFF12E70F383AF3832 + + fileRef + 8FEA57F71D7521DFC5241AA6617499DE + isa + PBXBuildFile + + B42C86C6EA29770EC0AC436082B2438A + + fileRef + 3173AA738305CC0BE07E6603709A8E19 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + B4664FA8372B7CD58714C6A28F165B9E + + includeInIndex + 1 isa PBXFileReference lastKnownFileType sourcecode.c.objc name - RACSubscriptionScheduler.m + SDWebImageDecoder.m path - ReactiveCocoa/RACSubscriptionScheduler.m + SDWebImage/SDWebImageDecoder.m + sourceTree + <group> + + B4C7F254D7D19D970B5743C513732CC4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIControl+RACSignalSupport.h + path + ReactiveCocoa/UIControl+RACSignalSupport.h sourceTree <group> - B4B399D6B6BD36800388C38DF514C523 + B4DB0EFD9EB499E42020C73EA8B90052 fileRef - CE01489CD5CF601457B6D2C5D1B00210 + 749BF5902E6E6891EF6ADC8A272817EC isa PBXBuildFile settings @@ -8732,7 +8233,7 @@ - B544D885BF130D8DD726765A263C4C19 + B4F41B4CFA0893909AE4431681F368D5 includeInIndex 1 @@ -8741,57 +8242,82 @@ lastKnownFileType sourcecode.c.h name - RACStream+Private.h + RACIndexSetSequence.h path - ReactiveCocoa/RACStream+Private.h + ReactiveCocoa/RACIndexSetSequence.h sourceTree <group> - B5504A9492096387C2A9F52CA74C8F2F + B5281F66A21D235BBFBEB4D43FF85466 - children - - FBA183F8CEB6E1502C9CBA37072AA76E - 0135CB45DDDBA452074962CC4FBD15C4 - 3FD55D0C258BBCEA9D5C4D4EB5A1683E - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - Support Files + UIImageView+HighlightedWebCache.m path - ../Target Support Files/AFNetworking + SDWebImage/UIImageView+HighlightedWebCache.m sourceTree <group> - B56FF81792456265A5FF00925C85FE39 + B54AD408F1721A01D775611A2BB31C2A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - MASViewAttribute.h + RACMulticastConnection.m path - Masonry/MASViewAttribute.h + ReactiveCocoa/RACMulticastConnection.m sourceTree <group> - B57DA85175B1136F0C479F699E6789CC + B563B9616A97A1BA104410BAC9A46D70 - fileRef - 104AFF1DE2EE972BC6D3F0B9E74F0BAE + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + name + RACSignalProvider.d + path + ReactiveCocoa/RACSignalProvider.d + sourceTree + <group> + + B57830D98B2849080842A747C6F88DA7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACKVOChannel.m + path + ReactiveCocoa/RACKVOChannel.m + sourceTree + <group> + + B65FD05A1FF795BB0A8F5E367367CD3A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Aspects.h + sourceTree + <group> B6653DB75D219E078020C341A7D83ECE @@ -8810,7 +8336,7 @@ B685C45C6BF1321FC17F0F03AC635E4C fileRef - 1DAE47CB93A8820B8E21C80C65B414FA + 81551035D30538526F3A9F2D9B2E527C isa PBXBuildFile settings @@ -8819,24 +8345,7 @@ -DOS_OBJECT_USE_OBJC=0 - B69D0BAF9F73E441DF864679294AA04F - - children - - CC2EF386E6EB31FC9BC5D90FD15B70B1 - 499566C0E9CD3BD5D392DBEC16BAD137 - 4DC141C3FDE4F29B3B8F42FB8054EB4F - - isa - PBXGroup - name - Support Files - path - ../Target Support Files/SDWebImage - sourceTree - <group> - - B69F9892BE1074EA541607EE65E96594 + B6A22D5E9ECA1D372DBC0790D274EFAC includeInIndex 1 @@ -8845,26 +8354,27 @@ lastKnownFileType sourcecode.c.objc name - UIWebView+AFNetworking.m + UIButton+WebCache.m path - UIKit+AFNetworking/UIWebView+AFNetworking.m + SDWebImage/UIButton+WebCache.m sourceTree <group> - B7406BAC0B4267B78868DCB0D2687E12 + B6C3BB0342CA0157595A91FA2E1EA844 - containerPortal - D41D8CD98F00B204E9800998ECF8427E + fileRef + 62545A9E0285F51FC4E1E71F2CE6A80B isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - DBC9A0AF6D4571D059D2AF2422F2BD6E - remoteInfo - Aspects + PBXBuildFile + + B70A62D71CABE0042AD3B3FD69CE0B8D + + fileRef + 36916CF5DA1FE373970D2D502ED8C866 + isa + PBXBuildFile - B7686B7D69B3E285F991DBF462667415 + B74EF8B935DF8DB6BDF3B7898A6E959B includeInIndex 1 @@ -8873,31 +8383,31 @@ lastKnownFileType sourcecode.c.objc name - AFHTTPRequestOperation.m + UIStepper+RACSignalSupport.m path - AFNetworking/AFHTTPRequestOperation.m + ReactiveCocoa/UIStepper+RACSignalSupport.m sourceTree <group> - B793FFC7E3BBE870834BBCB42A153059 + B7829DA442DED671B644E2881F1925BE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIButton+RACCommandSupport.m + SDWebImagePrefetcher.h path - ReactiveCocoa/UIButton+RACCommandSupport.m + SDWebImage/SDWebImagePrefetcher.h sourceTree <group> - B82A170962598E7EAE9A8752574B7B74 + B7B46BA3170AB38B02FB2D5F33476BF8 fileRef - 582956321F29E8CB5D8D4000083FA273 + F0218A60CF118E77C2F159926207C45A isa PBXBuildFile settings @@ -8908,10 +8418,17 @@ - B85FBB6D7E49C61E5270EF4485F255AE + B7B7374AE3A5C59A4FC6FB14EAFA0BED + + fileRef + AB2602C596347CDA82E4E4BE36223D64 + isa + PBXBuildFile + + B82A170962598E7EAE9A8752574B7B74 fileRef - 38F406988E1D01B50F475863B31EC199 + BC7BE710902B679323E6EC35C5CE26FA isa PBXBuildFile settings @@ -8925,7 +8442,7 @@ B88B985BCF32AAAD610994FAAE7B9604 baseConfigurationReference - FBA183F8CEB6E1502C9CBA37072AA76E + 9B5DB9EEDE586E53C458D04475A7E704 buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -8956,52 +8473,10 @@ name Debug - B8BB79DE32405EE2DC4BEA14B1FA242F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACBehaviorSubject.m - path - ReactiveCocoa/RACBehaviorSubject.m - sourceTree - <group> - - B8BEDDCAF0176CA17B822E7F3C17EB2E - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACEmptySequence.m - path - ReactiveCocoa/RACEmptySequence.m - sourceTree - <group> - - B8E5BEC8B81D972D365B70F7AA8046CA - - fileRef - 758978F83428DA4D8B66E32E141B5885 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -fno-objc-arc - - B9140FC12410CBE58A51EEC03AB28A4F baseConfigurationReference - FBA183F8CEB6E1502C9CBA37072AA76E + 9B5DB9EEDE586E53C458D04475A7E704 buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -9032,7 +8507,20 @@ name Release - B916116B6285D76B6613F1A54BD1A543 + B91C1A689286738712B2FC6CD94C37C7 + + containerPortal + D41D8CD98F00B204E9800998ECF8427E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 0C1D89EAE68EF4D4ABEDB611EC44AAB0 + remoteInfo + CYLTabBarController + + B941BEB290F39685CD1920FE7E9EE280 includeInIndex 1 @@ -9041,20 +8529,13 @@ lastKnownFileType sourcecode.c.h name - XACrystallization.h + UIImageView+AFNetworking.h path - XAspect/Core/XACrystallization.h + UIKit+AFNetworking/UIImageView+AFNetworking.h sourceTree <group> - B9292BFF0457A5BA88B32D4EF8F38AB3 - - fileRef - 0BD06C4DDA7B80C1742B09DDCF556762 - isa - PBXBuildFile - - B95B6BF4B263D0E9857C5CE00A3DB020 + B99E50A56C2E80EB7207069737D1225B includeInIndex 1 @@ -9063,41 +8544,31 @@ lastKnownFileType sourcecode.c.h name - UIAlertView+AFNetworking.h + UIImage+GIF.h path - UIKit+AFNetworking/UIAlertView+AFNetworking.h + SDWebImage/UIImage+GIF.h sourceTree <group> - B995F6C491CD4491EFFB38B22D432FA4 + B9C10C63D018D5B487E431124476D073 - buildConfigurationList - F0314A47BEA034880AA0E333F4B4F7B7 - buildPhases - - D1CE1B16C2DD160F766958C20B339705 - 3690256E0F99DB05CD807419A1A05648 - A0A220208A7665AAB0C35C49DA236BE6 - - buildRules - - dependencies - + explicitFileType + archive.ar + includeInIndex + 0 isa - PBXNativeTarget + PBXFileReference name - XAspect - productName - XAspect - productReference - 63958894F8A2B30EC7DC43706ED1A1CA - productType - com.apple.product-type.library.static + libAspects.a + path + libAspects.a + sourceTree + BUILT_PRODUCTS_DIR B9DAA002CF3E0E8EBE9B6E9A7778CFD4 fileRef - 0135CB45DDDBA452074962CC4FBD15C4 + 72EBC3B91782DFC648C33324DEF5FB15 isa PBXBuildFile @@ -9108,14 +8579,7 @@ isa PBXBuildFile - BA34B3B7138CB040AF983280C590F59D - - fileRef - BF169F0D65145A9B7AC7E446C4A55706 - isa - PBXBuildFile - - BA6428E9F66FD5A23C0A2E06ED26CD2F + BA6428E9F66FD5A23C0A2E06ED26CD2F includeInIndex 1 @@ -9135,7 +8599,21 @@ BA743E2665C1C3D87FD70E8CFBC581AC fileRef - FCC32E4089B93933079F7040E4A7491E + 27E4264B68067CFF369F4D19682FA599 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + BA8CA89D16A3069C9C315ADA4C671E0C + + fileRef + E60362B62BC4A2E7872BD7F400EF400F isa PBXBuildFile settings @@ -9146,7 +8624,26 @@ - BABD49C2333852326929CEAEB6FE04E7 + BA8E5F31353D2182B8BD558BD832C34D + + fileRef + DA3EBE76BCED4F93B80D6CC8A394C7B2 + isa + PBXBuildFile + + BAA47853766464C0B5C994A5A83D1E0B + + fileRef + 6191584C259B4383F47D6A49A9D85E5C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fno-objc-arc + + + BAF07965D9BAAAA1592777CA8FC127D8 includeInIndex 1 @@ -9155,33 +8652,28 @@ lastKnownFileType sourcecode.c.objc name - JSONModelClassProperty.m + UISwitch+RACSignalSupport.m path - JSONModel/JSONModel/JSONModelClassProperty.m + ReactiveCocoa/UISwitch+RACSignalSupport.m sourceTree <group> - BAF078745485F21C76E8293BF6982CE7 + BAFCA3FA18B85A757257C7522C957A2B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc + name + RACEagerSequence.m path - ReactiveCocoa-prefix.pch + ReactiveCocoa/RACEagerSequence.m sourceTree <group> - BB036866E506E2539AA1C504AA47DD6B - - fileRef - 2B675FE7BE27BF4A88FACDEC5C041CCC - isa - PBXBuildFile - - BB5406E50F64CC1977954CD5228C8B81 + BB312BC3F8EB1727EBD62393D9CE870D includeInIndex 1 @@ -9190,16 +8682,23 @@ lastKnownFileType sourcecode.c.h name - AFURLRequestSerialization.h + SDWebImageDownloaderOperation.h path - AFNetworking/AFURLRequestSerialization.h + SDWebImage/SDWebImageDownloaderOperation.h sourceTree <group> - BBAA8D4BFEB1EF83EEFA9E8DC464EBE3 + BB94D5A50591219B66748B72795E43F3 + + fileRef + 7A6BC89400594DE9E000159B75A95DD3 + isa + PBXBuildFile + + BBB5BFA88D37F2C6701759401517FC2D fileRef - E947279877DF8A82CF3C684C9A8D3F6D + C56A7AB7D7ED6C3346A3BF10ADBC8EFF isa PBXBuildFile settings @@ -9210,7 +8709,7 @@ - BC4AED5F728CE8A8F7E6DC06C1A20DE0 + BC124DA3E0AD75608C3477374BEBC17C includeInIndex 1 @@ -9219,45 +8718,38 @@ lastKnownFileType sourcecode.c.objc name - View+MASAdditions.m + NSObject+RACDeallocating.m path - Masonry/View+MASAdditions.m + ReactiveCocoa/NSObject+RACDeallocating.m sourceTree <group> BC7993B7436D4D7FADE6DD554DA52769 fileRef - C2047EA48BA7AC3B9DFC7F25A4F61244 + 92D2A49D15CEE5164F48E38340AD32AA isa PBXBuildFile - BCCA176AFF17EF4AA821307506265219 + BC7BE710902B679323E6EC35C5CE26FA includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIControl+RACSignalSupportPrivate.m + JSONModel.h path - ReactiveCocoa/UIControl+RACSignalSupportPrivate.m + JSONModel/JSONModel/JSONModel.h sourceTree <group> - BCD4B362C6194513150915437754E2D4 - - fileRef - 20D2248D4C8B8FEEA1CE8F92D8746EED - isa - PBXBuildFile - - BD906B445A4095AD878131A63038A65C + BC8666627E83F9BBDD96BAEE1B7AA49E fileRef - A7A73F10361D20AC0896BA56E538FF5B + B4F41B4CFA0893909AE4431681F368D5 isa PBXBuildFile settings @@ -9268,39 +8760,10 @@ - BDD210D7537DD15CFE59AE126005E5F8 - - fileRef - 2E9908333E3087BD7341A44CD11F801A - isa - PBXBuildFile - - BE024118D329F8F566BD1811A1DC16CB - - fileRef - 1D391D61C0A9621E98CB7B5E8E1CBD16 - isa - PBXBuildFile - - BE05843E2D30494B31AE9076742B8F06 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UISlider+RACSignalSupport.h - path - ReactiveCocoa/UISlider+RACSignalSupport.h - sourceTree - <group> - - BE2BB54978E18C9CB0472402EB722F1D + BCBCC9FF9151BBAA22285657DC3D2CE3 fileRef - 2C397EF1FF5C3F34C812BCEFF39C429A + 0E07CAC8A5C9858E30FF5E9AED1BD6AB isa PBXBuildFile settings @@ -9311,32 +8774,32 @@ - BEB6974807F8FFE158ED0133C9A3CE9B + BCD4B362C6194513150915437754E2D4 fileRef - B8BEDDCAF0176CA17B822E7F3C17EB2E + EE76FC3577DCDB4A2C6FF6302EC314BE isa PBXBuildFile - BF169F0D65145A9B7AC7E446C4A55706 + BDBF54DA40B41A16762C4A4C5A0C8781 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACSubscriptingAssignmentTrampoline.m + RACArraySequence.h path - ReactiveCocoa/RACSubscriptingAssignmentTrampoline.m + ReactiveCocoa/RACArraySequence.h sourceTree <group> - BF805FEC28212F40516FE26B1BF8C372 + BDCE76BCF06764923721B3020CB74123 fileRef - 3036C5663F553FD2A22AD6B74961059A + AD4AA56235609BBDEF9FD234D26DFD1E isa PBXBuildFile settings @@ -9347,30 +8810,17 @@ - BF8E7560208D1238F6A4223E9701F1D5 - - includeInIndex - 1 - isa - PBXFileReference - name - XACExtensions.c - path - XAspect/Core/XACExtensions.c - sourceTree - <group> - - BF940DBDB6B4DCCF226F6DC35983D307 + BDD210D7537DD15CFE59AE126005E5F8 fileRef - E798802252FBC085207B7EF5246FD5D4 + 3311C026F41413D4A8B6F47D772F5F63 isa PBXBuildFile - BFAE693DAAF8358EF4B63138D24773BB + BDFD9AF00C44DF99D52D6443D37A0A8E fileRef - E91C9516CFEAF53AA8B50A9B9F11B275 + DCAF00830DD6C09D6D61A9C1199CA0CE isa PBXBuildFile settings @@ -9381,34 +8831,14 @@ - C020DA99B6AD309040A6C00ECBA4EE19 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - CYLTabBarController.xcconfig - sourceTree - <group> - - C1453BDD59B774566354DEA20C02B55B + BE024118D329F8F566BD1811A1DC16CB fileRef - AEB9E43201C4A3C8CF078B10B1B2DC7E + C93B1E549DCB759BA26517CF8ABE4C4F isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - C1AA148B9439B41219BDA56410A9B5C2 + BE1F430ADF45E969576002079ED2FD3C includeInIndex 1 @@ -9416,27 +8846,27 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + RACDisposable.h path - Aspects.h + ReactiveCocoa/RACDisposable.h sourceTree <group> - C2020C1EB46409061C8BB7DF0E703EC9 + BEC22C108316732DFAD5A8649D25F58F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIActivityIndicatorView+AFNetworking.h + sourcecode.c.objc path - UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h + SDWebImage-dummy.m sourceTree <group> - C2047EA48BA7AC3B9DFC7F25A4F61244 + BF48CE6E9B022C722DF102F52A931AFF includeInIndex 1 @@ -9445,13 +8875,41 @@ lastKnownFileType sourcecode.c.objc name - AFNetworkReachabilityManager.m + JSONValueTransformer.m path - AFNetworking/AFNetworkReachabilityManager.m + JSONModel/JSONModelTransformations/JSONValueTransformer.m sourceTree <group> - C208817A5549140282E7150447CB076D + BFAAD2731711F0B848DEBAF029A8E4B7 + + fileRef + F221452B1B1DB6A6CCF5BD5EE23ABA54 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + C3336607D83BE9B77CEBE5E35A1D3F81 + + fileRef + 46D65F7EB6FBC2C765A3D74191A5444B + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + C39AF15B4BFC1DD927679F15E9C317F3 includeInIndex 1 @@ -9460,87 +8918,63 @@ lastKnownFileType sourcecode.c.h name - NSObject+RACDeallocating.h + RACBlockTrampoline.h path - ReactiveCocoa/NSObject+RACDeallocating.h + ReactiveCocoa/RACBlockTrampoline.h sourceTree <group> - C24B2A8EF774E2F65A8CF2F8727C6DDE + C3E17119C9E2A1300F7B36A35F1AAD66 children - 5AA41E85613DF2260863CC8B56190903 - B69D0BAF9F73E441DF864679294AA04F + 3315F33B1B77126B68CCFF1FAF187B0B isa PBXGroup name - SDWebImage - path - SDWebImage + Frameworks sourceTree <group> - C282CB59296F9F83EA17F38A745BA23B + C421FE4B29E3C5DBCDE764368D0C474F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSArray+MASAdditions.m + NSObject+RACKVOWrapper.h path - Masonry/NSArray+MASAdditions.m + ReactiveCocoa/NSObject+RACKVOWrapper.h sourceTree <group> - C2CAA3E9C9A2D5484A5B29E9A6F0F62E - - fileRef - 9D63BAE391E0628AE26D7CC280015CB1 - isa - PBXBuildFile - - C2F679593251F2B5A69C3E1DA3FFA626 + C46BCDBFB5F4C6A682212FB8371F8E9C - children - - EC440A5421781218D66C3DA94AAD9F7E - 44EC176E81593AA77DA1126913033AF8 - 2A096C86942CC895EA812CB46F269472 - 8F6FC9245F1F8D05DC3F3F4059A79FBA - 7165930A2A48BA178E2CFFDBEB5EF44F - 35FD08A7594776E99EBDB2276B282532 - B5504A9492096387C2A9F52CA74C8F2F - E8D42D390C04E2635A464E5D2250089E - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - AFNetworking + AFHTTPRequestOperationManager.m path - AFNetworking + AFNetworking/AFHTTPRequestOperationManager.m sourceTree <group> - C2F80B454486352D3A1468370B9B67C2 + C4EA856651212F3B9A77D3EA4C6EC0C8 fileRef - 456F16D56E6A14837886973506955D7F + 3F71D2177669333731E820865DA2D231 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - C30865260F1AA88E2CCC8258DD8F5C5F + C56A7AB7D7ED6C3346A3BF10ADBC8EFF includeInIndex 1 @@ -9549,51 +8983,16 @@ lastKnownFileType sourcecode.c.h name - NSObject+RACLifting.h + SDWebImageDecoder.h path - ReactiveCocoa/NSObject+RACLifting.h + SDWebImage/SDWebImageDecoder.h sourceTree <group> - C34EC341C42C03679C4D189B4B545BD5 - - fileRef - 34E3C23774C3F071C360A95E781D5C0A - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - C38AD16F31C060C53626F2534346AF82 - - fileRef - 283E771991494A2B96E2BBCE637D6390 - isa - PBXBuildFile - - C46D032E779A9A0460C48DE7D7E2EF01 - - fileRef - 982EC4210D0E11D4C222FE2EC9A04E3D - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - C58268D5A4D2A786576E0EAA5B50FB93 fileRef - 8FF4ACBA69C04C52C770DBB4AAA0F442 + 4ECCA2FD461EFA3B022347720B7A0237 isa PBXBuildFile settings @@ -9607,7 +9006,7 @@ C591CE6B9FA1950409E543A70B3ECABE fileRef - 8D702D0F1FBE57C1D1C6980E22C66EBE + 267FD3AFADCF12800AF3DAB8E3B7C89D isa PBXBuildFile settings @@ -9618,32 +9017,53 @@ - C5A3B5E4AF4CC833A8A862DCD5968428 + C6446B6E15442B15106D49DC60183D1B fileRef - F440593CC80B6F762E15F1ED231B4E19 + 0ABC93F6575931ED410C56908FE082AF isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - C60FDD97329B3F41A91733E7D1369A56 + C64BCDC42B81D042946E04636B106880 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACQueueScheduler.m + RACScheduler.h path - ReactiveCocoa/RACQueueScheduler.m + ReactiveCocoa/RACScheduler.h + sourceTree + <group> + + C653B6CB5FCB8B5E170D0E8577D5FCA2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Aspects-dummy.m + sourceTree + <group> + + C6975705934F58AFCAACB89DB3EB294E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIWebView+AFNetworking.m + path + UIKit+AFNetworking/UIWebView+AFNetworking.m sourceTree <group> @@ -9661,25 +9081,46 @@ isa XCConfigurationList - C6AFC54A7B6BE1A53FCF12B72CFD340A + C6C5BF6955312BDF8635A74BEE022378 - includeInIndex - 1 + children + + EB7CA93484A64DA41DA995CDCDAAFE51 + A5809F61C5B6F19A814DFC29ECF82EB4 + 5E5FF559E666649849CFF4F8D446629C + E7EA101BDD489A4BED3B8F0F4066EC17 + 40D595E6B087FCC985869CB435BD62BD + 6CF371128BD01C378F8B6D67975C4BAF + BC7BE710902B679323E6EC35C5CE26FA + 87F282AB3C2677BD2D143D5020431ED2 + A743224C6A1CA40D3FE0A1FDF4839D46 + 1F2F2AA47466EE9B72EB785A21775E71 + DA02260E9C9DA18939EF3B57CA5D401E + 19D02301BF02838213F24E7F8887821D + 04783261FB6729BD15B0FE2946512043 + CD1B1D9F29C1568866D360CAE9280B20 + 00929B0F1375903B01DA333074381F17 + 74ACE91E1BB28EE8AE35E3B58C9D3A3A + 267FD3AFADCF12800AF3DAB8E3B7C89D + 20C5209E3167276E1F17E266DDB92675 + BF48CE6E9B022C722DF102F52A931AFF + AF5656A5796440E7FFA6019C05D4FBF3 + 81551035D30538526F3A9F2D9B2E527C + F5DE55D327DB675D6B778FE089325A79 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - RACTuple.h + JSONModel path - ReactiveCocoa/RACTuple.h + JSONModel sourceTree <group> C6EE194D232E9FE87097C0F1DF91B9FA fileRef - 9D80E32A2AA1B3D7EF258957919E809A + 19666C0EDCA9726C17BF976A7F4A32E0 isa PBXBuildFile settings @@ -9690,10 +9131,25 @@ - C7ACDDE36465ACAF629FEC233B1BF172 + C70A741FF32DD5926E496F5F15B2AC4A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UISlider+RACSignalSupport.m + path + ReactiveCocoa/UISlider+RACSignalSupport.m + sourceTree + <group> + + C755153372C2D17AB51E52B671A4DDB9 fileRef - CC5C270FBF1CEE5E35AE6CD12033ED2D + 9AB97AF7B67492F6587E29623D14D2A0 isa PBXBuildFile settings @@ -9704,25 +9160,58 @@ - C7F82F3525440A2409D8442F2AEE6EB7 + C759D8EE6C549CDFC482E9379D31EFB9 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - UIControl+RACSignalSupport.h + RACCompoundDisposableProvider.d path - ReactiveCocoa/UIControl+RACSignalSupport.h + ReactiveCocoa/RACCompoundDisposableProvider.d sourceTree <group> - C8F81A30A1484015DEE5D84613C982B2 + C79FC6CC148CF1C28E074AC79C0FC2DD + + fileRef + FF978E1C2AC89DC8FC0A9A10FB55C648 + isa + PBXBuildFile + + C7A1E2FAAB3E8C87F4662C50E1ECE8A4 + + fileRef + 4E0768EF582C32EC850A977B2BD5B80A + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + C7ACDDE36465ACAF629FEC233B1BF172 + + fileRef + E9A8C6608F60B3951DDFC8B2903D0603 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + C7CA239660C182F0D322D7C4F975BE91 fileRef - 4BFF8DADBD1721BF5461F26BCA2F1E87 + 299011B619A00EBC8E4017C8C65D5AE0 isa PBXBuildFile settings @@ -9733,52 +9222,197 @@ - C912F1BE0FB8E0D9CE75EA8F718EA45E + C932015425BD500D4A6083DB0623EC64 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFURLResponseSerialization.h + RACEmptySignal.m path - AFNetworking/AFURLResponseSerialization.h + ReactiveCocoa/RACEmptySignal.m sourceTree <group> - C93F8E93788AD6B216F8D684EEDB9FA7 + C93B1E549DCB759BA26517CF8ABE4C4F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSObject+RACSelectorSignal.h + MASConstraint.m path - ReactiveCocoa/NSObject+RACSelectorSignal.h + Masonry/MASConstraint.m sourceTree <group> - C954A8FAAF2F7A10B18F3F926D51557A + C993A0F96A6FAAEF55798FAB1E3D894C - includeInIndex - 1 + children + + B162F15944278B58E9A5C9E1959A2601 + 3870E4A9BA248AFE88604FFA4A61195A + 9AB97AF7B67492F6587E29623D14D2A0 + 99B18091467DC619CAAB11E060AC1121 + 080756BFAF462006CA1CB97A3EA1D7AA + 14AD4534447CBC236698A31895D401F2 + 8870896F8AE8D1DA8EB01CBED4AC1C58 + 0BE788C3CB3F7E78E23D1D390D939DAB + AD4AA56235609BBDEF9FD234D26DFD1E + 143CDB1E69B14E49CA034A39F5194687 + 2CBA7A14A1C2AF1E22C50E6CE482BD55 + CD00BA036E9C58CB9D3ECC5375F367C7 + 44877DC0490619A24BD20531F6A0A5DE + 23530EDB822FDDE0339E09D976220909 + 8EFCDE6DA263A175B2A6E96E943D1416 + 9BEC7C577BD7C1695F7C1C594202AF22 + 861D072B1AC17B39839086655FC21DB9 + BC124DA3E0AD75608C3477374BEBC17C + 9ED632B427AC3FAECB45343B6F534A01 + 1FC894FF194E4D3E40ADFB0D919A52B9 + C421FE4B29E3C5DBCDE764368D0C474F + 0AFD697C1D3464E6DD2AB0D8CCAEF042 + 75FC5A679675C9B89843197C7D3171C5 + 3F71D2177669333731E820865DA2D231 + 8186776A47C9D6ED6108AB91550A0989 + 9D89814A5FE0AD9B4433D95DD47A1C52 + 0D47C7A5E1BF67CDDE0D3DED4C2BF6C4 + 94DFBADA302CB79810621D9C521AC4C0 + 35C9733730903336A1E774698B6C7C4E + 083BA6BFEB763C731F02688780A11EB3 + 46D65F7EB6FBC2C765A3D74191A5444B + 295D6E1DBF9FAA857725CE5884BDEC83 + 22D08E3648451771043636DD7DEEE284 + B05A64156A3417B7CC4E3AF35C82A680 + B261D888D53B9D2390374ECFEC786B9B + 9C054D2305C720C0B99D1D5A7727F489 + 993BAA0FDA7062280D3005B655BC8388 + CED3AC0CA2AA60DFE9D320BCDEC5B657 + 273AFE3662E49F40E4CF533147A8403B + 01F159ED6F5F238200CF3F0B936808FC + E0A47213FE70FB695C6C933410638AF3 + A594D67EE669883807FBCA765E8B552D + BDBF54DA40B41A16762C4A4C5A0C8781 + 681E3A5D090DDD7CBE298EC8851D4D12 + E60362B62BC4A2E7872BD7F400EF400F + 1D47ED097A3DAD61C001D6FD5485D3B6 + C39AF15B4BFC1DD927679F15E9C317F3 + 9A61F1BB44876994F5F53372B82B11C3 + 0483E8EC03F94EB38AE44D540D1103FD + 82E7AC6E1DD676A02A27FA9E194066B0 + 5E57C78F83934D86D9A5171C30083D59 + 92FEFBB1C20F0AAD1BC09DB2CC06F396 + DCAF00830DD6C09D6D61A9C1199CA0CE + 9BBA8775E91B0040A8C8A4656D2129FA + C759D8EE6C549CDFC482E9379D31EFB9 + 2907BD39C74E60F0FDD942123AF9D143 + 4CF65A701B1BE85EC147610D641309B5 + BE1F430ADF45E969576002079ED2FD3C + 1E094BB001BC4B8DD6D3B8692B0D28C0 + 41E2651FF81F50331945FCCFD83DC429 + 3D8613FB9057E6157DB1D60E10E98E08 + EAFD9C93CC8085D2F07483DAD42AB781 + 4E88B7E7DCA9967A4633781A315EC83B + 0EB8B30A1CC6330B08C57D41E2B7133F + BAFCA3FA18B85A757257C7522C957A2B + 299011B619A00EBC8E4017C8C65D5AE0 + DA3EBE76BCED4F93B80D6CC8A394C7B2 + A3BB933DADD14CB8DBD473EC6BF17EDC + C932015425BD500D4A6083DB0623EC64 + 02B2F23E74F8BEB386D7563F64C1F808 + 0ABC93F6575931ED410C56908FE082AF + 749BF5902E6E6891EF6ADC8A272817EC + 676BECC6AE0171F9136A69F624DEB759 + 5159B129DE1BC211151FDE6DE1D2B6CA + 30A2D35F0E883F713C2AEB4AF8A47637 + 9662B978A2BF20CC4D967B3E90515DFC + A4BB0C7EADFAD6A1DD1BE9EC3DF0C0A3 + A565A9CD7A9918942D221C5F1F513775 + AB2602C596347CDA82E4E4BE36223D64 + 0190945F9BF1EAB8CD7279A26AC7BCAD + DCF1F57D0E6D06F4AC3305BF54A14BAF + B4F41B4CFA0893909AE4431681F368D5 + EF3011E738122A0A380DCA81ECB7D10A + 819F984CC9898B5312ECF9E98583F654 + B57830D98B2849080842A747C6F88DA7 + 249B69A2A3999EA1D14701B0FAAEB5EC + 997C4C3399F300AD66818E3A4C6D84EB + 84C7FB4EDD986892F01177AECEB92FD1 + 03306FD17D5572A086255ECDAC692D0D + CDAE64017A222509F608FA2BF5581A14 + 4E0768EF582C32EC850A977B2BD5B80A + B54AD408F1721A01D775611A2BB31C2A + A7F2287F2AE2FDF73582111450DFC9A3 + 95B5A6B242676F67C65EFF220348ACAE + 36916CF5DA1FE373970D2D502ED8C866 + DBDDA6567FA3773567DBA87ADDC396BB + 632EBDB3CCB54217F760522A809A4EF6 + 502F02902D12F7F70B598E370585A968 + 14D765B9A42437B82B77A38E5B9E8D4B + 153E3A7DEF14D7E494AFFA6073638EB6 + A351C49D0B7B5368D708075E1B790F7B + A18A8E90AA1D35FF9E94ADA176B10A5E + C64BCDC42B81D042946E04636B106880 + 68549E42677EBBF9FE7FDD396A1BC2B3 + 14EE2BB2C6D784A106FF1D168C1FD25D + D64F7F3D1B9EB1ADD9DC50F6853A9EEF + AE4F977AC92FF4C9A2655E4EA0803C87 + 29F4E625003F95F249CAE42723A20CFC + 08183933167568F2C8781986F3FB112E + ED7D2955A29AA5EF791E7EE4B001F536 + 75BD3BC18F7C32C1E34AD675CBF9745C + 9A84EA35F2D3E77AC5001D80E576C6B4 + D720F77CD503831B331597B657E86F13 + 546043D08C492E3C07CDE69F0C33381C + 711BF74F0676B87A2838048351DE2206 + FF978E1C2AC89DC8FC0A9A10FB55C648 + B563B9616A97A1BA104410BAC9A46D70 + 9E55B4F4BC7D691EF9EC345F4D64C441 + 74688FDEAD67A2999F1D34587BF6CC1D + 1A6F5266C23C619C54C0477DFE7283AB + 56D2E074E8876B140C4BC52247941163 + 7CD30ED4BF2E42E61802AA7A7FCCA86D + D5B6E64B7D12380EAD3FE18643DB1AF6 + 684B248578D78367990650D36F7F710B + C9B1003A73D6910F6BA17F3C45B5D5A8 + 3D5E45149CD961B9BE684964D8BBEA84 + F221452B1B1DB6A6CCF5BD5EE23ABA54 + 859BD9C09F91D1B505846B7FDE8323BA + 342B293E2F15B3DF835525E4183DAA8F + 78EE318D7701BC658F2ABDA07708B7C0 + 7EECED4464BFD6C89FDB21CC4B759B0C + 37A576FA7C2A130D99739CBAA80BAED9 + 8FEA57F71D7521DFC5241AA6617499DE + E37E92E243FD74EE0405FD37AEB53427 + 7312D5806639AF8561995B0A9F0C6672 + D9A184DCB54CBAF2585073657BF85DA2 + 53D81312E4A85A6CFB6C3C06D619A81F + 30C5085BB18CAB3AC2BF72421A1920E9 + 7A6BC89400594DE9E000159B75A95DD3 + 5B13BC93E7096A8DFC3B2CA65F53D280 + C9D5B5CB412625215188D92B7A7383C6 + D09AEC9BB3FEF6DE69C518EBB750C0CE + 9E05D3F78600BEB3A30E851F7FA55B3F + 3D70BB8CA5FDEB02564B76BC77F516B8 + 407E04979D0276E5B91DC610CD6BACF7 + EDEE2194BAD340B988C97C63499C622E + 7A4C14BBA7CAC02D27A295C3CA226CF1 + 0E07CAC8A5C9858E30FF5E9AED1BD6AB + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - MASViewAttribute.m - path - Masonry/MASViewAttribute.m + Core sourceTree <group> - C9AE24C328D4A75275E3BD6C16C5A145 + C9B1003A73D6910F6BA17F3C45B5D5A8 includeInIndex 1 @@ -9787,13 +9421,13 @@ lastKnownFileType sourcecode.c.h name - RACScheduler+Private.h + RACSubject.h path - ReactiveCocoa/RACScheduler+Private.h + ReactiveCocoa/RACSubject.h sourceTree <group> - C9E88E1C6561A96D7C24E59993CA1296 + C9C6FB489BC99A38D3135EAB9F90F8F0 includeInIndex 1 @@ -9802,42 +9436,69 @@ lastKnownFileType sourcecode.c.h name - JPEngine.h + XAExtObjcMetamacros.h path - JSPatch/JPEngine.h + XAspect/Macros/XAExtObjcMetamacros.h sourceTree <group> - CA00DB45EEB83A2CC6ED12AD89126EB1 + C9D4DC0DB0726C68ACDA91FA18A64E7E + + fileRef + 5C75502C38CBAEFC2F76A453F740ADDD + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + C9D5B5CB412625215188D92B7A7383C6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACmetamacros.h + RACTupleSequence.m path - ReactiveCocoa/extobjc/RACmetamacros.h + ReactiveCocoa/RACTupleSequence.m sourceTree <group> - CAA0F8074B35A2F73890310EC4521A0D + CA9A3CC7011661524DF55E8069E2D4CC - fileRef - 42AA6E2A1E2F248A8025078B457ADE4F + buildActionMask + 2147483647 + files + + B7B46BA3170AB38B02FB2D5F33476BF8 + 3EE979D8676CD634215E3B57AE205BF8 + 78B4B0ED9E5D576E2CC167B19E15E2C4 + DABEE575E43A9097279607616AC05BDD + F4C5F5DA17E3869B0B9AF799DED6AD0F + 92A346DDE83BD2A9B2D1F3A51C5CC7BE + 2D551CABFBF39AAF69CDA0EF999D0E18 + C9D4DC0DB0726C68ACDA91FA18A64E7E + isa - PBXBuildFile + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - CB167AEAF1AF4CCF87533BE624FA0313 + CAA0F8074B35A2F73890310EC4521A0D fileRef - 76284515223FB7A04FEFF4D49AF1E1D2 + ECAAF2C7B7412B87A7732C9C164836F8 isa PBXBuildFile - CBB902BE9B2970A11479B4A17CF73B1C + CAEE1C9E82CCA7640A2F796D31EFE435 includeInIndex 1 @@ -9846,69 +9507,118 @@ lastKnownFileType sourcecode.c.objc name - RACTuple.m + AFHTTPRequestOperation.m path - ReactiveCocoa/RACTuple.m + AFNetworking/AFHTTPRequestOperation.m sourceTree <group> - CC2EF386E6EB31FC9BC5D90FD15B70B1 + CAFC9C069CD9CEF94C741C52BF7C155D + + fileRef + E798802252FBC085207B7EF5246FD5D4 + isa + PBXBuildFile + + CC26929FDB6C8949BC83255384E31E30 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + UIBarButtonItem+RACCommandSupport.m path - SDWebImage.xcconfig + ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m sourceTree <group> - CC3CDEA4B94B6903CE0614F0A44F85EF - - fileRef - B13C33D0C0315117BBAF70867F7E6C57 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - CC5C270FBF1CEE5E35AE6CD12033ED2D + CD00BA036E9C58CB9D3ECC5375F367C7 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIProgressView+AFNetworking.h + NSIndexSet+RACSequenceAdditions.m path - UIKit+AFNetworking/UIProgressView+AFNetworking.h + ReactiveCocoa/NSIndexSet+RACSequenceAdditions.m + sourceTree + <group> + + CD12C168AC0109196544C25F747EB5FB + + children + + FA2CEE153AF0EBF4A4AB72D050A175F2 + EE76FC3577DCDB4A2C6FF6302EC314BE + DCA45A7F9A436DC2BEDAC0AD26C65BAB + C93B1E549DCB759BA26517CF8ABE4C4F + F2EFF7F54E643FC6C7E72B5372091F26 + 3AA0B279BB40445C34DF9A357B5A9C12 + EB6683FC3260150506801302AD17C926 + 19666C0EDCA9726C17BF976A7F4A32E0 + 3311C026F41413D4A8B6F47D772F5F63 + 206C04450ADF97A54B938ADB00EBBF1F + 596B174E46C0474CE36AEF416A2FAE51 + 5ADC59D09BE50B8B735C967AF50CBE5F + 70725A3D27E3186C99D5E59262792240 + F25D909EB8F45EA1B2792B197BBD58E2 + 41CBE05F873C848A0181E13D315F7FB8 + 7F032C0F9E4566CBAD7B1284E266B421 + A3D2C29F2D61DF4AF12B21F7956B3A8F + 9A6734BD63244CEB683F00F0CBA3B221 + 364B47625B5A6016FD04DF7BC35E31C4 + 319DA3C4AD1CA0D7724534142424E6B5 + 41050362AD1BD1CA52A8EB240377B286 + 6CFD7DC1ED89F875CD7399DB254A722A + A3F71E90C69029CDD15B2D2578518B92 + 5C5A5F9BD67F2AD265A236C4C592107E + 6BED4DDD022C6F6F69A4E108741AB69C + 9CFE728FBC713C74EBC629AD8EECF6C7 + + isa + PBXGroup + name + Masonry + path + Masonry sourceTree <group> - CD1044A204A17CE5F93A1D622654107A + CD1B1D9F29C1568866D360CAE9280B20 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACDynamicSequence.h + JSONModelClassProperty.m path - ReactiveCocoa/RACDynamicSequence.h + JSONModel/JSONModel/JSONModelClassProperty.m sourceTree <group> + CD2366082A94BCCDF499180B3F09427A + + fileRef + C64BCDC42B81D042946E04636B106880 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + CD3C1EABD2FDE02CC4B8D15D740ED83C buildActionMask @@ -9923,7 +9633,7 @@ runOnlyForDeploymentPostprocessing 0 - CD843B00B812E8A0F72FE1FE9734BA27 + CD48F56B0AA64AC67F38F425B82D720B includeInIndex 1 @@ -9932,13 +9642,27 @@ lastKnownFileType sourcecode.c.h name - RACChannel.h + UITextView+RACSignalSupport.h path - ReactiveCocoa/RACChannel.h + ReactiveCocoa/UITextView+RACSignalSupport.h sourceTree <group> - CE01489CD5CF601457B6D2C5D1B00210 + CD602F03A80FCB1A17E67B40847E22C7 + + fileRef + 95B5A6B242676F67C65EFF220348ACAE + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + CDAE64017A222509F608FA2BF5581A14 includeInIndex 1 @@ -9947,37 +9671,89 @@ lastKnownFileType sourcecode.c.h name - RACCompoundDisposable.h + RACmetamacros.h path - ReactiveCocoa/RACCompoundDisposable.h + ReactiveCocoa/extobjc/RACmetamacros.h sourceTree <group> - CE3774003D0ED90A82FC9C28440DCC94 + CDDC6FA3D49D36AB2802BBDEFA5F6229 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - MKAnnotationView+RACSignalSupport.m + UIAlertView+RACSignalSupport.h path - ReactiveCocoa/MKAnnotationView+RACSignalSupport.m + ReactiveCocoa/UIAlertView+RACSignalSupport.h sourceTree <group> - CE84A772E28105B307D4B6A91BF03791 + CDE3EFC66341F11D494C06362FB5F7F0 - buildActionMask - 2147483647 - files + children - 706DD8FF096C234E8CA60A7C2853884B - B2F7F45FDBEC10A913006AA8951AF781 - E945BDD35E1CB29A64A46A30FB726E02 - 2CC4F56F95BAD6706291C68A5E65EE84 + 1CA299BEF0F2B330A92CFE5FD0759F9C + FEC4EF4B8F6EAEA6E2829EE84BC8912A + 059196CADDF986D00738A637A66671BD + 6A382666DCE8BFAE7DFEC59B6C20509E + CDDC6FA3D49D36AB2802BBDEFA5F6229 + AF8C2A5D6D0B444877FEDC80D2FF756B + 24A61D750860359356C16584EF89469C + CC26929FDB6C8949BC83255384E31E30 + FDBBAAAFCF83B7732FCB13B9D0CD9A95 + 721201CF6A2409961E43ECE1DDFC967D + A0A931A92557100FC57CB363E078049A + 69ACA4208C1F51ECCB41C7D2864D303D + B4C7F254D7D19D970B5743C513732CC4 + DE194BEF0D2CD53AFE4B2F0F4C3827EA + 30B546A5FD13E84829437967FBD5FFDF + 4C0437E768B286949A1AF95182161D88 + 561D1F2678923A0D9ECFB84315F1A18F + D3F55C54D57DA8CEDF61A47C1491A1C8 + 6586B4DBB4F7173C33D43A5A81458397 + 671942142A25439F9D7DE7312A1E1C0E + D1689D50FB7C92FF4B0E10234FEDE371 + B048FB3C43D6C6205466CC99604792E3 + 6BA10D4286688F83720041C63E248375 + D7AB68C6607E13DE9B6CCEA4C0724626 + 662AAA15A4707A8339251AA4D47587E5 + 3B705B6A81E85F2054BA5735E280879E + F7AF88794E0B7118A5A846E9DBB7B270 + C70A741FF32DD5926E496F5F15B2AC4A + 6FEE79E9096E50FC8463117C1A92244A + B74EF8B935DF8DB6BDF3B7898A6E959B + 49C02A3B831B982B78163EC10EF0D33E + BAF07965D9BAAAA1592777CA8FC127D8 + 675304FCB27570FCF0FC8E98745ED10C + 0CD13BB1A191EE2C413094C65571B015 + 9721AAD85135FB9BDDBE80BA4D11BF97 + 4B95E10EB54BF9480A8CB857F0170925 + 7A3EE7C0964DB86D3D08DDDF2F1EAF72 + D6C7385C2B2E7DCC766B9AB7B0667CD1 + CD48F56B0AA64AC67F38F425B82D720B + 8C7D8CEB0B69C10DB79CACF33AD1897C + + isa + PBXGroup + name + UI + sourceTree + <group> + + CE84A772E28105B307D4B6A91BF03791 + + buildActionMask + 2147483647 + files + + 706DD8FF096C234E8CA60A7C2853884B + B2F7F45FDBEC10A913006AA8951AF781 + E945BDD35E1CB29A64A46A30FB726E02 + 2CC4F56F95BAD6706291C68A5E65EE84 ABD9C7E4737F28E48833F21BDAF6B477 isa @@ -9985,14 +9761,7 @@ runOnlyForDeploymentPostprocessing 0 - CE9C4D5715C4925FD06419626BFDD626 - - fileRef - 8313FA831D7925C254EBFC2A8EA1AD88 - isa - PBXBuildFile - - CF6EFFA22C3751AB7F978D1903CA7BA8 + CED3AC0CA2AA60DFE9D320BCDEC5B657 includeInIndex 1 @@ -10001,87 +9770,66 @@ lastKnownFileType sourcecode.c.objc name - RACKVOProxy.m + NSString+RACSupport.m path - ReactiveCocoa/RACKVOProxy.m + ReactiveCocoa/NSString+RACSupport.m sourceTree <group> - CF76BF2C0371BD2AB3578F79BC94ADF5 + CF725C0AF421A0B19A687A93D51EE210 children - A8C77BBDC031F4497C55AEC67342E6DD - 5420E11F49B04AED7D232AE9D262AD06 - D15CE21E75F56B084E9EBE19DA225527 + F204284237CD0FEBCA29B587BC2EE11A + 057F7CE354F1F79F8F5A3C146C834B82 + 28D80F8E081C91AF857CB10D6B115758 + 2A1D3F97B2BE40F6F3A8892047D86035 isa PBXGroup name - Support Files - path - ../Target Support Files/Aspects + NSURLSession sourceTree <group> - CF898DCC51D0B128217B1CB345014375 - - fileRef - D95489F071B1051AF42780E607BD9B29 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Private - - - - CFA8A2398FEFAC14A69F9C3AAB3C89D5 + D05C466FB318D96070003E32C3FD0EFD - fileRef - 53C1A4C9F7C64CD396285B361DF3D54F + explicitFileType + archive.ar + includeInIndex + 0 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + name + libSDWebImage.a + path + libSDWebImage.a + sourceTree + BUILT_PRODUCTS_DIR - CFAA5BCCF7A8CD45FA8E2D8E08DDE01D + D070B784EFCA099C141EEAB69FBCC870 fileRef - A4DD75475D1D94904BE126F618F34E42 + 58FB72A327F803DBCC27E14D362FDBEF isa PBXBuildFile - D0115EFEA597359A1B8D1D0C51015C4C + D09AEC9BB3FEF6DE69C518EBB750C0CE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSString+RACSequenceAdditions.m + RACUnarySequence.h path - ReactiveCocoa/NSString+RACSequenceAdditions.m + ReactiveCocoa/RACUnarySequence.h sourceTree <group> - D070B784EFCA099C141EEAB69FBCC870 - - fileRef - 78A05F5CF4D02BC837A4B681217E6AE3 - isa - PBXBuildFile - - D085A13B21A5418702B3BF087E39C0D4 + D0CC9582E84D7B5AE27051053ECA8719 includeInIndex 1 @@ -10090,56 +9838,27 @@ lastKnownFileType sourcecode.c.h name - NSFileHandle+RACSupport.h + AFURLConnectionOperation.h path - ReactiveCocoa/NSFileHandle+RACSupport.h + AFNetworking/AFURLConnectionOperation.h sourceTree <group> - D08EC6096C0C443EF22CD3B38AD34DD0 + D0E43668224843EC3D52533B49477C98 fileRef - D0115EFEA597359A1B8D1D0C51015C4C - isa - PBXBuildFile - - D0938112D63C96C6560926C5C50F4CA6 - - fileRef - 978BA4AFEBBADAD1F2ED5B6FC1297A6F - isa - PBXBuildFile - - D0C47D9B5493D9078FCA5F8E8A1AE4CD - - fileRef - 175855F4E67EE3757EA4DDFBF012D699 + 7CD30ED4BF2E42E61802AA7A7FCCA86D isa PBXBuildFile settings ATTRIBUTES - Public + Private - D0E0EAB42F50A63590B7CDC94C841DA8 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - MASConstraint+Private.h - path - Masonry/MASConstraint+Private.h - sourceTree - <group> - - D128BA5BEE4A598E09EFC2652AE98D2C + D1689D50FB7C92FF4B0E10234FEDE371 includeInIndex 1 @@ -10148,44 +9867,38 @@ lastKnownFileType sourcecode.c.h name - XAFoundation.h + UIImagePickerController+RACSignalSupport.h path - XAspect/Macros/XAFoundation.h + ReactiveCocoa/UIImagePickerController+RACSignalSupport.h sourceTree <group> - D15CE21E75F56B084E9EBE19DA225527 + D1E8639ECA079EC1FE119896243DD478 - includeInIndex - 1 + fileRef + 6A382666DCE8BFAE7DFEC59B6C20509E isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - path - Aspects-prefix.pch - sourceTree - <group> + PBXBuildFile - D178139F0687F97F4F446AE3F33251E1 + D26C82F0149EE994C17E003C3CA3C96C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - MASViewConstraint.h + UIImage+GIF.m path - Masonry/MASViewConstraint.h + SDWebImage/UIImage+GIF.m sourceTree <group> - D1906A0AD640EB43CE6915914B23AC53 + D2718FB5214DA8A524CE735932323F82 fileRef - 5FF2061AAC0FBD245CF04573AA4ADE56 + 5E5FF559E666649849CFF4F8D446629C isa PBXBuildFile settings @@ -10196,33 +9909,27 @@ - D1CE1B16C2DD160F766958C20B339705 + D3A075C816DF5B9D3CAE6AC0B93F2421 - buildActionMask - 2147483647 - files + children - AEBDFAF53661B68583504130E00C7AE9 - FB3F7E75C7BF09EED702375E584C44BE - DCCEFAF43B67E25DA5A8C6C34EC6C3AF - B8E5BEC8B81D972D365B70F7AA8046CA + B65FD05A1FF795BB0A8F5E367367CD3A + E546A797D535F0184D885932D32A6FA5 + 3B8F8E157C7BE1081371F7E5AA5ECFF1 isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - D2374162F96CD29971B4D14B3EADB7C6 - - fileRef - DE2CF928F20C327DA4A335EB22BB2AB1 - isa - PBXBuildFile + PBXGroup + name + Aspects + path + Aspects + sourceTree + <group> - D2718FB5214DA8A524CE735932323F82 + D3AF770B574C46F2B3BD7CF39C587477 fileRef - 017C816C17DB67AE9F6826A6FE13364C + 6FEE79E9096E50FC8463117C1A92244A isa PBXBuildFile settings @@ -10233,72 +9940,28 @@ - D2F49FA6D2AABB104A20852C5E52B01C - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIImageView+AFNetworking.h - path - UIKit+AFNetworking/UIImageView+AFNetworking.h - sourceTree - <group> - - D3B8C337C8BF6B62816B7E7428D90847 + D3D9F12613E23AD64C1FA5F7081A3668 - includeInIndex - 1 + fileRef + 319DA3C4AD1CA0D7724534142424E6B5 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIButton+AFNetworking.h - path - UIKit+AFNetworking/UIButton+AFNetworking.h - sourceTree - <group> + PBXBuildFile - D3C233514075711C6040EA1D4182F48F + D3F55C54D57DA8CEDF61A47C1491A1C8 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFHTTPRequestOperation.h + UIDatePicker+RACSignalSupport.m path - AFNetworking/AFHTTPRequestOperation.h + ReactiveCocoa/UIDatePicker+RACSignalSupport.m sourceTree <group> - D3D9F12613E23AD64C1FA5F7081A3668 - - fileRef - 2540DE235D6AB8FABDEE8086C064476A - isa - PBXBuildFile - - D40351ECDACAA431D087799077D87DF4 - - fileRef - 80D702D144296236010345C7FF6C942F - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - D41D8CD98F00B204E9800998ECF8427E attributes @@ -10325,7 +9988,7 @@ mainGroup 7DB346D0F39D3F0E887471402A8071AB productRefGroup - DB35818992FDC0EF557CED682DEE6AFE + D729A403EF8B197790AB0FCD68642870 projectDirPath projectReferences @@ -10338,33 +10001,32 @@ DBC9A0AF6D4571D059D2AF2422F2BD6E 0C1D89EAE68EF4D4ABEDB611EC44AAB0 09FA060F1A0492FB25232F489AC4E573 - FD1D53461DE538B7C8DFE0B76D857587 53480ED0BE09FF49E34B1702D485CAAB - 37132430457D61938FCD620DE393009A - 4F7ACF1421268A3CDFC9455CABF9A6D5 - 44D882ADFA06DC141944859F300FC170 - B995F6C491CD4491EFFB38B22D432FA4 + 24033AEA24A4232754B0FF455FDFA2E2 + 9A935B6D3AACE527D4DF682DB3C53BDD + 32B858CF09199FB109685F306D190C38 + 898AEA184EF58065EB8EFB5AEA26B508 - D45DBCF012C00712D545E78EA25DDD79 + D42786EB0B73506E279351FA1FCEE0B9 + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.objc name - SDImageCache.m + libCYLTabBarController.a path - SDWebImage/SDImageCache.m + libCYLTabBarController.a sourceTree - <group> + BUILT_PRODUCTS_DIR D4A65C2E29ACB340587FD41196176F8A fileRef - D2F49FA6D2AABB104A20852C5E52B01C + B941BEB290F39685CD1920FE7E9EE280 isa PBXBuildFile settings @@ -10375,7 +10037,14 @@ - D4A8C167B632453BE354070C0F51ABD6 + D4EF11B8928C1374360A67C3BC22AD13 + + fileRef + 336B1E6E8484ECB8832FF08AF4325EBF + isa + PBXBuildFile + + D4FA8C3887E2B0E18FAC76CD493A9DE4 includeInIndex 1 @@ -10384,104 +10053,77 @@ lastKnownFileType sourcecode.c.h name - RACSerialDisposable.h + AFNetworking.h path - ReactiveCocoa/RACSerialDisposable.h + AFNetworking/AFNetworking.h sourceTree <group> - D4DE18E47EB116337574B300EF2DDA9E + D5A53314F0406B315CA0867F8EFCFD33 - fileRef - 7B37AAA08BAC43E0F6C4FF873F7E3273 - isa - PBXBuildFile - settings + baseConfigurationReference + 741BF78A50444622EEC3602E1EBD1DD6 + buildSettings - ATTRIBUTES - - Public - + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/JSONModel/JSONModel-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES - - D4EF11B8928C1374360A67C3BC22AD13 - - fileRef - 5C80CF6C279B57FBE47D8A75882EF395 - isa - PBXBuildFile - - D51C02B6411EFDCED556818C14E6C499 - - fileRef - B42262E7778E726F825B5C16311E64E2 isa - PBXBuildFile - - D583239E3286B94DA3F2CCCAC386E907 - - fileRef - DB2950F7F98988B053479C722B92A536 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + XCBuildConfiguration + name + Debug - D5A3134C9C8FF8D3E667992F788A7878 + D5B6E64B7D12380EAD3FE18643DB1AF6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACKVOTrampoline.m + RACStringSequence.h path - ReactiveCocoa/RACKVOTrampoline.m + ReactiveCocoa/RACStringSequence.h sourceTree <group> - D5A53314F0406B315CA0867F8EFCFD33 + D64F7F3D1B9EB1ADD9DC50F6853A9EEF - baseConfigurationReference - 62025C7C78033BDE974F2B6D80D47C55 - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/JSONModel/JSONModel-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - + includeInIndex + 1 isa - XCBuildConfiguration + PBXFileReference + lastKnownFileType + sourcecode.c.h name - Debug + RACScheduler+Subclass.h + path + ReactiveCocoa/RACScheduler+Subclass.h + sourceTree + <group> - D5ACC55E5D76B8F4D99C462E4E394EA0 + D6C7385C2B2E7DCC766B9AB7B0667CD1 includeInIndex 1 @@ -10490,62 +10132,85 @@ lastKnownFileType sourcecode.c.objc name - RACEmptySignal.m + UITextField+RACSignalSupport.m path - ReactiveCocoa/RACEmptySignal.m + ReactiveCocoa/UITextField+RACSignalSupport.m sourceTree <group> - D6237EEAE81FAC77DC4CDAA075B264E9 - - buildConfigurations - - E8AD59FB2E51C2C0EE83DA2DD0BFFADE - 201CFBF48EDE533E3BAF73E0E64B9FA0 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList - - D68697C739DE55500A7B6FD1FCCF5990 + D720F77CD503831B331597B657E86F13 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + RACSignal.h path - JSPatch.xcconfig + ReactiveCocoa/RACSignal.h + sourceTree + <group> + + D729A403EF8B197790AB0FCD68642870 + + children + + 95425136DDE162827E8835D3A5B2A1D2 + B9C10C63D018D5B487E431124476D073 + D42786EB0B73506E279351FA1FCEE0B9 + 94E3EC661536CD989F7D7BA46681D369 + 8AA007B97AE5CC80ACC692D6E590CFFE + 3D06057B737713403EA64DC89536AA1A + 29E728C49794360ABDC8BBF02D053E99 + D05C466FB318D96070003E32C3FD0EFD + A44A50D0E07C187E301FFE14CE4F76F5 + + isa + PBXGroup + name + Products sourceTree <group> - D6B6C0BAB71F40084CD19007816F5135 + D75A579A255FA3FD070FD33E85C6F24B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACKVOChannel.h + CYLTabBarController.m path - ReactiveCocoa/RACKVOChannel.h + CYLTabBarController/CYLTabBarController.m sourceTree <group> - D7D2F9CC2AD634DAE9D71734596DB2A3 + D793E4294DC014D55F33291B13E780AD + + fileRef + C70A741FF32DD5926E496F5F15B2AC4A + isa + PBXBuildFile + + D7A019D837A9FAF6218EBB1810634FAC fileRef - 659B6927C788554CB763D95DD9F6DB5F + 561D1F2678923A0D9ECFB84315F1A18F isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - D7D7B6198C38BE29584CFDA470A53399 + D7AB68C6607E13DE9B6CCEA4C0724626 includeInIndex 1 @@ -10554,9 +10219,9 @@ lastKnownFileType sourcecode.c.objc name - RACMulticastConnection.m + UIRefreshControl+RACCommandSupport.m path - ReactiveCocoa/RACMulticastConnection.m + ReactiveCocoa/UIRefreshControl+RACCommandSupport.m sourceTree <group> @@ -10574,25 +10239,10 @@ isa XCConfigurationList - D839E838BF47A54E1A485B25A793BDC2 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIImageView+WebCache.h - path - SDWebImage/UIImageView+WebCache.h - sourceTree - <group> - - D8F1A2BEF3DCA1DF604868EC71FEA1D4 + D9985F5CB374D3DFA16483F436C6CED6 fileRef - 21700C06D8FE72A135711E023B3EBC76 + 567A662A94B17F76035960CAC8926339 isa PBXBuildFile settings @@ -10603,7 +10253,7 @@ - D95489F071B1051AF42780E607BD9B29 + D9A184DCB54CBAF2585073657BF85DA2 includeInIndex 1 @@ -10612,65 +10262,93 @@ lastKnownFileType sourcecode.c.h name - RACMulticastConnection+Private.h + RACTestScheduler.h path - ReactiveCocoa/RACMulticastConnection+Private.h + ReactiveCocoa/RACTestScheduler.h sourceTree <group> - D9D358458CED65BE821E001F12A5BAAF + DA02260E9C9DA18939EF3B57CA5D401E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACTestScheduler.m + JSONModelArray.h path - ReactiveCocoa/RACTestScheduler.m + JSONModel/JSONModel/JSONModelArray.h sourceTree <group> - DA0FB964F98DBBB51E94B0A6C3A0AC9A + DA3EBE76BCED4F93B80D6CC8A394C7B2 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACSignal.h + RACEmptySequence.m path - ReactiveCocoa/RACSignal.h + ReactiveCocoa/RACEmptySequence.m sourceTree <group> - DA848D003DF56A71D62834E0CCFB76F1 + DAB25E48FD64C97812C36A5B69F837E3 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - libMasonry.a + UIImage+MultiFormat.m path - libMasonry.a + SDWebImage/UIImage+MultiFormat.m sourceTree - BUILT_PRODUCTS_DIR + <group> + + DABEE575E43A9097279607616AC05BDD + + fileRef + C9C6FB489BC99A38D3135EAB9F90F8F0 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - DAA089651531F65F35B37A3D17DF641D + DB2E92A71137AD2E6993E8B0CE682C89 + + fileRef + D0CC9582E84D7B5AE27051053ECA8719 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + DB42C604EF2F39D542F805AC6A05E090 fileRef - 16A3E780C0937600C7C09D0DB3CCBD34 + 375AE8DDF76E5AEE2565EDAB8B8FC134 isa PBXBuildFile - DB2950F7F98988B053479C722B92A536 + DB88B0D560024D1484A08A232F03F53A includeInIndex 1 @@ -10679,16 +10357,16 @@ lastKnownFileType sourcecode.c.h name - RACPassthroughSubscriber.h + UIImageView+WebCache.h path - ReactiveCocoa/RACPassthroughSubscriber.h + SDWebImage/UIImageView+WebCache.h sourceTree <group> - DB2E92A71137AD2E6993E8B0CE682C89 + DBB5DF22BCB4A481B9015D798A013CAC fileRef - 30D377C733F30186EA2D73B73E56E053 + BDBF54DA40B41A16762C4A4C5A0C8781 isa PBXBuildFile settings @@ -10699,34 +10377,48 @@ - DB35818992FDC0EF557CED682DEE6AFE + DBB7FF057A3318B501E048A372AED490 children - 6AC09D1314CA9AA3CDF4938347A11233 - 029945DE96FA76F2D1D65517B3C6C838 - 0B6C5B152C38204C10136BCEB05D3EEA - 0916C4FA894AA91746D3CD3ECBBCD738 - 5F6D57308FA578FEA1CA7A71481B91CA - DA848D003DF56A71D62834E0CCFB76F1 - 94A83BD33AFCDC59F41573552F1D6EB7 - 4D1ABF333E068D7241F4565EA3D3D04E - 2577EAA643A58B7C32375D37068F9D3B - 63958894F8A2B30EC7DC43706ED1A1CA + E415AED7CAC955A983D0A35E8D8F11EF + C3E17119C9E2A1300F7B36A35F1AAD66 isa PBXGroup name - Products + GTSDK + path + GTSDK sourceTree <group> - DB42C604EF2F39D542F805AC6A05E090 + DBBE26BB77A044E5F7DDE107F6D3B655 - fileRef - 375AE8DDF76E5AEE2565EDAB8B8FC134 + buildActionMask + 2147483647 + files + + 4C8D561215C600D35D8DA7FAF3B73BAF + E06E63C50E3D20C358907964924DD991 + 1F61AF68D4FB00039F02EC30594AD211 + 1AA9B819449D239EA31ECFF6ECA1657C + A6EA3EF30ED4BF71BDF6673EC96F2B4B + 66E55C0B562121517F4002078C2657EA + 9FF01B0CCE7632491EA40CE567821790 + F2E245B306BFA9016D866687173C0510 + 95FF7E5BE776C8B96D4D4E6F5999820C + 1D264E71F9CE1566934BD1E66B808EB5 + DDA028E596654F0D008B8F90580034F4 + 382C10F59BDBD1E36CCD0768F5C3B087 + FDB2E620B5F227C5BCD594019FFE39F4 + 2FC06DD1461305DDFBAD5D3E9005BEF6 + 9779286FFE4DABF539E1B6D24816136C + isa - PBXBuildFile + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 DBC9A0AF6D4571D059D2AF2422F2BD6E @@ -10749,10 +10441,25 @@ productName Aspects productReference - 029945DE96FA76F2D1D65517B3C6C838 + B9C10C63D018D5B487E431124476D073 productType com.apple.product-type.library.static + DBDDA6567FA3773567DBA87ADDC396BB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACQueueScheduler.h + path + ReactiveCocoa/RACQueueScheduler.h + sourceTree + <group> + DC8579C657135E3C32AB580A48C6D524 buildActionMask @@ -10776,10 +10483,40 @@ runOnlyForDeploymentPostprocessing 0 + DCA45A7F9A436DC2BEDAC0AD26C65BAB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MASConstraint.h + path + Masonry/MASConstraint.h + sourceTree + <group> + + DCAF00830DD6C09D6D61A9C1199CA0CE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACCompoundDisposable.h + path + ReactiveCocoa/RACCompoundDisposable.h + sourceTree + <group> + DCB74D72FE0E9C8C8E23B49C8CE52276 fileRef - 69CC3D71377DFD142B605B31539E917D + BF48CE6E9B022C722DF102F52A931AFF isa PBXBuildFile settings @@ -10788,17 +10525,25 @@ -DOS_OBJECT_USE_OBJC=0 - DCCEFAF43B67E25DA5A8C6C34EC6C3AF + DCF1F57D0E6D06F4AC3305BF54A14BAF - fileRef - 734BEF397C9DA28B4B2D333301B13D20 - isa - PBXBuildFile + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACImmediateScheduler.m + path + ReactiveCocoa/RACImmediateScheduler.m + sourceTree + <group> DD1F717B0527C71229B3339324E35E55 fileRef - 764F684BDBDE99D982727FDAACEF4E56 + 41050362AD1BD1CA52A8EB240377B286 isa PBXBuildFile settings @@ -10809,28 +10554,46 @@ - DD618B07C2697365A5F160EE23051DD3 + DD26E7CE35356848D36F859800E4EC2C - fileRef - 243C8D42E812E7176AD1B8E1922F13F0 + buildActionMask + 2147483647 + files + + 9B67E3B325A1A44DCF58EFE8AE9CB0B1 + D9985F5CB374D3DFA16483F436C6CED6 + 9F350145B972381A96FD71D13547412B + BBB5BFA88D37F2C6701759401517FC2D + EDC030DEF6CB1478AEA2DA12F4A38A37 + 4F0CE6C217097838A813CBEB0BC26AC5 + FAFE589A1BCB942F30C11B6D71A9FEDF + FA819734BAD3D8CF6B68DF8D5E230C2A + 668796CCFC4D513A16AF9E665E8613B2 + 8BDC0C656DCAA4376CB051A92C444366 + 1281F232FEDBF2EA9B3C6B58A83A39AF + B42C86C6EA29770EC0AC436082B2438A + 4FA81B7382912B7432A92DB6F953724B + E9C61BB3628EDC46285667E087566E2B + 45DC8A4074CB9B15EE75825B8EC4325F + isa - PBXBuildFile + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - DD66D5E4E2B231622D52276A052755BE + DDA028E596654F0D008B8F90580034F4 fileRef - 23379D081E9ABB25B5C2841C3732BE3C + D26C82F0149EE994C17E003C3CA3C96C isa PBXBuildFile settings - ATTRIBUTES - - Public - + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - DE2CF928F20C327DA4A335EB22BB2AB1 + DE194BEF0D2CD53AFE4B2F0F4C3827EA includeInIndex 1 @@ -10839,16 +10602,16 @@ lastKnownFileType sourcecode.c.objc name - RACEvent.m + UIControl+RACSignalSupport.m path - ReactiveCocoa/RACEvent.m + ReactiveCocoa/UIControl+RACSignalSupport.m sourceTree <group> DECD5915774351B8473476B041DD87D7 fileRef - 1F50540DA7E31473386BCD577392B993 + F204284237CD0FEBCA29B587BC2EE11A isa PBXBuildFile settings @@ -10859,20 +10622,7 @@ - DF49020A45AAD83B73F2B3E4BD4DB040 - - buildActionMask - 2147483647 - files - - 12B17C4E95BBF046F7AEA9604E00D203 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - E0291E4ED72C93C2ABD2C1EA896D6261 + DFA572E19AAB833058879FFCB2542CAB includeInIndex 1 @@ -10881,13 +10631,25 @@ lastKnownFileType sourcecode.c.objc name - UIButton+AFNetworking.m + SDImageCache.m path - UIKit+AFNetworking/UIButton+AFNetworking.m + SDWebImage/SDImageCache.m sourceTree <group> - E0C332A92E8CD15A40F2CEA81ADEA5B3 + E06E63C50E3D20C358907964924DD991 + + fileRef + DFA572E19AAB833058879FFCB2542CAB + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + E0A47213FE70FB695C6C933410638AF3 includeInIndex 1 @@ -10896,54 +10658,57 @@ lastKnownFileType sourcecode.c.h name - RACEagerSequence.h + NSUserDefaults+RACSupport.h path - ReactiveCocoa/RACEagerSequence.h + ReactiveCocoa/NSUserDefaults+RACSupport.h sourceTree <group> - E0D44EA2CA43A535F084E48871AFF74C + E0BF109179C0DCCF7E11BF91E9968783 fileRef - 5420E11F49B04AED7D232AE9D262AD06 + 08183933167568F2C8781986F3FB112E isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - E1567B114544F0E220C2D236D3A47E82 + E0D44EA2CA43A535F084E48871AFF74C - children - - C020DA99B6AD309040A6C00ECBA4EE19 - FF75C273E835D9600B1264CC1FA3320F - 3DADB29339AC082A3B5F6C32092EF483 - + fileRef + C653B6CB5FCB8B5E170D0E8577D5FCA2 isa - PBXGroup - name - Support Files - path - ../Target Support Files/CYLTabBarController - sourceTree - <group> + PBXBuildFile - E182FAEF2027E3CE1000307AE23CD5C3 + E0DAC7BBE8380A84DDBE5F0C27113D7E fileRef - 65885D26E021BDBB24AA0FD2FFF56189 + 14AD4534447CBC236698A31895D401F2 isa PBXBuildFile - E249E933AF2AC413228EB267386BA7DC + E208C9A0257BF2A6BBCCC4D15C3B125F - fileRef - CBB902BE9B2970A11479B4A17CF73B1C + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + SDWebImage-prefix.pch + sourceTree + <group> - E317BE629C3618780960E1E95F206B06 + E2711D48FE646C1F092908689D43A73E fileRef - A7315DC7E23C786CCF26DCCDECE98C45 + D64F7F3D1B9EB1ADD9DC50F6853A9EEF isa PBXBuildFile settings @@ -10954,35 +10719,62 @@ - E368EA7D0BE0C0B2133A5F5BFC232329 + E37E92E243FD74EE0405FD37AEB53427 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACTargetQueueScheduler.h + path + ReactiveCocoa/RACTargetQueueScheduler.h + sourceTree + <group> + + E390C23E48599B65AFF2A0B428CACCCA + + containerPortal + D41D8CD98F00B204E9800998ECF8427E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 898AEA184EF58065EB8EFB5AEA26B508 + remoteInfo + XAspect + + E3A57EA96D434DBF5A92DEC7DDE92661 fileRef - 563CABE8034F56611588FFFEA8122352 + D7AB68C6607E13DE9B6CCEA4C0724626 isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - E3C50525D0EAEA67317369A02774E83E + E415AED7CAC955A983D0A35E8D8F11EF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + GeTuiSdk.h + sourceTree + <group> + + E5175713ED35FC59D38CB29379E16018 fileRef - 4E0FFAB1DBFDD2724BA8FA304BD72F01 + A18A8E90AA1D35FF9E94ADA176B10A5E isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - E4FFFF5E9D9955E4515CDFBD7A7CD4CF + E546A797D535F0184D885932D32A6FA5 includeInIndex 1 @@ -10990,14 +10782,26 @@ PBXFileReference lastKnownFileType sourcecode.c.objc - name - ViewController+MASAdditions.m path - Masonry/ViewController+MASAdditions.m + Aspects.m + sourceTree + <group> + + E558DB829F044906CCC96EE0CE60336F + + children + + 84FA53805A65251FC0CAB19D0585B085 + 92D2A49D15CEE5164F48E38340AD32AA + + isa + PBXGroup + name + Reachability sourceTree <group> - E5AE29ED4BEFE8DAB244B278DDBC06CE + E60362B62BC4A2E7872BD7F400EF400F includeInIndex 1 @@ -11006,27 +10810,34 @@ lastKnownFileType sourcecode.c.h name - RACScheduler.h + RACBehaviorSubject.h path - ReactiveCocoa/RACScheduler.h + ReactiveCocoa/RACBehaviorSubject.h sourceTree <group> - E6B49FBCE3957DB67F691ACCC4CAF4BE + E6689D7C50A50E004D66ADE32971AF81 fileRef - F66B78D4B47EE859EC50E73C16837FC7 + 502F02902D12F7F70B598E370585A968 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + - E6DD6ABB4FC13B60FA54C950FB6B262B + E6B49FBCE3957DB67F691ACCC4CAF4BE fileRef - 0D21AF65FBED97A433B38D6666F40AAA + 41CBE05F873C848A0181E13D315F7FB8 isa PBXBuildFile - E6EF7EE978A5191A9BB4FC5BDE0D60CC + E6CA760B5394495E519115B0AB6C3DD9 includeInIndex 1 @@ -11035,12 +10846,137 @@ lastKnownFileType sourcecode.c.objc name - CYLTabBar.m + SDWebImageDownloader.m path - CYLTabBarController/CYLTabBar.m + SDWebImage/SDWebImageDownloader.m sourceTree <group> + E6DD6ABB4FC13B60FA54C950FB6B262B + + fileRef + 13589ACA22C4AED47051D9D4FE80F76F + isa + PBXBuildFile + + E713967A6600947084C4D66D3375C696 + + buildActionMask + 2147483647 + files + + 4BF97AA932B32DD81BD7DBD33CE76F27 + A859E1AA4C4E3FE0653C98080FD4B758 + 4FE7D89FE522F656FF6D8BD5B2D752B9 + E0DAC7BBE8380A84DDBE5F0C27113D7E + 8505AC4941A9B561D847933B53664111 + A5C1035E8D6E58A45460F5B2CD955353 + 6295F5F4E67533BFB194EF1AAF8E8B08 + FD83741DFCC987B6F8C39356881215B2 + F3C65640A1A19944099A1A64337C26BC + 97138795855F6D9F51924BE978A8BE80 + 9EDAD693C9217384E635AF76CF37F923 + EE452DB7731E48F1D2F70775FA697235 + C4EA856651212F3B9A77D3EA4C6EC0C8 + F396D650E1CF38B91227646DF6E0FB42 + 072DBFB47B1B2723FC4055B85A65F9B9 + 6E3C0A6DD3A355BCDB7308E8DAF5BBBC + 647B51417A1660D36E7FAE3CB2A38F36 + 3F1A0CF4FA7F08FCA2A63E3C872EAF50 + 46F4CB5B2D448A9DDF96CF039D108E8F + A4763E22F94FAA131C037ED0B6A1C59B + 5B6200D0F58FB8FC92A2A28A3D699336 + 7E5F1915B3A4DA3F809619F72949F326 + 80FEFD0365FE84022A1A34BDEEC4CAC1 + B13972E4A1736403D94A273BA539CFED + 96F8C5242F337D002F64184A01C4E651 + 770AB12294B26508E28247BEC572575A + 4337EAADB137537429211C3878012386 + 600D5E33B16CAFA6B4D014105B16A468 + 685E945BBC662FF58B7BBD7398B679F4 + 061105E57BB9E3E753AE0AF47837A809 + 08AE94CCA410E8277B7818D0EFAE4965 + 95E74A7FAB761D5592681007955A376A + 68F43AA8292D8A77222F96E23757EBB0 + AE0606BF4AC02591B760F465EB8EDB9A + BA8E5F31353D2182B8BD558BD832C34D + 9838593D1811293CE2C175BCF4CD9448 + C6446B6E15442B15106D49DC60183D1B + EB6C7E7A690B504E157E1AF6BD0C62FB + 1DC03790E6AB0AB5E040AE2B14363821 + B7B7374AE3A5C59A4FC6FB14EAFA0BED + 39372248B74BC3AF21AB234E0838B3BC + 7637FB30274DC6B03009AA159CE0A71B + E8E214212330188F8AF266A886BC4614 + 4FEA23AC659B8A10AA41CD9E405DA4E9 + 216363526676D0071143855BB8AB1A57 + 6D5E390D425D49D2FA0F9AEA0203B94E + AF60285AA341AD6671EC96486117A816 + B70A62D71CABE0042AD3B3FD69CE0B8D + 517FDB0BCAF1A6CF990B2AD5A6649613 + AC9180896C090E0ED47E761151004746 + E5175713ED35FC59D38CB29379E16018 + F35BFD40F018DC9A6C68106905F7FB4F + F34DB16B800EB0652AFCF75741F60EF1 + 7EBD5076B9B45389A3EA4F80DDB7527D + 7693BDEA465D6C29949FE81042B49EA0 + C79FC6CC148CF1C28E074AC79C0FC2DD + 9D41E9863C4F1DF2F07A5C5822C7D95A + 7368F13141E5B9ADAD8D6E9BDCB90984 + F2AC96AA9678F8D13A7638DA178B53CD + 07D3EEF4536A328E668F3376FE2BE336 + 50B553DCB7DBF5C22B2AD520174C367B + FDDA23E0C00FC0952BB9A01A3F25ACC4 + 8FB794921D2D71380A2A0C0935D26E39 + 372DA6BA104FB86618A05E951C75A497 + B406B28EA904ABBFF12E70F383AF3832 + 8F1189C505527A9BA74E0CFFCD5092C6 + 01E291E9D7F510001EF8E0F51C467C31 + BB94D5A50591219B66748B72795E43F3 + 2F0339239226224B0EBE362FBEC90A24 + AF59ACE080C0107D3AE7C9A885BB49F5 + 7DA510557E0ACF4EA57AC39B20BB825C + 9D5C4AB2353A5952E3441F5A73C640C4 + 643A819CF4BA2FDDC598F64874E3ECFF + D1E8639ECA079EC1FE119896243DD478 + A92E430F81BAEF7F14785C0EBA549E75 + 3E3E6AB4703E2F1384E6623B7E3A922F + 86089ED3EBD01B3EE5D9AE7BB8365562 + 1EE384BB828F1AE595D89DC73174B403 + A96604F8EA6B9136A073E2DA05A29653 + 505A5567D1C7B697572D7905A96F79DC + FDA6B6E0FFABF3BCF80518597408E23E + 531A0F2EDCCFD0F3B47BCD17DB5C5F85 + 15DA087E1E156C6B1655764224E69941 + E3A57EA96D434DBF5A92DEC7DDE92661 + 8CCEC11DC188344B9433D786020A2620 + D793E4294DC014D55F33291B13E780AD + FA8BEFD2A3B858DC7840C3B8B2916A42 + 9CFBD27D336D1336CEF4F9C6F04A962F + 5E5BDE19D3FDF21E91EB1F315B0F88C2 + 86645448CC1E9477B8386BF0757F0896 + 70155E0155171E5488D76943F2A0E0C5 + 85E0615CAA269DD2D96AD52457D06D77 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + E77493C63D3D9AE7391F2487AB3287E8 + + fileRef + 37A576FA7C2A130D99739CBAA80BAED9 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + E798802252FBC085207B7EF5246FD5D4 isa @@ -11054,35 +10990,34 @@ sourceTree DEVELOPER_DIR - E7B66D448FF3C7D3F5B049918A9BED7B + E7EA101BDD489A4BED3B8F0F4066EC17 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - CYLConstants.h + JSONHTTPClient.m path - CYLTabBarController/CYLConstants.h + JSONModel/JSONModelNetworking/JSONHTTPClient.m sourceTree <group> - E7EDDB3648C282ABFA2F062CAD66BB26 + E81F41420E62D41FCEE540A57838396E - includeInIndex - 1 + buildActionMask + 2147483647 + files + + 2F3459930FBF7274B61EE83899FC5703 + 408EA800BDFEB248F45E5F5E1AF8DFE7 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACDisposable.h - path - ReactiveCocoa/RACDisposable.h - sourceTree - <group> + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 E8396AAECA7B0061597C8C1AB72E27FE @@ -11097,78 +11032,21 @@ runOnlyForDeploymentPostprocessing 0 - E8AD59FB2E51C2C0EE83DA2DD0BFFADE + E8E214212330188F8AF266A886BC4614 - baseConfigurationReference - D68697C739DE55500A7B6FD1FCCF5990 - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/JSPatch/JSPatch-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - - isa - XCBuildConfiguration - name - Debug - - E8D42D390C04E2635A464E5D2250089E - - children - - 76B7C27071A6D22260FC2A2585F070BD - B32C2D35515F69C3DF162EF759489EEE - C2020C1EB46409061C8BB7DF0E703EC9 - F9CA04A1AC1A5119C264BFE9667EE809 - B95B6BF4B263D0E9857C5CE00A3DB020 - F66268E5D5382C35C98197F3C4D51B98 - D3B8C337C8BF6B62816B7E7428D90847 - E0291E4ED72C93C2ABD2C1EA896D6261 - 3D3FBF048AAC09B00D8CE7E148CABAEC - D2F49FA6D2AABB104A20852C5E52B01C - 78A05F5CF4D02BC837A4B681217E6AE3 - 589EBB3F3E6E3A6A611453A4DD915ED5 - CC5C270FBF1CEE5E35AE6CD12033ED2D - ED99CEB724EB1A8CC658C31253E21BC4 - 8FF4ACBA69C04C52C770DBB4AAA0F442 - 3D661D03876F28D3286AE89027F93039 - 840426794A49EC536ABBD91C1E41D0A2 - B69F9892BE1074EA541607EE65E96594 - + fileRef + B57830D98B2849080842A747C6F88DA7 isa - PBXGroup - name - UIKit - sourceTree - <group> + PBXBuildFile - E90FE89EDA2F001944637A7C456AF004 + E945BDD35E1CB29A64A46A30FB726E02 fileRef - 50664F7E572B80CBF4E6FC9A827360A3 + 67B8D1029C75C73F1643114628229333 isa PBXBuildFile - E91C9516CFEAF53AA8B50A9B9F11B275 + E9A8C6608F60B3951DDFC8B2903D0603 includeInIndex 1 @@ -11177,31 +11055,37 @@ lastKnownFileType sourcecode.c.h name - RACSubject.h + UIProgressView+AFNetworking.h path - ReactiveCocoa/RACSubject.h + UIKit+AFNetworking/UIProgressView+AFNetworking.h sourceTree <group> - E945BDD35E1CB29A64A46A30FB726E02 + E9BADEC7E474ADE375184CB25246C401 - fileRef - FF75C273E835D9600B1264CC1FA3320F + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + text.xcconfig + path + ReactiveCocoa.xcconfig + sourceTree + <group> - E947279877DF8A82CF3C684C9A8D3F6D + E9BC93CF7243043504BABAE792DD43DA includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - RACQueueScheduler.h + AFSecurityPolicy.m path - ReactiveCocoa/RACQueueScheduler.h + AFNetworking/AFSecurityPolicy.m sourceTree <group> @@ -11237,25 +11121,70 @@ runOnlyForDeploymentPostprocessing 0 - EAC969C6C60F8BD2BF2FD30609AA034D + E9C61BB3628EDC46285667E087566E2B + + fileRef + DB88B0D560024D1484A08A232F03F53A + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + EAE30534210F4962CBCB9FAFF8B99B8D + + fileRef + CD48F56B0AA64AC67F38F425B82D720B + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + EAF2198ED9386B68D3B65B66433B7733 + + children + + 9B5DB9EEDE586E53C458D04475A7E704 + 72EBC3B91782DFC648C33324DEF5FB15 + 816C4B8A46C88A91F732149F9D473D31 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/AFNetworking + sourceTree + <group> + + EAFD9C93CC8085D2F07483DAD42AB781 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACEXTRuntimeExtensions.m + RACDynamicSignal.h path - ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.m + ReactiveCocoa/RACDynamicSignal.h sourceTree <group> EB02AEF303313F801392DE8D90AFF0F7 fileRef - D178139F0687F97F4F446AE3F33251E1 + F25D909EB8F45EA1B2792B197BBD58E2 isa PBXBuildFile settings @@ -11266,115 +11195,145 @@ - EB932C7244160CC464D5F7E2A9713D3F + EB6683FC3260150506801302AD17C926 - buildActionMask - 2147483647 - files - - 216E5A12ACFD64B84DC1A2E253336D9B - + includeInIndex + 1 isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MASConstraintMaker.m + path + Masonry/MASConstraintMaker.m + sourceTree + <group> - EBA69E8FAA01CBD798D4F6C67B0DD981 + EB6C7E7A690B504E157E1AF6BD0C62FB + + fileRef + 676BECC6AE0171F9136A69F624DEB759 + isa + PBXBuildFile + + EB7CA93484A64DA41DA995CDCDAAFE51 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - RACUnarySequence.m + JSONAPI.h path - ReactiveCocoa/RACUnarySequence.m + JSONModel/JSONModelNetworking/JSONAPI.h sourceTree <group> - EBE2C705D406C16BC2D23784E5DD4805 + EB932C7244160CC464D5F7E2A9713D3F - baseConfigurationReference - 51DEAD099F5FEE7BE4DBD4CB7DDF0A0A - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/XAspect/XAspect-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - + buildActionMask + 2147483647 + files + + 216E5A12ACFD64B84DC1A2E253336D9B + isa - XCBuildConfiguration - name - Debug + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - EC0D5F87286AE5412CAC701D6ACAB402 + EB9A65CF8C6373F340063FFCBD007F43 buildActionMask 2147483647 files - 95B78BFC3D921957F8DD6A2CE3E0B499 + CAFC9C069CD9CEF94C741C52BF7C155D isa - PBXHeadersBuildPhase + PBXFrameworksBuildPhase runOnlyForDeploymentPostprocessing 0 - EC35FA32A2CD206519C0FF29685ECACC + EC6BDF9C49C4873A125EA392C6EF9763 + + fileRef + 080756BFAF462006CA1CB97A3EA1D7AA + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + EC6CCC98505D2067BC98B4E6223C9DF8 + + fileRef + 3AA0B279BB40445C34DF9A357B5A9C12 + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + ECAAF2C7B7412B87A7732C9C164836F8 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SDWebImagePrefetcher.h + AFURLResponseSerialization.m path - SDWebImage/SDWebImagePrefetcher.h + AFNetworking/AFURLResponseSerialization.m sourceTree <group> - EC440A5421781218D66C3DA94AAD9F7E + ECD2A148381C6717D8DCE2AA472F61A3 + + fileRef + A3BB933DADD14CB8DBD473EC6BF17EDC + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + ED7D2955A29AA5EF791E7EE4B001F536 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFNetworking.h + RACSequence.m path - AFNetworking/AFNetworking.h + ReactiveCocoa/RACSequence.m sourceTree <group> - EC6CCC98505D2067BC98B4E6223C9DF8 + EDC030DEF6CB1478AEA2DA12F4A38A37 fileRef - 7452892FA18756C935569E6F334C60D7 + 9C1253E47A1EA2670E5136F8216924DB isa PBXBuildFile settings @@ -11385,7 +11344,7 @@ - ED2480D499308776B8E3932253E7C46A + EDEE2194BAD340B988C97C63499C622E includeInIndex 1 @@ -11394,46 +11353,43 @@ lastKnownFileType sourcecode.c.h name - RACDynamicSignal.h + RACValueTransformer.h path - ReactiveCocoa/RACDynamicSignal.h + ReactiveCocoa/RACValueTransformer.h sourceTree <group> - ED99CEB724EB1A8CC658C31253E21BC4 + EE0F99FB0D1509C0A7E03A68A8068CD7 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.objc name - UIProgressView+AFNetworking.m + XACrystallization.cpp path - UIKit+AFNetworking/UIProgressView+AFNetworking.m + XAspect/Core/XACrystallization.cpp sourceTree <group> - EDFDFB257B49EF3F125E7706606F1B76 + EE43841F080329C982D3412E2685B88A - includeInIndex - 1 + fileRef + 75FC5A679675C9B89843197C7D3171C5 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACIndexSetSequence.m - path - ReactiveCocoa/RACIndexSetSequence.m - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + EE43A56420D041C473C78C19CD1B0EDB baseConfigurationReference - 6265DE8669B72124D597C877F521FA7B + 4E743A1D8C07C485D1E25B2E8F69503B buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -11464,20 +11420,83 @@ name Debug - EE99B43C5929107E4A199A7A9D6089B7 + EE452DB7731E48F1D2F70775FA697235 - baseConfigurationReference - C020DA99B6AD309040A6C00ECBA4EE19 - buildSettings + fileRef + 0AFD697C1D3464E6DD2AB0D8CCAEF042 + isa + PBXBuildFile + + EE6025199E346EEFB630B84F576E6276 + + fileRef + 8870896F8AE8D1DA8EB01CBED4AC1C58 + isa + PBXBuildFile + settings - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/CYLTabBarController/CYLTabBarController-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - YES + ATTRIBUTES + + Public + + + + EE6697C2C766C11CC4AA6C8FFF3FF7F6 + + includeInIndex + 1 + isa + PBXFileReference + name + XACExtensions.c + path + XAspect/Core/XACExtensions.c + sourceTree + <group> + + EE76FC3577DCDB4A2C6FF6302EC314BE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MASCompositeConstraint.m + path + Masonry/MASCompositeConstraint.m + sourceTree + <group> + + EE95B42B682BCB595D49554F8E78CA43 + + fileRef + 0EB8B30A1CC6330B08C57D41E2B7133F + isa + PBXBuildFile + settings + + ATTRIBUTES + + Public + + + + EE99B43C5929107E4A199A7A9D6089B7 + + baseConfigurationReference + 6BF5EAEFA9CA9FA862AF2D37D8D5B7BC + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/CYLTabBarController/CYLTabBarController-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + YES OTHER_LDFLAGS OTHER_LIBTOOLFLAGS @@ -11498,69 +11517,63 @@ name Debug - EEB0D4F9D043F877FF24AB99975A2250 + EF14456F85CB3D05B276E8FDC8A98826 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - XACrystallization.cpp + AFNetworkActivityIndicatorManager.m path - XAspect/Core/XACrystallization.cpp + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m sourceTree <group> - EEB5290704C77B4AF53D587E0B28249D - - fileRef - 8C598575EE88748ED3B64D6A1BE8EDA8 - isa - PBXBuildFile - - EF73143168A51F29EB621728AC617319 + EF3011E738122A0A380DCA81ECB7D10A - fileRef - 840210445DEB38A5E16BFBBC95DF7950 + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + RACIndexSetSequence.m + path + ReactiveCocoa/RACIndexSetSequence.m + sourceTree + <group> - EF826E8CB4E61D957E5D6F6A4779DF30 + EFB818120A8A60620138DB3835BFAB85 - fileRef - ED2480D499308776B8E3932253E7C46A isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXTargetDependency + name + Masonry + target + 53480ED0BE09FF49E34B1702D485CAAB + targetProxy + 3B043BCCC298A6F3CB95244509270730 - EFE24904C5DA3409D8B4583BE1DAB653 + F003CA8064D942B82B09DE63B338A506 - fileRef - A6700863B906BF25509A8103819B98F3 + includeInIndex + 1 isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIButton+AFNetworking.h + path + UIKit+AFNetworking/UIButton+AFNetworking.h + sourceTree + <group> - F02B853176928C740B241F44B5FB6835 + F0218A60CF118E77C2F159926207C45A includeInIndex 1 @@ -11569,25 +11582,26 @@ lastKnownFileType sourcecode.c.h name - UICollectionReusableView+RACSignalSupport.h + XACExtensions.h path - ReactiveCocoa/UICollectionReusableView+RACSignalSupport.h + XAspect/Core/XACExtensions.h sourceTree <group> - F0314A47BEA034880AA0E333F4B4F7B7 + F08553B1A91E401FF6877A9A61481C12 - buildConfigurations - - EBE2C705D406C16BC2D23784E5DD4805 - 9C7C6A30BC4D9CB07976524036ADC07F - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + includeInIndex + 1 isa - XCConfigurationList + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + XAObjcMetaprogramming.h + path + XAspect/Macros/XAObjcMetaprogramming.h + sourceTree + <group> F08E19D8B440D85D564273B1A501B1FC @@ -11596,45 +11610,81 @@ isa PBXBuildFile - F0A333F532B0C1AC3B62F8A28A039C88 + F204284237CD0FEBCA29B587BC2EE11A - fileRef - 4BBDEB6CE73B6137C47501419AF2777F + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFHTTPSessionManager.h + path + AFNetworking/AFHTTPSessionManager.h + sourceTree + <group> + + F221452B1B1DB6A6CCF5BD5EE23ABA54 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + RACSubscriber.h + path + ReactiveCocoa/RACSubscriber.h + sourceTree + <group> + + F25D909EB8F45EA1B2792B197BBD58E2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MASViewConstraint.h + path + Masonry/MASViewConstraint.h + sourceTree + <group> - F0B02EB9DD33ACB53286BC5521FAFF14 + F2AC96AA9678F8D13A7638DA178B53CD fileRef - 1EC1EDEFF2F3CEE160D4FD254D03DE25 + 74688FDEAD67A2999F1D34587BF6CC1D isa PBXBuildFile - settings - - ATTRIBUTES - - Public - - - F1052941DC75B5A88703211548A9B2DD + F2AF56F00E313B9CD0F4ADA3C5D73BDF fileRef - CE3774003D0ED90A82FC9C28440DCC94 + F51EE27ECFD016DA35FD0B8868EC10B8 isa PBXBuildFile - F122131280504E657C6CC246E7175B67 + F2E245B306BFA9016D866687173C0510 fileRef - 510325018C1BA2426D1484BFAAFE04D5 + 1F10A60D8ECF7A52FF2B6C11977CF151 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - F14DE15041F277E1CB02818F551857B5 + F2E63C36BC0C65D1820A28127018031E fileRef - 2101678EE1CAC9906F2C737F1FC9B939 + 2CBA7A14A1C2AF1E22C50E6CE482BD55 isa PBXBuildFile settings @@ -11645,17 +11695,39 @@ - F2AF56F00E313B9CD0F4ADA3C5D73BDF + F2EFF7F54E643FC6C7E72B5372091F26 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MASConstraint+Private.h + path + Masonry/MASConstraint+Private.h + sourceTree + <group> + + F34DB16B800EB0652AFCF75741F60EF1 fileRef - F51EE27ECFD016DA35FD0B8868EC10B8 + 29F4E625003F95F249CAE42723A20CFC + isa + PBXBuildFile + + F35BFD40F018DC9A6C68106905F7FB4F + + fileRef + 68549E42677EBBF9FE7FDD396A1BC2B3 isa PBXBuildFile - F3A88A208A89BB9D8FCE5A337ABFBC28 + F371FF874C0053ED5B901B4CDC3B866B fileRef - 094A8CD944A7C5AC470D871229D258E0 + C9B1003A73D6910F6BA17F3C45B5D5A8 isa PBXBuildFile settings @@ -11666,35 +11738,19 @@ - F3E0BF3FC9B1D5D5AC7BD46E8C386867 + F396D650E1CF38B91227646DF6E0FB42 - includeInIndex - 1 + fileRef + 9D89814A5FE0AD9B4433D95DD47A1C52 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UITextField+RACSignalSupport.m - path - ReactiveCocoa/UITextField+RACSignalSupport.m - sourceTree - <group> + PBXBuildFile - F3FB6F90335365FFF935B4FB91F5D94A + F3C65640A1A19944099A1A64337C26BC - includeInIndex - 1 + fileRef + 9BEC7C577BD7C1695F7C1C594202AF22 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACErrorSignal.h - path - ReactiveCocoa/RACErrorSignal.h - sourceTree - <group> + PBXBuildFile F428C0A5C7AEF469CC7F9B7E6EC0003A @@ -11713,25 +11769,24 @@ runOnlyForDeploymentPostprocessing 0 - F440593CC80B6F762E15F1ED231B4E19 + F4A1512E8C4D8C8194CBB276BF72A552 - includeInIndex - 1 + fileRef + 4DD08C0B21C162E6D324D90B91E741C2 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIButton+RACCommandSupport.h - path - ReactiveCocoa/UIButton+RACCommandSupport.h - sourceTree - <group> + PBXBuildFile + settings + + ATTRIBUTES + + Public + + - F4A1512E8C4D8C8194CBB276BF72A552 + F4B03681047157E5C357E584147F5A46 fileRef - 75D2D91A65315844BFD96735D194EBF1 + 05440307997E67C54848A5EC63BA113A isa PBXBuildFile settings @@ -11742,10 +11797,10 @@ - F4B03681047157E5C357E584147F5A46 + F4C5F5DA17E3869B0B9AF799DED6AD0F fileRef - 589EBB3F3E6E3A6A611453A4DD915ED5 + 4810F189AFC3DCD40A14FBCEF9833BAD isa PBXBuildFile settings @@ -11772,7 +11827,7 @@ F4D2A0918C2C064F1A16B4CA2D42089A fileRef - AC5083844F2D2F9F51E1E80933EC149E + 00929B0F1375903B01DA333074381F17 isa PBXBuildFile settings @@ -11786,7 +11841,7 @@ F4DCBA2A42A38C6E7A755182DA50DEA2 fileRef - 76B7C27071A6D22260FC2A2585F070BD + 1FFDC86E9668A2B725A5E14834BC864F isa PBXBuildFile settings @@ -11810,380 +11865,47 @@ sourceTree DEVELOPER_DIR - F5B23A8DB947C061C43DFC4FFED383BE - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - RACEmptySignal.h - path - ReactiveCocoa/RACEmptySignal.h - sourceTree - <group> - - F66268E5D5382C35C98197F3C4D51B98 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIAlertView+AFNetworking.m - path - UIKit+AFNetworking/UIAlertView+AFNetworking.m - sourceTree - <group> - - F66B78D4B47EE859EC50E73C16837FC7 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - MASViewConstraint.m - path - Masonry/MASViewConstraint.m - sourceTree - <group> - - F675A8DDF41D4884C065D13E96007B65 - - children - - BF8E7560208D1238F6A4223E9701F1D5 - FDF2348A859024AC05590AEE05594567 - EEB0D4F9D043F877FF24AB99975A2250 - B916116B6285D76B6613F1A54BD1A543 - 758978F83428DA4D8B66E32E141B5885 - 85F392C1372F726906BC2B879CFF3FC9 - - isa - PBXGroup - name - Core - sourceTree - <group> - - F739D150BC139BBFC781BC5FF683F53F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UITableViewCell+RACSignalSupport.h - path - ReactiveCocoa/UITableViewCell+RACSignalSupport.h - sourceTree - <group> - - F7B307B12425313F4B5EC4656EF68EBF + F5C2027D90A77D8A47CDF109FFB32E2B fileRef - 2F2C87C497B0D64D96372D87D03850BC + EE6697C2C766C11CC4AA6C8FFF3FF7F6 isa PBXBuildFile settings COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - F7B5D2658B77049DDEC0AAA88E6FCEA7 - - fileRef - AC683279CE140109D25DB1A0329F9E8F - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - - - F7ED8CA4F17E22E786B4F4658110F091 - - baseConfigurationReference - A8C77BBDC031F4497C55AEC67342E6DD - buildSettings - - ENABLE_STRICT_OBJC_MSGSEND - YES - GCC_PREFIX_HEADER - Target Support Files/Aspects/Aspects-prefix.pch - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - MTL_ENABLE_DEBUG_INFO - NO - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRIVATE_HEADERS_FOLDER_PATH - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - - SDKROOT - iphoneos - SKIP_INSTALL - YES - - isa - XCBuildConfiguration - name - Release - - F80F668A8F6E7D9DF4DDD32E7E99A09E - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UISegmentedControl+RACSignalSupport.m - path - ReactiveCocoa/UISegmentedControl+RACSignalSupport.m - sourceTree - <group> - - F82F5322899D1E6683512F768F6B4C9B - - fileRef - 3381F12C163CA27DAB6C05AB64098D9E - isa - PBXBuildFile - - F92C693888AC9830EA897E087C7328CB - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - JSONKeyMapper.h - path - JSONModel/JSONModelTransformations/JSONKeyMapper.h - sourceTree - <group> - - F9575F63C631FB07CA73C4567D3D9DA0 - - fileRef - C6AFC54A7B6BE1A53FCF12B72CFD340A - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - + -fno-objc-arc - F99004E5FF8745BDDB86E40F96AA5831 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACReplaySubject.m - path - ReactiveCocoa/RACReplaySubject.m - sourceTree - <group> - - F9A104A960E0257D7A7BAF9AA133AF85 + F5DE55D327DB675D6B778FE089325A79 - buildActionMask - 2147483647 - files + children - F1052941DC75B5A88703211548A9B2DD - 2A8C2C1BA962C825F2F8D04CDBB5649E - C2CAA3E9C9A2D5484A5B29E9A6F0F62E - DD618B07C2697365A5F160EE23051DD3 - FC6B96FE4E875072E0BDD40B3C776985 - 461441BB0039FFBF9FFEC9A12FF0525F - AE0DA3B70021F67AB7543B247F1754DD - 2841B4168F5F6452653DE47EDEC70B00 - F0A333F532B0C1AC3B62F8A28A039C88 - 6E44AA3980A4EA3C258E38573C306B36 - 02811C7B60F93138985F40306F45E68D - 0C11F8AFE41DAB4312639F7FBA9C7DF8 - 3283ED0D6AC39771F2FB56070C414677 - 140B87BDAA052AF62B194A41BD3F5485 - 0E22F1DDE5ED636BC8CF1792611481B4 - 755228EBEDB3A61E5D08B3D96B94866F - 7009EBE73A4C910697A4A21282089B06 - 20E0B451FEA8C21D357EB3EB8620AAD2 - D08EC6096C0C443EF22CD3B38AD34DD0 - 344DB5E27F667A528595D40A52338169 - 26BB4FEAB632089BB12D38E317DBB091 - 08615F925825849B44B6CCD3E6F0603E - 40C6841E8BEA23E62F758DF4AFB7EE44 - 8A794E0ED3682DF3F2D84BB3350A297B - 304CD204412EE5C882A771B88A801D44 - CE9C4D5715C4925FD06419626BFDD626 - DAA089651531F65F35B37A3D17DF641D - 5B5B00543EABECF5F8B93CAA833A5DFD - A4261CED5E5A7226F5FA65BCF8044BDE - 819E6615CF458C4E29F4D422C9AA1B23 - EEB5290704C77B4AF53D587E0B28249D - 451A9850F23BFA1C02FB8FA6A179F06C - 2270594E7C70F13CFAE56D01E4555BF3 - F122131280504E657C6CC246E7175B67 - BEB6974807F8FFE158ED0133C9A3CE9B - 7248B9BD088DBD52635462FD79DCE8E0 - D7D2F9CC2AD634DAE9D71734596DB2A3 - D2374162F96CD29971B4D14B3EADB7C6 - FC1E2B523661AA465DD70E9DCD0D76F9 - 09A3D2D431763E68E628962ED536E86F - A51069A7F86CF1847F2D544C0777CD46 - 736EEB09A74B695F08491CBA8B52FF0F - 7053FA23055952EFF57A2801B729A9CE - 04AF8D8C177C1967327A34A91AC5DC0A - 66AA607A66B431C3CFA1C96A1BFC835F - 5691B0310ACD8CBFDB2B3E910C6C06B5 - 18C54F73D160C5DE51EE76A34F4A2D28 - 69E080A3E3655867E7296826684D9E27 - 0036B867576A91F864CA856ED7A346BB - 5E0CF2719FFDAB581CA902645FE2B8BB - 3D9C138CA58DB20B7958E752E277C061 - B153305CAB6057ABEA1D38F1ED6C3FB3 - B3836EC94CD274E785D8B0302683757D - 1FD825150D8FF10423EFAD474091BF59 - C38AD16F31C060C53626F2534346AF82 - 55DAF72F6CDEFB6BE0251EC4A55C1BEC - CFAA5BCCF7A8CD45FA8E2D8E08DDE01D - 0B8F9D22BE0302370E75B416C2572DBA - 102C0BF60B91AF4ADFE25AF4376A6F09 - 55F97BB22E50192EFDF5E1D465482B9E - D0938112D63C96C6560926C5C50F4CA6 - 79C87CB103AEE07E13CC34AC6471EA15 - 2A29B9901845547F2855DE837562CC10 - BA34B3B7138CB040AF983280C590F59D - D51C02B6411EFDCED556818C14E6C499 - 5A765CA0E436261D1B45E2F0AD0616E5 - 6BC4B87350EBF064A54481585D49217D - E249E933AF2AC413228EB267386BA7DC - BB036866E506E2539AA1C504AA47DD6B - 36C43111876FF992816ECB7AF602E9D2 - FE0FFBE4F747B7143262EBAA1D989613 - 8B3DCAF43D573EA1DAB1CA36231FB5EF - E182FAEF2027E3CE1000307AE23CD5C3 - 31E0E3D2D0FFD314985BC551FA85C163 - 2B5518F5D8E2D7C4F17B86BF27196257 - FA8E8771A2264A9C78070ED74D18020C - 0CC98B5370BB5B9EB73E4A1856ACB18B - AAF515E9CAE57C26AF1A3E51495FF779 - 099CBCF0599B3B23AAD11286282DDB25 - 3FE45802A334D3A34D1E9801DF60855E - F82F5322899D1E6683512F768F6B4C9B - 19B9A09BC12D7BB8283B469DB729B2EC - 5986E21E36132C23558BE0EEBD75BF46 - 899DD76852C172803602DDE6ADA838CF - A28E2581565AA2BD5592D8B1880FFBBA - 684F328D84DB590851126DD1D1FA216F - 2CF6C1779F523346732DDD5A481525C2 - FC8FD374C25E8E47345B3F858037DD74 - CB167AEAF1AF4CCF87533BE624FA0313 - A6DDB785D42C61A3E867E03E898635DC - 140834AA8BE1DC77A219D2210F946031 - 05B6FCF2A3F84FBE5600B24177C5B284 + 741BF78A50444622EEC3602E1EBD1DD6 + 336B1E6E8484ECB8832FF08AF4325EBF + 3378C8AD2EF891AE0AF4915F6ACD4032 isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - F9CA04A1AC1A5119C264BFE9667EE809 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIActivityIndicatorView+AFNetworking.m - path - UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m - sourceTree - <group> - - FA4AF3EAA8C3A19405FB7B9B433420E9 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - RACReplaySubject.h + Support Files path - ReactiveCocoa/RACReplaySubject.h + ../Target Support Files/JSONModel sourceTree <group> - FA8E8771A2264A9C78070ED74D18020C - - fileRef - 0840A76EC690C8025301D5B2587F04F9 - isa - PBXBuildFile - - FAB9E9D9BBDB93399D3C2B91469EC4B6 + F6934BC9C81809F660C462C082D63614 - buildActionMask - 2147483647 - files - - 2F85D170E76C661AB0D9E9A8B206C78D - 9A6AE1EF2E94AEB6912BE845583E7D57 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - FAC1777451F4CF9AC6712170B22847B3 - - fileRef - 594DDD0D23DB6F4D39E406074E9A1567 - isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + isa + PBXTargetDependency + name + XAspect + target + 898AEA184EF58065EB8EFB5AEA26B508 + targetProxy + E390C23E48599B65AFF2A0B428CACCCA - FAF1AB4051B3B9E753D50E9095D01044 + F7AF88794E0B7118A5A846E9DBB7B270 includeInIndex 1 @@ -12192,25 +11914,27 @@ lastKnownFileType sourcecode.c.h name - NSArray+RACSequenceAdditions.h + UISlider+RACSignalSupport.h path - ReactiveCocoa/NSArray+RACSequenceAdditions.h + ReactiveCocoa/UISlider+RACSignalSupport.h sourceTree <group> - FB3F7E75C7BF09EED702375E584C44BE + F7B5D2658B77049DDEC0AAA88E6FCEA7 fileRef - EEB0D4F9D043F877FF24AB99975A2250 + A743224C6A1CA40D3FE0A1FDF4839D46 isa PBXBuildFile settings - COMPILER_FLAGS - -fno-objc-arc + ATTRIBUTES + + Public + - FB7ED69A0A9F3DBA39CF3BA76B660EFF + F7CC25DAFD63A1A8FFE474BF9429135C includeInIndex 1 @@ -12218,30 +11942,64 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - ReactiveCocoa.h path - ReactiveCocoa/ReactiveCocoa.h + Aspects-prefix.pch sourceTree <group> - FBA183F8CEB6E1502C9CBA37072AA76E + F7ED8CA4F17E22E786B4F4658110F091 + + baseConfigurationReference + 5D0A0AC7E297CCC9504DCCB7F98867C7 + buildSettings + + ENABLE_STRICT_OBJC_MSGSEND + YES + GCC_PREFIX_HEADER + Target Support Files/Aspects/Aspects-prefix.pch + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + MTL_ENABLE_DEBUG_INFO + NO + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRIVATE_HEADERS_FOLDER_PATH + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Release + + FA2CEE153AF0EBF4A4AB72D050A175F2 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + MASCompositeConstraint.h path - AFNetworking.xcconfig + Masonry/MASCompositeConstraint.h sourceTree <group> - FBB0541077071EFAE01C2B06AB233CB5 + FA819734BAD3D8CF6B68DF8D5E230C2A fileRef - E0C332A92E8CD15A40F2CEA81ADEA5B3 + 0EBA43F54C3667374FD70E17C4B437A2 isa PBXBuildFile settings @@ -12252,24 +12010,52 @@ - FC1E2B523661AA465DD70E9DCD0D76F9 + FA8BEFD2A3B858DC7840C3B8B2916A42 + + fileRef + B74EF8B935DF8DB6BDF3B7898A6E959B + isa + PBXBuildFile + + FAB9E9D9BBDB93399D3C2B91469EC4B6 + + buildActionMask + 2147483647 + files + + 2F85D170E76C661AB0D9E9A8B206C78D + 9A6AE1EF2E94AEB6912BE845583E7D57 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + FAFE589A1BCB942F30C11B6D71A9FEDF fileRef - EAC969C6C60F8BD2BF2FD30609AA034D + 735843161B754292F8061E3F63C071C5 isa PBXBuildFile + settings + + ATTRIBUTES + + Public + + FC33E7B450A96626E3956F557A061B9C fileRef - 42F37DFACB2534ED1B8F85FA5BF203AD + E546A797D535F0184D885932D32A6FA5 isa PBXBuildFile FC5CE4331073DAEE9787ECB2636651C2 baseConfigurationReference - C020DA99B6AD309040A6C00ECBA4EE19 + 6BF5EAEFA9CA9FA862AF2D37D8D5B7BC buildSettings ENABLE_STRICT_OBJC_MSGSEND @@ -12300,17 +12086,10 @@ name Release - FC6B96FE4E875072E0BDD40B3C776985 - - fileRef - 7A225968E7F6AB6C378FB62566296289 - isa - PBXBuildFile - - FC7D8F0AE042206281D80363E9920224 + FC5F6569B5BBEC724A67613EACEEDBC7 fileRef - 7E8F683A3FAFE6F8AD716FDDF5F708CD + 5159B129DE1BC211151FDE6DE1D2B6CA isa PBXBuildFile settings @@ -12321,54 +12100,10 @@ - FC7FF831376FA8C9100E2C08023F477F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACSignalSequence.m - path - ReactiveCocoa/RACSignalSequence.m - sourceTree - <group> - - FC8FD374C25E8E47345B3F858037DD74 - - fileRef - 042A892BF73D36F9B88BD05E3CA301C0 - isa - PBXBuildFile - - FCC32E4089B93933079F7040E4A7491E - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIViewController+CYLTabBarControllerExtention.h - path - CYLTabBarController/UIViewController+CYLTabBarControllerExtention.h - sourceTree - <group> - - FCC374BDD7ECFFDE067EC85853E9B84C - - fileRef - 272643F56613CA0D336AE3DBF19DC404 - isa - PBXBuildFile - - FCE5C18C12E02BA55788BCC2D8D32BD1 + FD39EBE3398E1A99965AC003B273450D fileRef - FAF1AB4051B3B9E753D50E9095D01044 + 7F032C0F9E4566CBAD7B1284E266B421 isa PBXBuildFile settings @@ -12379,48 +12114,10 @@ - FD1A9D19CF02957A5C755BDED2F42F34 - - buildActionMask - 2147483647 - files - - FCC374BDD7ECFFDE067EC85853E9B84C - - isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - FD1D53461DE538B7C8DFE0B76D857587 - - buildConfigurationList - D6237EEAE81FAC77DC4CDAA075B264E9 - buildPhases - - 7F85DFA0BA8E5DF5155BF3912A24B2A0 - 00CD0B0096519208337740D5BC28FE6D - EC0D5F87286AE5412CAC701D6ACAB402 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - JSPatch - productName - JSPatch - productReference - 5F6D57308FA578FEA1CA7A71481B91CA - productType - com.apple.product-type.library.static - - FD39EBE3398E1A99965AC003B273450D + FD5D5B84A17DE1F44687D8E5A3B723F4 fileRef - 3853D3CEFB1581CF31C6C033376581B0 + 1A6F5266C23C619C54C0477DFE7283AB isa PBXBuildFile settings @@ -12434,40 +12131,37 @@ FD6F966F458CEE40B07A2367BA3BC8EC fileRef - ED99CEB724EB1A8CC658C31253E21BC4 + 1890C07A8BA8839AC3686951BF277AEB isa PBXBuildFile - FD7DDBDD0E5A72786C1A87D606D8334C + FD83741DFCC987B6F8C39356881215B2 - includeInIndex - 1 + fileRef + 23530EDB822FDDE0339E09D976220909 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - RACImmediateScheduler.m - path - ReactiveCocoa/RACImmediateScheduler.m - sourceTree - <group> + PBXBuildFile + + FDA6B6E0FFABF3BCF80518597408E23E + + fileRef + D3F55C54D57DA8CEDF61A47C1491A1C8 + isa + PBXBuildFile - FDAA52691B534B5F48185CA2B84BE0AE + FDB2E620B5F227C5BCD594019FFE39F4 fileRef - D6B6C0BAB71F40084CD19007816F5135 + B5281F66A21D235BBFBEB4D43FF85466 isa PBXBuildFile settings - ATTRIBUTES - - Public - + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - FDF2348A859024AC05590AEE05594567 + FDBBAAAFCF83B7732FCB13B9D0CD9A95 includeInIndex 1 @@ -12476,50 +12170,38 @@ lastKnownFileType sourcecode.c.h name - XACExtensions.h + UIButton+RACCommandSupport.h path - XAspect/Core/XACExtensions.h + ReactiveCocoa/UIButton+RACCommandSupport.h sourceTree <group> - FE0FFBE4F747B7143262EBAA1D989613 + FDDA23E0C00FC0952BB9A01A3F25ACC4 fileRef - 239FB2B346B31E34E553402848248712 + 3D5E45149CD961B9BE684964D8BBEA84 isa PBXBuildFile - FE3016F8D24573180CF7C7D05212A264 + FEC4EF4B8F6EAEA6E2829EE84BC8912A - containerPortal - D41D8CD98F00B204E9800998ECF8427E - isa - PBXContainerItemProxy - proxyType + includeInIndex 1 - remoteGlobalIDString - 44D882ADFA06DC141944859F300FC170 - remoteInfo - SDWebImage - - FEA4EB466A8EB01D17216878C9EFF90E - - fileRef - 0D12B91CB78BF7CD99A66A8D0AF6BD9A isa - PBXBuildFile - settings - - ATTRIBUTES - - Public - - + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MKAnnotationView+RACSignalSupport.m + path + ReactiveCocoa/MKAnnotationView+RACSignalSupport.m + sourceTree + <group> - FED068C67D733208A64F4953026881B6 + FEC7C43491775ECA43A0C635A44E5C59 fileRef - C208817A5549140282E7150447CB076D + C421FE4B29E3C5DBCDE764368D0C474F isa PBXBuildFile settings @@ -12530,7 +12212,7 @@ - FF42A8789D18FAD4AF9A46051584CD05 + FF1741BE56FD6460B06F37F6EABA351B includeInIndex 1 @@ -12539,16 +12221,32 @@ lastKnownFileType sourcecode.c.h name - ViewController+MASAdditions.h + XAspect.h path - Masonry/ViewController+MASAdditions.h + XAspect/XAspect.h sourceTree <group> + FF5EA1C804C15099106D18CA52C58431 + + buildActionMask + 2147483647 + files + + F5C2027D90A77D8A47CDF109FFB32E2B + 94DFC7CF85D85A79751DD1716BDF8087 + B6C3BB0342CA0157595A91FA2E1EA844 + BAA47853766464C0B5C994A5A83D1E0B + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + FF682E8B083BAEBBDF38C52D89D45E37 fileRef - 0480BE93F654AD1A2D187F4B80831514 + 596B174E46C0474CE36AEF416A2FAE51 isa PBXBuildFile settings @@ -12559,31 +12257,7 @@ - FF75C273E835D9600B1264CC1FA3320F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - path - CYLTabBarController-dummy.m - sourceTree - <group> - - FFCE83538E61E9B07A77FC1494D5DF55 - - isa - PBXTargetDependency - name - ReactiveCocoa - target - 4F7ACF1421268A3CDFC9455CABF9A6D5 - targetProxy - 08FC414E4468D8119EB2F0B1BA89EDB6 - - FFFBC385AE074ECF5DEE7254C05D04D1 + FF978E1C2AC89DC8FC0A9A10FB55C648 includeInIndex 1 @@ -12592,9 +12266,9 @@ lastKnownFileType sourcecode.c.objc name - SDWebImageDownloaderOperation.m + RACSignal+Operations.m path - SDWebImage/SDWebImageDownloaderOperation.m + ReactiveCocoa/RACSignal+Operations.m sourceTree <group> diff --git a/Pods/Target Support Files/AFNetworking/AFNetworking.xcconfig b/Pods/Target Support Files/AFNetworking/AFNetworking.xcconfig index 583f03e..13200b0 100644 --- a/Pods/Target Support Files/AFNetworking/AFNetworking.xcconfig +++ b/Pods/Target Support Files/AFNetworking/AFNetworking.xcconfig @@ -1,5 +1,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/AFNetworking" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/AFNetworking" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" OTHER_LDFLAGS = -framework "CoreGraphics" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/Aspects/Aspects.xcconfig b/Pods/Target Support Files/Aspects/Aspects.xcconfig index ef2ce50..0d1c678 100644 --- a/Pods/Target Support Files/Aspects/Aspects.xcconfig +++ b/Pods/Target Support Files/Aspects/Aspects.xcconfig @@ -1,4 +1,4 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Aspects" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Aspects" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/CYLTabBarController/CYLTabBarController.xcconfig b/Pods/Target Support Files/CYLTabBarController/CYLTabBarController.xcconfig index 06ce0fb..8ad6a39 100644 --- a/Pods/Target Support Files/CYLTabBarController/CYLTabBarController.xcconfig +++ b/Pods/Target Support Files/CYLTabBarController/CYLTabBarController.xcconfig @@ -1,4 +1,4 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/CYLTabBarController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/CYLTabBarController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/JSONModel/JSONModel.xcconfig b/Pods/Target Support Files/JSONModel/JSONModel.xcconfig index db4f47a..ec0f6a1 100644 --- a/Pods/Target Support Files/JSONModel/JSONModel.xcconfig +++ b/Pods/Target Support Files/JSONModel/JSONModel.xcconfig @@ -1,4 +1,4 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/JSONModel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/JSONModel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/JSPatch/JSPatch-dummy.m b/Pods/Target Support Files/JSPatch/JSPatch-dummy.m deleted file mode 100644 index 523f646..0000000 --- a/Pods/Target Support Files/JSPatch/JSPatch-dummy.m +++ /dev/null @@ -1,5 +0,0 @@ -#import -@interface PodsDummy_JSPatch : NSObject -@end -@implementation PodsDummy_JSPatch -@end diff --git a/Pods/Target Support Files/JSPatch/JSPatch-prefix.pch b/Pods/Target Support Files/JSPatch/JSPatch-prefix.pch deleted file mode 100644 index aa992a4..0000000 --- a/Pods/Target Support Files/JSPatch/JSPatch-prefix.pch +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef __OBJC__ -#import -#endif - diff --git a/Pods/Target Support Files/JSPatch/JSPatch.xcconfig b/Pods/Target Support Files/JSPatch/JSPatch.xcconfig deleted file mode 100644 index 43bbb53..0000000 --- a/Pods/Target Support Files/JSPatch/JSPatch.xcconfig +++ /dev/null @@ -1,5 +0,0 @@ -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/JSPatch" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" -OTHER_LDFLAGS = -framework "Foundation" -weak_framework "JavaScriptCore" -PODS_ROOT = ${SRCROOT} -SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/Masonry/Masonry.xcconfig b/Pods/Target Support Files/Masonry/Masonry.xcconfig index 1197080..e746468 100644 --- a/Pods/Target Support Files/Masonry/Masonry.xcconfig +++ b/Pods/Target Support Files/Masonry/Masonry.xcconfig @@ -1,5 +1,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Masonry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Masonry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" OTHER_LDFLAGS = -framework "Foundation" -framework "UIKit" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown b/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown index 97a3e31..5f45838 100644 --- a/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown @@ -442,32 +442,6 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense -## JSPatch - -The MIT License (MIT) - -Copyright (c) 2015 bang - -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. - - - ## Masonry Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry @@ -537,6 +511,11 @@ THE SOFTWARE. +## UMengAnalytics-NO-IDFA + +Copyright 2011 - 2015 UMeng.com. All rights reserved. + + ## XAspect **Copyright (c) 2015 Kang-Yu Xaree Lee** diff --git a/Pods/Target Support Files/Pods/Pods-acknowledgements.plist b/Pods/Target Support Files/Pods/Pods-acknowledgements.plist index bb499d9..f489cf3 100644 --- a/Pods/Target Support Files/Pods/Pods-acknowledgements.plist +++ b/Pods/Target Support Files/Pods/Pods-acknowledgements.plist @@ -473,36 +473,6 @@ The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/M Type PSGroupSpecifier - - FooterText - The MIT License (MIT) - -Copyright (c) 2015 bang - -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. - - - Title - JSPatch - Type - PSGroupSpecifier - FooterText Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry @@ -584,6 +554,15 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright 2011 - 2015 UMeng.com. All rights reserved. + + Title + UMengAnalytics-NO-IDFA + Type + PSGroupSpecifier + FooterText **Copyright (c) 2015 Kang-Yu Xaree Lee** diff --git a/Pods/Target Support Files/Pods/Pods-resources.sh b/Pods/Target Support Files/Pods/Pods-resources.sh index 81eba04..16774fb 100755 --- a/Pods/Target Support Files/Pods/Pods-resources.sh +++ b/Pods/Target Support Files/Pods/Pods-resources.sh @@ -57,12 +57,6 @@ install_resource() ;; esac } -if [[ "$CONFIGURATION" == "Debug" ]]; then - install_resource "JSPatch/JSPatch/JSPatch.js" -fi -if [[ "$CONFIGURATION" == "Release" ]]; then - install_resource "JSPatch/JSPatch/JSPatch.js" -fi mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" diff --git a/Pods/Target Support Files/Pods/Pods.debug.xcconfig b/Pods/Target Support Files/Pods/Pods.debug.xcconfig index 62bee4d..2e6cefb 100644 --- a/Pods/Target Support Files/Pods/Pods.debug.xcconfig +++ b/Pods/Target Support Files/Pods/Pods.debug.xcconfig @@ -1,6 +1,7 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/UMengAnalytics-NO-IDFA/umsdk_IOS_analyics_no-idfa_v4.1.1" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GTSDK" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/Aspects" -isystem "${PODS_ROOT}/Headers/Public/CYLTabBarController" -isystem "${PODS_ROOT}/Headers/Public/GTSDK" -isystem "${PODS_ROOT}/Headers/Public/JSONModel" -isystem "${PODS_ROOT}/Headers/Public/JSPatch" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/ReactiveCocoa" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/XAspect" -OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"Aspects" -l"CYLTabBarController" -l"GeTuiSdk-1.5.0" -l"JSONModel" -l"JSPatch" -l"Masonry" -l"ReactiveCocoa" -l"SDWebImage" -l"XAspect" -l"c++" -l"sqlite3.0" -l"z" -framework "AVFoundation" -framework "CFNetwork" -framework "CoreBluetooth" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "Foundation" -framework "ImageIO" -framework "JavaScriptCore" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -weak_framework "JavaScriptCore" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" +LIBRARY_SEARCH_PATHS = "$(PODS_ROOT)/UMengAnalytics-NO-IDFA/**" $(inherited) "${PODS_ROOT}/GTSDK" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/Aspects" -isystem "${PODS_ROOT}/Headers/Public/CYLTabBarController" -isystem "${PODS_ROOT}/Headers/Public/GTSDK" -isystem "${PODS_ROOT}/Headers/Public/JSONModel" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/ReactiveCocoa" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" -isystem "${PODS_ROOT}/Headers/Public/XAspect" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"Aspects" -l"CYLTabBarController" -l"GeTuiSdk-1.5.0" -l"JSONModel" -l"Masonry" -l"ReactiveCocoa" -l"SDWebImage" -l"XAspect" -l"c++" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AVFoundation" -framework "CFNetwork" -framework "CoreBluetooth" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "Foundation" -framework "ImageIO" -framework "JavaScriptCore" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "UMMobClick" PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Pods/Target Support Files/Pods/Pods.release.xcconfig b/Pods/Target Support Files/Pods/Pods.release.xcconfig index 62bee4d..2e6cefb 100644 --- a/Pods/Target Support Files/Pods/Pods.release.xcconfig +++ b/Pods/Target Support Files/Pods/Pods.release.xcconfig @@ -1,6 +1,7 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/UMengAnalytics-NO-IDFA/umsdk_IOS_analyics_no-idfa_v4.1.1" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GTSDK" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/Aspects" -isystem "${PODS_ROOT}/Headers/Public/CYLTabBarController" -isystem "${PODS_ROOT}/Headers/Public/GTSDK" -isystem "${PODS_ROOT}/Headers/Public/JSONModel" -isystem "${PODS_ROOT}/Headers/Public/JSPatch" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/ReactiveCocoa" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/XAspect" -OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"Aspects" -l"CYLTabBarController" -l"GeTuiSdk-1.5.0" -l"JSONModel" -l"JSPatch" -l"Masonry" -l"ReactiveCocoa" -l"SDWebImage" -l"XAspect" -l"c++" -l"sqlite3.0" -l"z" -framework "AVFoundation" -framework "CFNetwork" -framework "CoreBluetooth" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "Foundation" -framework "ImageIO" -framework "JavaScriptCore" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -weak_framework "JavaScriptCore" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" +LIBRARY_SEARCH_PATHS = "$(PODS_ROOT)/UMengAnalytics-NO-IDFA/**" $(inherited) "${PODS_ROOT}/GTSDK" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/Aspects" -isystem "${PODS_ROOT}/Headers/Public/CYLTabBarController" -isystem "${PODS_ROOT}/Headers/Public/GTSDK" -isystem "${PODS_ROOT}/Headers/Public/JSONModel" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/ReactiveCocoa" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" -isystem "${PODS_ROOT}/Headers/Public/XAspect" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"Aspects" -l"CYLTabBarController" -l"GeTuiSdk-1.5.0" -l"JSONModel" -l"Masonry" -l"ReactiveCocoa" -l"SDWebImage" -l"XAspect" -l"c++" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AVFoundation" -framework "CFNetwork" -framework "CoreBluetooth" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "Foundation" -framework "ImageIO" -framework "JavaScriptCore" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "UMMobClick" PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.xcconfig b/Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.xcconfig index 196a301..22a708b 100644 --- a/Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.xcconfig +++ b/Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.xcconfig @@ -1,4 +1,4 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ReactiveCocoa" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ReactiveCocoa" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/SDWebImage/SDWebImage.xcconfig b/Pods/Target Support Files/SDWebImage/SDWebImage.xcconfig index 32b7914..068a1bd 100644 --- a/Pods/Target Support Files/SDWebImage/SDWebImage.xcconfig +++ b/Pods/Target Support Files/SDWebImage/SDWebImage.xcconfig @@ -1,5 +1,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" OTHER_LDFLAGS = -framework "ImageIO" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/Pods/Target Support Files/XAspect/XAspect.xcconfig b/Pods/Target Support Files/XAspect/XAspect.xcconfig index ce05191..7a93b33 100644 --- a/Pods/Target Support Files/XAspect/XAspect.xcconfig +++ b/Pods/Target Support Files/XAspect/XAspect.xcconfig @@ -1,7 +1,7 @@ CLANG_CXX_LANGUAGE_STANDARD = c++11 CLANG_CXX_LIBRARY = libc++ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/XAspect" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/JSPatch" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/XAspect" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/XAspect" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Aspects" "${PODS_ROOT}/Headers/Public/CYLTabBarController" "${PODS_ROOT}/Headers/Public/GTSDK" "${PODS_ROOT}/Headers/Public/JSONModel" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/ReactiveCocoa" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/UMengAnalytics-NO-IDFA" "${PODS_ROOT}/Headers/Public/XAspect" OTHER_LDFLAGS = -l"c++" PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES \ No newline at end of file diff --git a/README.md b/README.md index 46922ea..2e511c1 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ static NSString * const kDesignerModuleActionsDictionaryKeyImage=@"image"; ###JiaCore(基础功能封装) -JiaCore是整个APP最基础模块,所有的模块化都要依赖,主要包含一些全局的功能模块,比如JiaBaseViewController、JiaAppDelegate、JiaBaseRequest等;目前已经把一些默认的功能进行集成在里面,包含网络状态变化判断及提示、日志记录功能等;并把一些相关配置的内容用JiaCoreConfigManager这个管理类进行统一设置,比如是否打开日志记录功能;JiaCoreConfigManager类则是开放给具体APP设置全局的相关配置;下面就以其中一个日志记录功能进行讲解: +JiaCore是整个APP最基础模块,所有的模块化都要依赖,主要包含一些全局的功能模块,比如JiaBaseViewController、JiaAppDelegate等;目前已经把一些默认的功能进行集成在里面,包含网络状态变化判断及提示、日志记录功能等;并把一些相关配置的内容用JiaCoreConfigManager这个管理类进行统一设置,比如是否打开日志记录功能;JiaCoreConfigManager类则是开放给具体APP设置全局的相关配置;下面就以其中一个日志记录功能进行讲解: ```obj-c //JiaCore基础模块相关配置 @@ -135,7 +135,7 @@ static const int ddLogLevel = DDLogLevelVerbose; ###JiaNetWork(网络交互封装) -对于网络请求模块则采用YTKNetwork,底层还是以AFNetworking进行网络通信交互,在基础全局模块JiaCore中,定义一个继承于YTKBaseRequest的JiaBaseRequest,针对JiaBaseRequest则是为了后期各个APP可以对它进行分类扩展,对于一些超时、请求头部等进行统一个性化设置,毕竟这些是每个APP都不相同;而针对模块中关于请求网络的前缀设置,则在每个模块中都有一个单例的配置类,此配置类是为了针对该模块对不同APP变化而定义;相应的配置内容开放给APP,由具体APP来定义,例如现在项目中的JiaBaseRequest+App.h类,里面有简单设置超时跟头部;当然记得把这个分类引入到APP中,比如AppPrefixHeader这个APP的全局头部; +对于网络请求模块则采用YTKNetwork,底层还是以AFNetworking进行网络通信交互,定义一个继承于YTKBaseRequest的JiaBaseRequest,针对JiaBaseRequest则是为了后期各个APP可以对它进行分类扩展,对于一些超时、请求头部等进行统一个性化设置,毕竟这些是每个APP都不相同;而针对模块中关于请求网络的前缀设置,则在每个模块中都有一个单例的配置类,此配置类是为了针对该模块对不同APP变化而定义;相应的配置内容开放给APP,由具体APP来定义,例如现在项目中的JiaBaseRequest+App.h类,里面有简单设置超时跟头部;当然记得把这个分类引入到APP中,比如AppPrefixHeader这个APP的全局头部; ```obj-c #import "JiaBaseRequest+App.h" @@ -221,6 +221,36 @@ gtConfig.jiaGTAppSecret=@"2282vl0IwZd9KL3ZpDyoUL7"; + +###JiaAnalytics模块(友盟统计封装) + +JiaAnalytics模块是在友盟统计SDK跟Aspect相结合基础上完成,对于页面的进出统计采用Aop切面方式进行,把原本应该在每个页面生命周期的统计代码移除,App运用只要简单配置友盟相对应的信息,也可以设置要统计页面的过滤条件,目前已经有三种如要统计的开头页面的前缀字符串数组、要统计的页面名称字符串数组、不统计的页面名称字符串数组;可以结合使用,达到精确统计页面的目的;而且把统计的代码放在异步线程进行,不会影响主线程的响应; + +```obj-c +__weak typeof(self) ws = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + [UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id info, BOOL animated){ + UIViewController *controller = [info instance]; + BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])]; + if (filterResult) { + [ws beginLogPageView:[controller class]]; + } + } error:NULL]; + + [UIViewController aspect_hookSelector:@selector(viewWillDisappear:) withOptions:AspectPositionAfter usingBlock:^(id info, BOOL animated){ + UIViewController *controller = [info instance]; + BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])]; + if (filterResult) { + [ws endLogPageView:[controller class]]; + } + } error:NULL]; + }); + +``` + + + #模块化结合私有Pods方案 上面实例中只是把相关模块化的提取都在一个工程进行体现,最后还是要落实结合Pods进行管理,把每个模块分开管理,不同的APP可以简单通过Pods指令就可以达到引入模块的效果,对于一些相同模块可以在不同的APP重复引用,减小重复开发成本; diff --git a/jiaModuleDemo.xcodeproj/project.pbxproj b/jiaModuleDemo.xcodeproj/project.pbxproj index 25513ec..4550f9b 100644 --- a/jiaModuleDemo.xcodeproj/project.pbxproj +++ b/jiaModuleDemo.xcodeproj/project.pbxproj @@ -9,17 +9,18 @@ /* Begin PBXBuildFile section */ 0DC796C047BBA513A78E857B /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6109480D64D9F6F4E2BC07CB /* libPods.a */; }; 340C3D781D8FDD8D00E3BACD /* JiaAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 340C3D771D8FDD8D00E3BACD /* JiaAppDelegate.m */; }; - 343EB39C1D92178C00110CE5 /* YTKBaseRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB38A1D92178C00110CE5 /* YTKBaseRequest.m */; }; - 343EB39D1D92178C00110CE5 /* YTKBatchRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB38C1D92178C00110CE5 /* YTKBatchRequest.m */; }; - 343EB39E1D92178C00110CE5 /* YTKBatchRequestAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB38E1D92178C00110CE5 /* YTKBatchRequestAgent.m */; }; - 343EB39F1D92178C00110CE5 /* YTKChainRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3901D92178C00110CE5 /* YTKChainRequest.m */; }; - 343EB3A01D92178C00110CE5 /* YTKChainRequestAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3921D92178C00110CE5 /* YTKChainRequestAgent.m */; }; - 343EB3A11D92178C00110CE5 /* YTKNetworkAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3951D92178C00110CE5 /* YTKNetworkAgent.m */; }; - 343EB3A21D92178C00110CE5 /* YTKNetworkConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3971D92178C00110CE5 /* YTKNetworkConfig.m */; }; - 343EB3A31D92178C00110CE5 /* YTKNetworkPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3991D92178C00110CE5 /* YTKNetworkPrivate.m */; }; - 343EB3A41D92178C00110CE5 /* YTKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB39B1D92178C00110CE5 /* YTKRequest.m */; }; - 343EB3A81D92180500110CE5 /* AFDownloadRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3A71D92180500110CE5 /* AFDownloadRequestOperation.m */; }; - 343EB3AB1D921E1200110CE5 /* JiaBaseRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3AA1D921E1200110CE5 /* JiaBaseRequest.m */; }; + 3411DD401D93D3CB00077FAD /* CLIColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3411DD3F1D93D3CB00077FAD /* CLIColor.m */; }; + 3411DD421D93DA4300077FAD /* XAspect-AnalyticsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3411DD411D93DA4300077FAD /* XAspect-AnalyticsAppDelegate.m */; }; + 3411DD451D93DBCD00077FAD /* JiaAnalyticsConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3411DD441D93DBCD00077FAD /* JiaAnalyticsConfigManager.m */; }; + 3411DD481D93DCD700077FAD /* JiaAnalyticsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3411DD471D93DCD700077FAD /* JiaAnalyticsHelper.m */; }; + 341F2D3D1D9A35E800379D48 /* JiaApp.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 341F2D3C1D9A35E800379D48 /* JiaApp.xcassets */; }; + 341F2D401D9A368D00379D48 /* JiaUserConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2D3F1D9A368D00379D48 /* JiaUserConfigManager.m */; }; + 341F2D441D9A373B00379D48 /* designerImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 341F2D431D9A373B00379D48 /* designerImages.xcassets */; }; + 341F2D461D9A374C00379D48 /* userImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 341F2D451D9A374C00379D48 /* userImages.xcassets */; }; + 341F2D491D9A377200379D48 /* JiaProjectConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2D481D9A377200379D48 /* JiaProjectConfigManager.m */; }; + 341F2D4D1D9A37BD00379D48 /* projectImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 341F2D4C1D9A37BD00379D48 /* projectImages.xcassets */; }; + 341F2D501D9A429C00379D48 /* DesignerDetailModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2D4F1D9A429C00379D48 /* DesignerDetailModel.m */; }; + 341F2D531D9A42B400379D48 /* DesignerHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2D521D9A42B400379D48 /* DesignerHeaderView.m */; }; 343EB3B11D9220B300110CE5 /* DesignerServiceApi.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3B01D9220B300110CE5 /* DesignerServiceApi.m */; }; 343EB3B51D92226500110CE5 /* JiaBaseRequest+App.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3B41D92226500110CE5 /* JiaBaseRequest+App.m */; }; 343EB3BB1D922BC900110CE5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 343EB3B81D922BC900110CE5 /* AppDelegate.m */; }; @@ -260,7 +261,6 @@ 3468FFE61D90D2D900A69723 /* JiaMediator.m in Sources */ = {isa = PBXBuildFile; fileRef = 3468FFE51D90D2D900A69723 /* JiaMediator.m */; }; 3468FFEE1D91541A00A69723 /* jiaDesignerConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3468FFED1D91541A00A69723 /* jiaDesignerConfigManager.m */; }; 34732A5D1D9368FB00EE0D14 /* JiaCoreConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732A5C1D9368FB00EE0D14 /* JiaCoreConfigManager.m */; }; - 34732A9F1D93781500EE0D14 /* CLIColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732A851D93781500EE0D14 /* CLIColor.m */; }; 34732AA11D93781500EE0D14 /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732A891D93781500EE0D14 /* DDAbstractDatabaseLogger.m */; }; 34732AA21D93781500EE0D14 /* DDASLLogCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732A8B1D93781500EE0D14 /* DDASLLogCapture.m */; }; 34732AA31D93781500EE0D14 /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732A8D1D93781500EE0D14 /* DDASLLogger.m */; }; @@ -273,6 +273,83 @@ 34732AAD1D93795700EE0D14 /* JiaFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732AAC1D93795700EE0D14 /* JiaFileLogger.m */; }; 34732AB01D93796F00EE0D14 /* JiaLoggerFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732AAF1D93796F00EE0D14 /* JiaLoggerFormatter.m */; }; 34732AB41D9383C300EE0D14 /* JiaCoreHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34732AB31D9383C300EE0D14 /* JiaCoreHelper.m */; }; + 3479FD051D94D9D60084C9AB /* FLEXArgumentInputColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC5F1D94D9D50084C9AB /* FLEXArgumentInputColorView.m */; }; + 3479FD061D94D9D60084C9AB /* FLEXArgumentInputDateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC611D94D9D50084C9AB /* FLEXArgumentInputDateView.m */; }; + 3479FD071D94D9D60084C9AB /* FLEXArgumentInputFontsPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC631D94D9D50084C9AB /* FLEXArgumentInputFontsPickerView.m */; }; + 3479FD081D94D9D60084C9AB /* FLEXArgumentInputFontView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC651D94D9D50084C9AB /* FLEXArgumentInputFontView.m */; }; + 3479FD091D94D9D60084C9AB /* FLEXArgumentInputJSONObjectView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC671D94D9D50084C9AB /* FLEXArgumentInputJSONObjectView.m */; }; + 3479FD0A1D94D9D60084C9AB /* FLEXArgumentInputNotSupportedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC691D94D9D50084C9AB /* FLEXArgumentInputNotSupportedView.m */; }; + 3479FD0B1D94D9D60084C9AB /* FLEXArgumentInputNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC6B1D94D9D60084C9AB /* FLEXArgumentInputNumberView.m */; }; + 3479FD0C1D94D9D60084C9AB /* FLEXArgumentInputStringView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC6D1D94D9D60084C9AB /* FLEXArgumentInputStringView.m */; }; + 3479FD0D1D94D9D60084C9AB /* FLEXArgumentInputStructView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC6F1D94D9D60084C9AB /* FLEXArgumentInputStructView.m */; }; + 3479FD0E1D94D9D60084C9AB /* FLEXArgumentInputSwitchView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC711D94D9D60084C9AB /* FLEXArgumentInputSwitchView.m */; }; + 3479FD0F1D94D9D60084C9AB /* FLEXArgumentInputTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC731D94D9D60084C9AB /* FLEXArgumentInputTextView.m */; }; + 3479FD101D94D9D60084C9AB /* FLEXArgumentInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC751D94D9D60084C9AB /* FLEXArgumentInputView.m */; }; + 3479FD111D94D9D60084C9AB /* FLEXArgumentInputViewFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC771D94D9D60084C9AB /* FLEXArgumentInputViewFactory.m */; }; + 3479FD121D94D9D60084C9AB /* FLEXDefaultEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC791D94D9D60084C9AB /* FLEXDefaultEditorViewController.m */; }; + 3479FD131D94D9D60084C9AB /* FLEXFieldEditorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC7B1D94D9D60084C9AB /* FLEXFieldEditorView.m */; }; + 3479FD141D94D9D60084C9AB /* FLEXFieldEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC7D1D94D9D60084C9AB /* FLEXFieldEditorViewController.m */; }; + 3479FD151D94D9D60084C9AB /* FLEXIvarEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC7F1D94D9D60084C9AB /* FLEXIvarEditorViewController.m */; }; + 3479FD161D94D9D60084C9AB /* FLEXMethodCallingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC811D94D9D60084C9AB /* FLEXMethodCallingViewController.m */; }; + 3479FD171D94D9D60084C9AB /* FLEXPropertyEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC831D94D9D60084C9AB /* FLEXPropertyEditorViewController.m */; }; + 3479FD181D94D9D60084C9AB /* FLEXExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC861D94D9D60084C9AB /* FLEXExplorerViewController.m */; }; + 3479FD191D94D9D60084C9AB /* FLEXWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC881D94D9D60084C9AB /* FLEXWindow.m */; }; + 3479FD1A1D94D9D60084C9AB /* FLEXMultiColumnTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC8F1D94D9D60084C9AB /* FLEXMultiColumnTableView.m */; }; + 3479FD1B1D94D9D60084C9AB /* FLEXRealmDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC911D94D9D60084C9AB /* FLEXRealmDatabaseManager.m */; }; + 3479FD1C1D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC941D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.m */; }; + 3479FD1D1D94D9D60084C9AB /* FLEXTableColumnHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC961D94D9D60084C9AB /* FLEXTableColumnHeader.m */; }; + 3479FD1E1D94D9D60084C9AB /* FLEXTableContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC981D94D9D60084C9AB /* FLEXTableContentCell.m */; }; + 3479FD1F1D94D9D60084C9AB /* FLEXTableContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC9A1D94D9D60084C9AB /* FLEXTableContentViewController.m */; }; + 3479FD201D94D9D60084C9AB /* FLEXTableLeftCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC9C1D94D9D60084C9AB /* FLEXTableLeftCell.m */; }; + 3479FD211D94D9D60084C9AB /* FLEXTableListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FC9E1D94D9D60084C9AB /* FLEXTableListViewController.m */; }; + 3479FD221D94D9D60084C9AB /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 3479FC9F1D94D9D60084C9AB /* LICENSE */; }; + 3479FD231D94D9D60084C9AB /* FLEXClassesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCA11D94D9D60084C9AB /* FLEXClassesTableViewController.m */; }; + 3479FD241D94D9D60084C9AB /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCA31D94D9D60084C9AB /* FLEXCookiesTableViewController.m */; }; + 3479FD251D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCA51D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.m */; }; + 3479FD261D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCA71D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.m */; }; + 3479FD271D94D9D60084C9AB /* FLEXFileBrowserTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCA91D94D9D60084C9AB /* FLEXFileBrowserTableViewController.m */; }; + 3479FD281D94D9D60084C9AB /* FLEXGlobalsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCAB1D94D9D60084C9AB /* FLEXGlobalsTableViewController.m */; }; + 3479FD291D94D9D60084C9AB /* FLEXInstancesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCAD1D94D9D60084C9AB /* FLEXInstancesTableViewController.m */; }; + 3479FD2A1D94D9D60084C9AB /* FLEXLibrariesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCAF1D94D9D60084C9AB /* FLEXLibrariesTableViewController.m */; }; + 3479FD2B1D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCB11D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.m */; }; + 3479FD2C1D94D9D60084C9AB /* FLEXWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCB31D94D9D60084C9AB /* FLEXWebViewController.m */; }; + 3479FD2D1D94D9D60084C9AB /* FLEXSystemLogMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCB61D94D9D60084C9AB /* FLEXSystemLogMessage.m */; }; + 3479FD2E1D94D9D60084C9AB /* FLEXSystemLogTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCB81D94D9D60084C9AB /* FLEXSystemLogTableViewCell.m */; }; + 3479FD2F1D94D9D60084C9AB /* FLEXSystemLogTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCBA1D94D9D60084C9AB /* FLEXSystemLogTableViewController.m */; }; + 3479FD301D94D9D60084C9AB /* FLEXManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCBD1D94D9D60084C9AB /* FLEXManager.m */; }; + 3479FD311D94D9D60084C9AB /* FLEXNetworkCurlLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCC01D94D9D60084C9AB /* FLEXNetworkCurlLogger.m */; }; + 3479FD321D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCC21D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.m */; }; + 3479FD331D94D9D60084C9AB /* FLEXNetworkRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCC41D94D9D60084C9AB /* FLEXNetworkRecorder.m */; }; + 3479FD341D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCC61D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.m */; }; + 3479FD351D94D9D60084C9AB /* FLEXNetworkTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCC81D94D9D60084C9AB /* FLEXNetworkTransaction.m */; }; + 3479FD361D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCCA1D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.m */; }; + 3479FD371D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCCC1D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.m */; }; + 3479FD381D94D9D60084C9AB /* FLEXNetworkObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCCF1D94D9D60084C9AB /* FLEXNetworkObserver.m */; }; + 3479FD391D94D9D60084C9AB /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 3479FCD01D94D9D60084C9AB /* LICENSE */; }; + 3479FD3A1D94D9D60084C9AB /* FLEXArrayExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCD31D94D9D60084C9AB /* FLEXArrayExplorerViewController.m */; }; + 3479FD3B1D94D9D60084C9AB /* FLEXClassExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCD51D94D9D60084C9AB /* FLEXClassExplorerViewController.m */; }; + 3479FD3C1D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCD71D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.m */; }; + 3479FD3D1D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCD91D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.m */; }; + 3479FD3E1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCDB1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.m */; }; + 3479FD3F1D94D9D60084C9AB /* FLEXImageExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCDD1D94D9D60084C9AB /* FLEXImageExplorerViewController.m */; }; + 3479FD401D94D9D60084C9AB /* FLEXLayerExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCDF1D94D9D60084C9AB /* FLEXLayerExplorerViewController.m */; }; + 3479FD411D94D9D60084C9AB /* FLEXObjectExplorerFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCE11D94D9D60084C9AB /* FLEXObjectExplorerFactory.m */; }; + 3479FD421D94D9D60084C9AB /* FLEXObjectExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCE31D94D9D60084C9AB /* FLEXObjectExplorerViewController.m */; }; + 3479FD431D94D9D60084C9AB /* FLEXSetExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCE51D94D9D60084C9AB /* FLEXSetExplorerViewController.m */; }; + 3479FD441D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCE71D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.m */; }; + 3479FD451D94D9D60084C9AB /* FLEXViewExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCE91D94D9D60084C9AB /* FLEXViewExplorerViewController.m */; }; + 3479FD461D94D9D60084C9AB /* FLEXExplorerToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCEC1D94D9D60084C9AB /* FLEXExplorerToolbar.m */; }; + 3479FD471D94D9D60084C9AB /* FLEXToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCEE1D94D9D60084C9AB /* FLEXToolbarItem.m */; }; + 3479FD481D94D9D60084C9AB /* FLEXHeapEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCF11D94D9D60084C9AB /* FLEXHeapEnumerator.m */; }; + 3479FD491D94D9D60084C9AB /* FLEXKeyboardHelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCF31D94D9D60084C9AB /* FLEXKeyboardHelpViewController.m */; }; + 3479FD4A1D94D9D60084C9AB /* FLEXKeyboardShortcutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCF51D94D9D60084C9AB /* FLEXKeyboardShortcutManager.m */; }; + 3479FD4B1D94D9D60084C9AB /* FLEXMultilineTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCF71D94D9D60084C9AB /* FLEXMultilineTableViewCell.m */; }; + 3479FD4C1D94D9D60084C9AB /* FLEXResources.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCF91D94D9D60084C9AB /* FLEXResources.m */; }; + 3479FD4D1D94D9D60084C9AB /* FLEXRuntimeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCFB1D94D9D60084C9AB /* FLEXRuntimeUtility.m */; }; + 3479FD4E1D94D9D60084C9AB /* FLEXUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FCFD1D94D9D60084C9AB /* FLEXUtility.m */; }; + 3479FD4F1D94D9D60084C9AB /* FLEXHierarchyTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FD001D94D9D60084C9AB /* FLEXHierarchyTableViewCell.m */; }; + 3479FD501D94D9D60084C9AB /* FLEXHierarchyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FD021D94D9D60084C9AB /* FLEXHierarchyTableViewController.m */; }; + 3479FD511D94D9D60084C9AB /* FLEXImagePreviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479FD041D94D9D60084C9AB /* FLEXImagePreviewViewController.m */; }; 347BAFA21D87E30200D12F0B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 347BAFA11D87E30200D12F0B /* main.m */; }; 347BAFAD1D87E30200D12F0B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 347BAFAC1D87E30200D12F0B /* Assets.xcassets */; }; 347BAFB01D87E30200D12F0B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 347BAFAE1D87E30200D12F0B /* LaunchScreen.storyboard */; }; @@ -287,7 +364,28 @@ 347BB0071D87EBB700D12F0B /* ProjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 347BB0061D87EBB700D12F0B /* ProjectViewController.m */; }; 347BB00A1D87EBD800D12F0B /* UserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 347BB0091D87EBD800D12F0B /* UserViewController.m */; }; 347BB00D1D87EBEF00D12F0B /* DesignerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 347BB00C1D87EBEF00D12F0B /* DesignerViewController.m */; }; + 34919F741D98E7AB004B7307 /* GVUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 34919F731D98E7AB004B7307 /* GVUserDefaults.m */; }; + 34919F791D98EA6E004B7307 /* JPEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 34919F771D98EA6E004B7307 /* JPEngine.m */; }; + 34919F7A1D98EA6E004B7307 /* JSPatch.js in Resources */ = {isa = PBXBuildFile; fileRef = 34919F781D98EA6E004B7307 /* JSPatch.js */; }; + 34919F901D990F1E004B7307 /* JiaPathchHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34919F8F1D990F1E004B7307 /* JiaPathchHelper.m */; }; + 34919F931D990FFE004B7307 /* JiaPathchModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 34919F921D990FFE004B7307 /* JiaPathchModel.m */; }; + 34919F961D991241004B7307 /* GVUserDefaults+JiaCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 34919F951D991241004B7307 /* GVUserDefaults+JiaCore.m */; }; 34F1A3841D88E9C400931645 /* JiaBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F1A3831D88E9C400931645 /* JiaBaseViewController.m */; }; + 34F83C951D9B58030085A540 /* YYCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C8E1D9B58030085A540 /* YYCache.m */; }; + 34F83C961D9B58030085A540 /* YYDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C901D9B58030085A540 /* YYDiskCache.m */; }; + 34F83C971D9B58030085A540 /* YYKVStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C921D9B58030085A540 /* YYKVStorage.m */; }; + 34F83C981D9B58030085A540 /* YYMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C941D9B58030085A540 /* YYMemoryCache.m */; }; + 34F83CB31D9B9EB60085A540 /* AFDownloadRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C9C1D9B9EB60085A540 /* AFDownloadRequestOperation.m */; }; + 34F83CB41D9B9EB60085A540 /* JiaBaseRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83C9E1D9B9EB60085A540 /* JiaBaseRequest.m */; }; + 34F83CB51D9B9EB60085A540 /* YTKBaseRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CA11D9B9EB60085A540 /* YTKBaseRequest.m */; }; + 34F83CB61D9B9EB60085A540 /* YTKBatchRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CA31D9B9EB60085A540 /* YTKBatchRequest.m */; }; + 34F83CB71D9B9EB60085A540 /* YTKBatchRequestAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CA51D9B9EB60085A540 /* YTKBatchRequestAgent.m */; }; + 34F83CB81D9B9EB60085A540 /* YTKChainRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CA71D9B9EB60085A540 /* YTKChainRequest.m */; }; + 34F83CB91D9B9EB60085A540 /* YTKChainRequestAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CA91D9B9EB60085A540 /* YTKChainRequestAgent.m */; }; + 34F83CBA1D9B9EB60085A540 /* YTKNetworkAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CAC1D9B9EB60085A540 /* YTKNetworkAgent.m */; }; + 34F83CBB1D9B9EB60085A540 /* YTKNetworkConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CAE1D9B9EB60085A540 /* YTKNetworkConfig.m */; }; + 34F83CBC1D9B9EB60085A540 /* YTKNetworkPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CB01D9B9EB60085A540 /* YTKNetworkPrivate.m */; }; + 34F83CBD1D9B9EB60085A540 /* YTKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F83CB21D9B9EB60085A540 /* YTKRequest.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -310,29 +408,30 @@ /* Begin PBXFileReference section */ 340C3D761D8FDD8D00E3BACD /* JiaAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaAppDelegate.h; sourceTree = ""; }; 340C3D771D8FDD8D00E3BACD /* JiaAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaAppDelegate.m; sourceTree = ""; }; - 343EB3891D92178C00110CE5 /* YTKBaseRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBaseRequest.h; sourceTree = ""; }; - 343EB38A1D92178C00110CE5 /* YTKBaseRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBaseRequest.m; sourceTree = ""; }; - 343EB38B1D92178C00110CE5 /* YTKBatchRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBatchRequest.h; sourceTree = ""; }; - 343EB38C1D92178C00110CE5 /* YTKBatchRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBatchRequest.m; sourceTree = ""; }; - 343EB38D1D92178C00110CE5 /* YTKBatchRequestAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBatchRequestAgent.h; sourceTree = ""; }; - 343EB38E1D92178C00110CE5 /* YTKBatchRequestAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBatchRequestAgent.m; sourceTree = ""; }; - 343EB38F1D92178C00110CE5 /* YTKChainRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKChainRequest.h; sourceTree = ""; }; - 343EB3901D92178C00110CE5 /* YTKChainRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKChainRequest.m; sourceTree = ""; }; - 343EB3911D92178C00110CE5 /* YTKChainRequestAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKChainRequestAgent.h; sourceTree = ""; }; - 343EB3921D92178C00110CE5 /* YTKChainRequestAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKChainRequestAgent.m; sourceTree = ""; }; - 343EB3931D92178C00110CE5 /* YTKNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetwork.h; sourceTree = ""; }; - 343EB3941D92178C00110CE5 /* YTKNetworkAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkAgent.h; sourceTree = ""; }; - 343EB3951D92178C00110CE5 /* YTKNetworkAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkAgent.m; sourceTree = ""; }; - 343EB3961D92178C00110CE5 /* YTKNetworkConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkConfig.h; sourceTree = ""; }; - 343EB3971D92178C00110CE5 /* YTKNetworkConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkConfig.m; sourceTree = ""; }; - 343EB3981D92178C00110CE5 /* YTKNetworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkPrivate.h; sourceTree = ""; }; - 343EB3991D92178C00110CE5 /* YTKNetworkPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkPrivate.m; sourceTree = ""; }; - 343EB39A1D92178C00110CE5 /* YTKRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKRequest.h; sourceTree = ""; }; - 343EB39B1D92178C00110CE5 /* YTKRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKRequest.m; sourceTree = ""; }; - 343EB3A61D92180500110CE5 /* AFDownloadRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFDownloadRequestOperation.h; sourceTree = ""; }; - 343EB3A71D92180500110CE5 /* AFDownloadRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFDownloadRequestOperation.m; sourceTree = ""; }; - 343EB3A91D921E1200110CE5 /* JiaBaseRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaBaseRequest.h; sourceTree = ""; }; - 343EB3AA1D921E1200110CE5 /* JiaBaseRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaBaseRequest.m; sourceTree = ""; }; + 3411DD3B1D93AE8D00077FAD /* JiaMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaMacros.h; sourceTree = ""; }; + 3411DD3E1D93D3CB00077FAD /* CLIColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLIColor.h; sourceTree = ""; }; + 3411DD3F1D93D3CB00077FAD /* CLIColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLIColor.m; sourceTree = ""; }; + 3411DD411D93DA4300077FAD /* XAspect-AnalyticsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XAspect-AnalyticsAppDelegate.m"; sourceTree = ""; }; + 3411DD431D93DBCD00077FAD /* JiaAnalyticsConfigManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaAnalyticsConfigManager.h; sourceTree = ""; }; + 3411DD441D93DBCD00077FAD /* JiaAnalyticsConfigManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaAnalyticsConfigManager.m; sourceTree = ""; }; + 3411DD461D93DCD700077FAD /* JiaAnalyticsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaAnalyticsHelper.h; sourceTree = ""; }; + 3411DD471D93DCD700077FAD /* JiaAnalyticsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaAnalyticsHelper.m; sourceTree = ""; }; + 341F2D3C1D9A35E800379D48 /* JiaApp.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = JiaApp.xcassets; sourceTree = ""; }; + 341F2D3E1D9A368D00379D48 /* JiaUserConfigManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaUserConfigManager.h; sourceTree = ""; }; + 341F2D3F1D9A368D00379D48 /* JiaUserConfigManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaUserConfigManager.m; sourceTree = ""; }; + 341F2D411D9A36B800379D48 /* userModulePrefixHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = userModulePrefixHeader.h; sourceTree = ""; }; + 341F2D421D9A36DD00379D48 /* userModuleMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = userModuleMacros.h; sourceTree = ""; }; + 341F2D431D9A373B00379D48 /* designerImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = designerImages.xcassets; sourceTree = ""; }; + 341F2D451D9A374C00379D48 /* userImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = userImages.xcassets; sourceTree = ""; }; + 341F2D471D9A377200379D48 /* JiaProjectConfigManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaProjectConfigManager.h; sourceTree = ""; }; + 341F2D481D9A377200379D48 /* JiaProjectConfigManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaProjectConfigManager.m; sourceTree = ""; }; + 341F2D4A1D9A378A00379D48 /* projectModuleMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = projectModuleMacros.h; sourceTree = ""; }; + 341F2D4B1D9A37A700379D48 /* projectModulePrefixHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = projectModulePrefixHeader.h; sourceTree = ""; }; + 341F2D4C1D9A37BD00379D48 /* projectImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = projectImages.xcassets; sourceTree = ""; }; + 341F2D4E1D9A429C00379D48 /* DesignerDetailModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DesignerDetailModel.h; sourceTree = ""; }; + 341F2D4F1D9A429C00379D48 /* DesignerDetailModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DesignerDetailModel.m; sourceTree = ""; }; + 341F2D511D9A42B400379D48 /* DesignerHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DesignerHeaderView.h; sourceTree = ""; }; + 341F2D521D9A42B400379D48 /* DesignerHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DesignerHeaderView.m; sourceTree = ""; }; 343EB3AF1D9220B300110CE5 /* DesignerServiceApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DesignerServiceApi.h; sourceTree = ""; }; 343EB3B01D9220B300110CE5 /* DesignerServiceApi.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DesignerServiceApi.m; sourceTree = ""; }; 343EB3B31D92226500110CE5 /* JiaBaseRequest+App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JiaBaseRequest+App.h"; sourceTree = ""; }; @@ -778,7 +877,6 @@ 343EB6BD1D92568700110CE5 /* XAspect-GeTuiAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XAspect-GeTuiAppDelegate.m"; sourceTree = ""; }; 346800101D915AA500A69723 /* designerModulePrefixHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = designerModulePrefixHeader.h; sourceTree = ""; }; 346800111D915B8B00A69723 /* designerModuleMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = designerModuleMacros.h; sourceTree = ""; }; - 346800121D915C4D00A69723 /* JiaMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JiaMacros.h; sourceTree = ""; }; 3468FFB21D90CA1A00A69723 /* MBProgressHUD+MP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MBProgressHUD+MP.h"; sourceTree = ""; }; 3468FFB31D90CA1A00A69723 /* MBProgressHUD+MP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MBProgressHUD+MP.m"; sourceTree = ""; }; 3468FFB41D90CA1A00A69723 /* MBProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBProgressHUD.h; sourceTree = ""; }; @@ -816,8 +914,6 @@ 3471536C1D8F9E4700BDB632 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 34732A5B1D9368FB00EE0D14 /* JiaCoreConfigManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaCoreConfigManager.h; sourceTree = ""; }; 34732A5C1D9368FB00EE0D14 /* JiaCoreConfigManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaCoreConfigManager.m; sourceTree = ""; }; - 34732A841D93781500EE0D14 /* CLIColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLIColor.h; sourceTree = ""; }; - 34732A851D93781500EE0D14 /* CLIColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLIColor.m; sourceTree = ""; }; 34732A881D93781500EE0D14 /* DDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDAbstractDatabaseLogger.h; sourceTree = ""; }; 34732A891D93781500EE0D14 /* DDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDAbstractDatabaseLogger.m; sourceTree = ""; }; 34732A8A1D93781500EE0D14 /* DDASLLogCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDASLLogCapture.h; sourceTree = ""; }; @@ -847,6 +943,162 @@ 34732AB11D937B9D00EE0D14 /* JiaCocoaLumberjack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JiaCocoaLumberjack.h; sourceTree = ""; }; 34732AB21D9383C300EE0D14 /* JiaCoreHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaCoreHelper.h; sourceTree = ""; }; 34732AB31D9383C300EE0D14 /* JiaCoreHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaCoreHelper.m; sourceTree = ""; }; + 3479FC5E1D94D9D50084C9AB /* FLEXArgumentInputColorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputColorView.h; sourceTree = ""; }; + 3479FC5F1D94D9D50084C9AB /* FLEXArgumentInputColorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputColorView.m; sourceTree = ""; }; + 3479FC601D94D9D50084C9AB /* FLEXArgumentInputDateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputDateView.h; sourceTree = ""; }; + 3479FC611D94D9D50084C9AB /* FLEXArgumentInputDateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputDateView.m; sourceTree = ""; }; + 3479FC621D94D9D50084C9AB /* FLEXArgumentInputFontsPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputFontsPickerView.h; sourceTree = ""; }; + 3479FC631D94D9D50084C9AB /* FLEXArgumentInputFontsPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputFontsPickerView.m; sourceTree = ""; }; + 3479FC641D94D9D50084C9AB /* FLEXArgumentInputFontView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputFontView.h; sourceTree = ""; }; + 3479FC651D94D9D50084C9AB /* FLEXArgumentInputFontView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputFontView.m; sourceTree = ""; }; + 3479FC661D94D9D50084C9AB /* FLEXArgumentInputJSONObjectView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputJSONObjectView.h; sourceTree = ""; }; + 3479FC671D94D9D50084C9AB /* FLEXArgumentInputJSONObjectView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputJSONObjectView.m; sourceTree = ""; }; + 3479FC681D94D9D50084C9AB /* FLEXArgumentInputNotSupportedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputNotSupportedView.h; sourceTree = ""; }; + 3479FC691D94D9D50084C9AB /* FLEXArgumentInputNotSupportedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputNotSupportedView.m; sourceTree = ""; }; + 3479FC6A1D94D9D50084C9AB /* FLEXArgumentInputNumberView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputNumberView.h; sourceTree = ""; }; + 3479FC6B1D94D9D60084C9AB /* FLEXArgumentInputNumberView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputNumberView.m; sourceTree = ""; }; + 3479FC6C1D94D9D60084C9AB /* FLEXArgumentInputStringView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputStringView.h; sourceTree = ""; }; + 3479FC6D1D94D9D60084C9AB /* FLEXArgumentInputStringView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputStringView.m; sourceTree = ""; }; + 3479FC6E1D94D9D60084C9AB /* FLEXArgumentInputStructView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputStructView.h; sourceTree = ""; }; + 3479FC6F1D94D9D60084C9AB /* FLEXArgumentInputStructView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputStructView.m; sourceTree = ""; }; + 3479FC701D94D9D60084C9AB /* FLEXArgumentInputSwitchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputSwitchView.h; sourceTree = ""; }; + 3479FC711D94D9D60084C9AB /* FLEXArgumentInputSwitchView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputSwitchView.m; sourceTree = ""; }; + 3479FC721D94D9D60084C9AB /* FLEXArgumentInputTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputTextView.h; sourceTree = ""; }; + 3479FC731D94D9D60084C9AB /* FLEXArgumentInputTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputTextView.m; sourceTree = ""; }; + 3479FC741D94D9D60084C9AB /* FLEXArgumentInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputView.h; sourceTree = ""; }; + 3479FC751D94D9D60084C9AB /* FLEXArgumentInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputView.m; sourceTree = ""; }; + 3479FC761D94D9D60084C9AB /* FLEXArgumentInputViewFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputViewFactory.h; sourceTree = ""; }; + 3479FC771D94D9D60084C9AB /* FLEXArgumentInputViewFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputViewFactory.m; sourceTree = ""; }; + 3479FC781D94D9D60084C9AB /* FLEXDefaultEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDefaultEditorViewController.h; sourceTree = ""; }; + 3479FC791D94D9D60084C9AB /* FLEXDefaultEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDefaultEditorViewController.m; sourceTree = ""; }; + 3479FC7A1D94D9D60084C9AB /* FLEXFieldEditorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFieldEditorView.h; sourceTree = ""; }; + 3479FC7B1D94D9D60084C9AB /* FLEXFieldEditorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFieldEditorView.m; sourceTree = ""; }; + 3479FC7C1D94D9D60084C9AB /* FLEXFieldEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFieldEditorViewController.h; sourceTree = ""; }; + 3479FC7D1D94D9D60084C9AB /* FLEXFieldEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFieldEditorViewController.m; sourceTree = ""; }; + 3479FC7E1D94D9D60084C9AB /* FLEXIvarEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXIvarEditorViewController.h; sourceTree = ""; }; + 3479FC7F1D94D9D60084C9AB /* FLEXIvarEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXIvarEditorViewController.m; sourceTree = ""; }; + 3479FC801D94D9D60084C9AB /* FLEXMethodCallingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethodCallingViewController.h; sourceTree = ""; }; + 3479FC811D94D9D60084C9AB /* FLEXMethodCallingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMethodCallingViewController.m; sourceTree = ""; }; + 3479FC821D94D9D60084C9AB /* FLEXPropertyEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXPropertyEditorViewController.h; sourceTree = ""; }; + 3479FC831D94D9D60084C9AB /* FLEXPropertyEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXPropertyEditorViewController.m; sourceTree = ""; }; + 3479FC851D94D9D60084C9AB /* FLEXExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerViewController.h; sourceTree = ""; }; + 3479FC861D94D9D60084C9AB /* FLEXExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXExplorerViewController.m; sourceTree = ""; }; + 3479FC871D94D9D60084C9AB /* FLEXWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXWindow.h; sourceTree = ""; }; + 3479FC881D94D9D60084C9AB /* FLEXWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXWindow.m; sourceTree = ""; }; + 3479FC891D94D9D60084C9AB /* FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEX.h; sourceTree = ""; }; + 3479FC8A1D94D9D60084C9AB /* FLEXManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXManager.h; sourceTree = ""; }; + 3479FC8D1D94D9D60084C9AB /* FLEXDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDatabaseManager.h; sourceTree = ""; }; + 3479FC8E1D94D9D60084C9AB /* FLEXMultiColumnTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultiColumnTableView.h; sourceTree = ""; }; + 3479FC8F1D94D9D60084C9AB /* FLEXMultiColumnTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultiColumnTableView.m; sourceTree = ""; }; + 3479FC901D94D9D60084C9AB /* FLEXRealmDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDatabaseManager.h; sourceTree = ""; }; + 3479FC911D94D9D60084C9AB /* FLEXRealmDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRealmDatabaseManager.m; sourceTree = ""; }; + 3479FC921D94D9D60084C9AB /* FLEXRealmDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDefines.h; sourceTree = ""; }; + 3479FC931D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSQLiteDatabaseManager.h; sourceTree = ""; }; + 3479FC941D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSQLiteDatabaseManager.m; sourceTree = ""; }; + 3479FC951D94D9D60084C9AB /* FLEXTableColumnHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableColumnHeader.h; sourceTree = ""; }; + 3479FC961D94D9D60084C9AB /* FLEXTableColumnHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableColumnHeader.m; sourceTree = ""; }; + 3479FC971D94D9D60084C9AB /* FLEXTableContentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentCell.h; sourceTree = ""; }; + 3479FC981D94D9D60084C9AB /* FLEXTableContentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentCell.m; sourceTree = ""; }; + 3479FC991D94D9D60084C9AB /* FLEXTableContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentViewController.h; sourceTree = ""; }; + 3479FC9A1D94D9D60084C9AB /* FLEXTableContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentViewController.m; sourceTree = ""; }; + 3479FC9B1D94D9D60084C9AB /* FLEXTableLeftCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableLeftCell.h; sourceTree = ""; }; + 3479FC9C1D94D9D60084C9AB /* FLEXTableLeftCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableLeftCell.m; sourceTree = ""; }; + 3479FC9D1D94D9D60084C9AB /* FLEXTableListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableListViewController.h; sourceTree = ""; }; + 3479FC9E1D94D9D60084C9AB /* FLEXTableListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableListViewController.m; sourceTree = ""; }; + 3479FC9F1D94D9D60084C9AB /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 3479FCA01D94D9D60084C9AB /* FLEXClassesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXClassesTableViewController.h; sourceTree = ""; }; + 3479FCA11D94D9D60084C9AB /* FLEXClassesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXClassesTableViewController.m; sourceTree = ""; }; + 3479FCA21D94D9D60084C9AB /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = ""; }; + 3479FCA31D94D9D60084C9AB /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = ""; }; + 3479FCA41D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFileBrowserFileOperationController.h; sourceTree = ""; }; + 3479FCA51D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserFileOperationController.m; sourceTree = ""; }; + 3479FCA61D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFileBrowserSearchOperation.h; sourceTree = ""; }; + 3479FCA71D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserSearchOperation.m; sourceTree = ""; }; + 3479FCA81D94D9D60084C9AB /* FLEXFileBrowserTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFileBrowserTableViewController.h; sourceTree = ""; }; + 3479FCA91D94D9D60084C9AB /* FLEXFileBrowserTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserTableViewController.m; sourceTree = ""; }; + 3479FCAA1D94D9D60084C9AB /* FLEXGlobalsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsTableViewController.h; sourceTree = ""; }; + 3479FCAB1D94D9D60084C9AB /* FLEXGlobalsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXGlobalsTableViewController.m; sourceTree = ""; }; + 3479FCAC1D94D9D60084C9AB /* FLEXInstancesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXInstancesTableViewController.h; sourceTree = ""; }; + 3479FCAD1D94D9D60084C9AB /* FLEXInstancesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXInstancesTableViewController.m; sourceTree = ""; }; + 3479FCAE1D94D9D60084C9AB /* FLEXLibrariesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLibrariesTableViewController.h; sourceTree = ""; }; + 3479FCAF1D94D9D60084C9AB /* FLEXLibrariesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXLibrariesTableViewController.m; sourceTree = ""; }; + 3479FCB01D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLiveObjectsTableViewController.h; sourceTree = ""; }; + 3479FCB11D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXLiveObjectsTableViewController.m; sourceTree = ""; }; + 3479FCB21D94D9D60084C9AB /* FLEXWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXWebViewController.h; sourceTree = ""; }; + 3479FCB31D94D9D60084C9AB /* FLEXWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXWebViewController.m; sourceTree = ""; }; + 3479FCB51D94D9D60084C9AB /* FLEXSystemLogMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogMessage.h; sourceTree = ""; }; + 3479FCB61D94D9D60084C9AB /* FLEXSystemLogMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogMessage.m; sourceTree = ""; }; + 3479FCB71D94D9D60084C9AB /* FLEXSystemLogTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogTableViewCell.h; sourceTree = ""; }; + 3479FCB81D94D9D60084C9AB /* FLEXSystemLogTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogTableViewCell.m; sourceTree = ""; }; + 3479FCB91D94D9D60084C9AB /* FLEXSystemLogTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogTableViewController.h; sourceTree = ""; }; + 3479FCBA1D94D9D60084C9AB /* FLEXSystemLogTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogTableViewController.m; sourceTree = ""; }; + 3479FCBC1D94D9D60084C9AB /* FLEXManager+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Private.h"; sourceTree = ""; }; + 3479FCBD1D94D9D60084C9AB /* FLEXManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXManager.m; sourceTree = ""; }; + 3479FCBF1D94D9D60084C9AB /* FLEXNetworkCurlLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkCurlLogger.h; sourceTree = ""; }; + 3479FCC01D94D9D60084C9AB /* FLEXNetworkCurlLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkCurlLogger.m; sourceTree = ""; }; + 3479FCC11D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkHistoryTableViewController.h; sourceTree = ""; }; + 3479FCC21D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkHistoryTableViewController.m; sourceTree = ""; }; + 3479FCC31D94D9D60084C9AB /* FLEXNetworkRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkRecorder.h; sourceTree = ""; }; + 3479FCC41D94D9D60084C9AB /* FLEXNetworkRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkRecorder.m; sourceTree = ""; }; + 3479FCC51D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkSettingsTableViewController.h; sourceTree = ""; }; + 3479FCC61D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkSettingsTableViewController.m; sourceTree = ""; }; + 3479FCC71D94D9D60084C9AB /* FLEXNetworkTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkTransaction.h; sourceTree = ""; }; + 3479FCC81D94D9D60084C9AB /* FLEXNetworkTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkTransaction.m; sourceTree = ""; }; + 3479FCC91D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkTransactionDetailTableViewController.h; sourceTree = ""; }; + 3479FCCA1D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkTransactionDetailTableViewController.m; sourceTree = ""; }; + 3479FCCB1D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkTransactionTableViewCell.h; sourceTree = ""; }; + 3479FCCC1D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkTransactionTableViewCell.m; sourceTree = ""; }; + 3479FCCE1D94D9D60084C9AB /* FLEXNetworkObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkObserver.h; sourceTree = ""; }; + 3479FCCF1D94D9D60084C9AB /* FLEXNetworkObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkObserver.m; sourceTree = ""; }; + 3479FCD01D94D9D60084C9AB /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 3479FCD21D94D9D60084C9AB /* FLEXArrayExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArrayExplorerViewController.h; sourceTree = ""; }; + 3479FCD31D94D9D60084C9AB /* FLEXArrayExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArrayExplorerViewController.m; sourceTree = ""; }; + 3479FCD41D94D9D60084C9AB /* FLEXClassExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXClassExplorerViewController.h; sourceTree = ""; }; + 3479FCD51D94D9D60084C9AB /* FLEXClassExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXClassExplorerViewController.m; sourceTree = ""; }; + 3479FCD61D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDefaultsExplorerViewController.h; sourceTree = ""; }; + 3479FCD71D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDefaultsExplorerViewController.m; sourceTree = ""; }; + 3479FCD81D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDictionaryExplorerViewController.h; sourceTree = ""; }; + 3479FCD91D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDictionaryExplorerViewController.m; sourceTree = ""; }; + 3479FCDA1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsTableViewControllerEntry.h; sourceTree = ""; }; + 3479FCDB1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXGlobalsTableViewControllerEntry.m; sourceTree = ""; }; + 3479FCDC1D94D9D60084C9AB /* FLEXImageExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXImageExplorerViewController.h; sourceTree = ""; }; + 3479FCDD1D94D9D60084C9AB /* FLEXImageExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXImageExplorerViewController.m; sourceTree = ""; }; + 3479FCDE1D94D9D60084C9AB /* FLEXLayerExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLayerExplorerViewController.h; sourceTree = ""; }; + 3479FCDF1D94D9D60084C9AB /* FLEXLayerExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXLayerExplorerViewController.m; sourceTree = ""; }; + 3479FCE01D94D9D60084C9AB /* FLEXObjectExplorerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerFactory.h; sourceTree = ""; }; + 3479FCE11D94D9D60084C9AB /* FLEXObjectExplorerFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectExplorerFactory.m; sourceTree = ""; }; + 3479FCE21D94D9D60084C9AB /* FLEXObjectExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerViewController.h; sourceTree = ""; }; + 3479FCE31D94D9D60084C9AB /* FLEXObjectExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectExplorerViewController.m; sourceTree = ""; }; + 3479FCE41D94D9D60084C9AB /* FLEXSetExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSetExplorerViewController.h; sourceTree = ""; }; + 3479FCE51D94D9D60084C9AB /* FLEXSetExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSetExplorerViewController.m; sourceTree = ""; }; + 3479FCE61D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXViewControllerExplorerViewController.h; sourceTree = ""; }; + 3479FCE71D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewControllerExplorerViewController.m; sourceTree = ""; }; + 3479FCE81D94D9D60084C9AB /* FLEXViewExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXViewExplorerViewController.h; sourceTree = ""; }; + 3479FCE91D94D9D60084C9AB /* FLEXViewExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewExplorerViewController.m; sourceTree = ""; }; + 3479FCEB1D94D9D60084C9AB /* FLEXExplorerToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerToolbar.h; sourceTree = ""; }; + 3479FCEC1D94D9D60084C9AB /* FLEXExplorerToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXExplorerToolbar.m; sourceTree = ""; }; + 3479FCED1D94D9D60084C9AB /* FLEXToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXToolbarItem.h; sourceTree = ""; }; + 3479FCEE1D94D9D60084C9AB /* FLEXToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXToolbarItem.m; sourceTree = ""; }; + 3479FCF01D94D9D60084C9AB /* FLEXHeapEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHeapEnumerator.h; sourceTree = ""; }; + 3479FCF11D94D9D60084C9AB /* FLEXHeapEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHeapEnumerator.m; sourceTree = ""; }; + 3479FCF21D94D9D60084C9AB /* FLEXKeyboardHelpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardHelpViewController.h; sourceTree = ""; }; + 3479FCF31D94D9D60084C9AB /* FLEXKeyboardHelpViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardHelpViewController.m; sourceTree = ""; }; + 3479FCF41D94D9D60084C9AB /* FLEXKeyboardShortcutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardShortcutManager.h; sourceTree = ""; }; + 3479FCF51D94D9D60084C9AB /* FLEXKeyboardShortcutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardShortcutManager.m; sourceTree = ""; }; + 3479FCF61D94D9D60084C9AB /* FLEXMultilineTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultilineTableViewCell.h; sourceTree = ""; }; + 3479FCF71D94D9D60084C9AB /* FLEXMultilineTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultilineTableViewCell.m; sourceTree = ""; }; + 3479FCF81D94D9D60084C9AB /* FLEXResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXResources.h; sourceTree = ""; }; + 3479FCF91D94D9D60084C9AB /* FLEXResources.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXResources.m; sourceTree = ""; }; + 3479FCFA1D94D9D60084C9AB /* FLEXRuntimeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeUtility.h; sourceTree = ""; }; + 3479FCFB1D94D9D60084C9AB /* FLEXRuntimeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeUtility.m; sourceTree = ""; }; + 3479FCFC1D94D9D60084C9AB /* FLEXUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXUtility.h; sourceTree = ""; }; + 3479FCFD1D94D9D60084C9AB /* FLEXUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXUtility.m; sourceTree = ""; }; + 3479FCFF1D94D9D60084C9AB /* FLEXHierarchyTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHierarchyTableViewCell.h; sourceTree = ""; }; + 3479FD001D94D9D60084C9AB /* FLEXHierarchyTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHierarchyTableViewCell.m; sourceTree = ""; }; + 3479FD011D94D9D60084C9AB /* FLEXHierarchyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHierarchyTableViewController.h; sourceTree = ""; }; + 3479FD021D94D9D60084C9AB /* FLEXHierarchyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHierarchyTableViewController.m; sourceTree = ""; }; + 3479FD031D94D9D60084C9AB /* FLEXImagePreviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXImagePreviewViewController.h; sourceTree = ""; }; + 3479FD041D94D9D60084C9AB /* FLEXImagePreviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXImagePreviewViewController.m; sourceTree = ""; }; 347BAF9D1D87E30200D12F0B /* jiaModuleDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = jiaModuleDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 347BAFA11D87E30200D12F0B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 347BAFAC1D87E30200D12F0B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -876,9 +1128,53 @@ 347BB0091D87EBD800D12F0B /* UserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserViewController.m; sourceTree = ""; }; 347BB00B1D87EBEF00D12F0B /* DesignerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DesignerViewController.h; sourceTree = ""; }; 347BB00C1D87EBEF00D12F0B /* DesignerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DesignerViewController.m; sourceTree = ""; }; + 34919F721D98E7AB004B7307 /* GVUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GVUserDefaults.h; sourceTree = ""; }; + 34919F731D98E7AB004B7307 /* GVUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GVUserDefaults.m; sourceTree = ""; }; + 34919F761D98EA6E004B7307 /* JPEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JPEngine.h; sourceTree = ""; }; + 34919F771D98EA6E004B7307 /* JPEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JPEngine.m; sourceTree = ""; }; + 34919F781D98EA6E004B7307 /* JSPatch.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSPatch.js; sourceTree = ""; }; + 34919F7B1D98EAB0004B7307 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + 34919F8E1D990F1E004B7307 /* JiaPathchHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaPathchHelper.h; sourceTree = ""; }; + 34919F8F1D990F1E004B7307 /* JiaPathchHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaPathchHelper.m; sourceTree = ""; }; + 34919F911D990FFE004B7307 /* JiaPathchModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaPathchModel.h; sourceTree = ""; }; + 34919F921D990FFE004B7307 /* JiaPathchModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaPathchModel.m; sourceTree = ""; }; + 34919F941D991241004B7307 /* GVUserDefaults+JiaCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GVUserDefaults+JiaCore.h"; sourceTree = ""; }; + 34919F951D991241004B7307 /* GVUserDefaults+JiaCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GVUserDefaults+JiaCore.m"; sourceTree = ""; }; 34F1A3811D88E00100931645 /* headerDesignerConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = headerDesignerConfig.h; sourceTree = ""; }; 34F1A3821D88E9C400931645 /* JiaBaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaBaseViewController.h; sourceTree = ""; }; 34F1A3831D88E9C400931645 /* JiaBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaBaseViewController.m; sourceTree = ""; }; + 34F83C8D1D9B58030085A540 /* YYCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYCache.h; sourceTree = ""; }; + 34F83C8E1D9B58030085A540 /* YYCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYCache.m; sourceTree = ""; }; + 34F83C8F1D9B58030085A540 /* YYDiskCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYDiskCache.h; sourceTree = ""; }; + 34F83C901D9B58030085A540 /* YYDiskCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYDiskCache.m; sourceTree = ""; }; + 34F83C911D9B58030085A540 /* YYKVStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYKVStorage.h; sourceTree = ""; }; + 34F83C921D9B58030085A540 /* YYKVStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYKVStorage.m; sourceTree = ""; }; + 34F83C931D9B58030085A540 /* YYMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYMemoryCache.h; sourceTree = ""; }; + 34F83C941D9B58030085A540 /* YYMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYMemoryCache.m; sourceTree = ""; }; + 34F83C9B1D9B9EB60085A540 /* AFDownloadRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFDownloadRequestOperation.h; sourceTree = ""; }; + 34F83C9C1D9B9EB60085A540 /* AFDownloadRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFDownloadRequestOperation.m; sourceTree = ""; }; + 34F83C9D1D9B9EB60085A540 /* JiaBaseRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JiaBaseRequest.h; sourceTree = ""; }; + 34F83C9E1D9B9EB60085A540 /* JiaBaseRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JiaBaseRequest.m; sourceTree = ""; }; + 34F83CA01D9B9EB60085A540 /* YTKBaseRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBaseRequest.h; sourceTree = ""; }; + 34F83CA11D9B9EB60085A540 /* YTKBaseRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBaseRequest.m; sourceTree = ""; }; + 34F83CA21D9B9EB60085A540 /* YTKBatchRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBatchRequest.h; sourceTree = ""; }; + 34F83CA31D9B9EB60085A540 /* YTKBatchRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBatchRequest.m; sourceTree = ""; }; + 34F83CA41D9B9EB60085A540 /* YTKBatchRequestAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKBatchRequestAgent.h; sourceTree = ""; }; + 34F83CA51D9B9EB60085A540 /* YTKBatchRequestAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKBatchRequestAgent.m; sourceTree = ""; }; + 34F83CA61D9B9EB60085A540 /* YTKChainRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKChainRequest.h; sourceTree = ""; }; + 34F83CA71D9B9EB60085A540 /* YTKChainRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKChainRequest.m; sourceTree = ""; }; + 34F83CA81D9B9EB60085A540 /* YTKChainRequestAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKChainRequestAgent.h; sourceTree = ""; }; + 34F83CA91D9B9EB60085A540 /* YTKChainRequestAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKChainRequestAgent.m; sourceTree = ""; }; + 34F83CAA1D9B9EB60085A540 /* YTKNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetwork.h; sourceTree = ""; }; + 34F83CAB1D9B9EB60085A540 /* YTKNetworkAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkAgent.h; sourceTree = ""; }; + 34F83CAC1D9B9EB60085A540 /* YTKNetworkAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkAgent.m; sourceTree = ""; }; + 34F83CAD1D9B9EB60085A540 /* YTKNetworkConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkConfig.h; sourceTree = ""; }; + 34F83CAE1D9B9EB60085A540 /* YTKNetworkConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkConfig.m; sourceTree = ""; }; + 34F83CAF1D9B9EB60085A540 /* YTKNetworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKNetworkPrivate.h; sourceTree = ""; }; + 34F83CB01D9B9EB60085A540 /* YTKNetworkPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKNetworkPrivate.m; sourceTree = ""; }; + 34F83CB11D9B9EB60085A540 /* YTKRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKRequest.h; sourceTree = ""; }; + 34F83CB21D9B9EB60085A540 /* YTKRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKRequest.m; sourceTree = ""; }; + 34F83CBE1D9B9F080085A540 /* JiaCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JiaCore.h; sourceTree = ""; }; 6109480D64D9F6F4E2BC07CB /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 824044CE8FBFAABF378217B6 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; CB0B006C172C1CEDD518B1F6 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -922,13 +1218,33 @@ path = JiaGT; sourceTree = ""; }; - 343EB3A51D9217DE00110CE5 /* AFDownloadRequestOperation */ = { + 3411DD3A1D93AE8D00077FAD /* JiaMacros */ = { isa = PBXGroup; children = ( - 343EB3A61D92180500110CE5 /* AFDownloadRequestOperation.h */, - 343EB3A71D92180500110CE5 /* AFDownloadRequestOperation.m */, + 3411DD3B1D93AE8D00077FAD /* JiaMacros.h */, ); - path = AFDownloadRequestOperation; + path = JiaMacros; + sourceTree = ""; + }; + 3411DD3C1D93D2DC00077FAD /* JiaAnalytics */ = { + isa = PBXGroup; + children = ( + 3411DD411D93DA4300077FAD /* XAspect-AnalyticsAppDelegate.m */, + 3411DD431D93DBCD00077FAD /* JiaAnalyticsConfigManager.h */, + 3411DD441D93DBCD00077FAD /* JiaAnalyticsConfigManager.m */, + 3411DD461D93DCD700077FAD /* JiaAnalyticsHelper.h */, + 3411DD471D93DCD700077FAD /* JiaAnalyticsHelper.m */, + ); + path = JiaAnalytics; + sourceTree = ""; + }; + 3411DD3D1D93D3CB00077FAD /* CLI */ = { + isa = PBXGroup; + children = ( + 3411DD3E1D93D3CB00077FAD /* CLIColor.h */, + 3411DD3F1D93D3CB00077FAD /* CLIColor.m */, + ); + path = CLI; sourceTree = ""; }; 343EB3B21D9221FB00110CE5 /* App */ = { @@ -941,6 +1257,7 @@ 343EB3B31D92226500110CE5 /* JiaBaseRequest+App.h */, 343EB3B41D92226500110CE5 /* JiaBaseRequest+App.m */, 343EB3B61D9228A400110CE5 /* AppPrefixHeader.pch */, + 341F2D3C1D9A35E800379D48 /* JiaApp.xcassets */, ); path = App; sourceTree = ""; @@ -1900,13 +2217,14 @@ 3468FFAF1D90C5D700A69723 /* JiaCoreHelper */ = { isa = PBXGroup; children = ( + 34919F801D990134004B7307 /* JiaPathchHelper */, 34732AAA1D93790F00EE0D14 /* JiaLoggerHelper */, - 343EB3A91D921E1200110CE5 /* JiaBaseRequest.h */, - 343EB3AA1D921E1200110CE5 /* JiaBaseRequest.m */, 34732A5B1D9368FB00EE0D14 /* JiaCoreConfigManager.h */, 34732A5C1D9368FB00EE0D14 /* JiaCoreConfigManager.m */, 34732AB21D9383C300EE0D14 /* JiaCoreHelper.h */, 34732AB31D9383C300EE0D14 /* JiaCoreHelper.m */, + 34919F941D991241004B7307 /* GVUserDefaults+JiaCore.h */, + 34919F951D991241004B7307 /* GVUserDefaults+JiaCore.m */, ); path = JiaCoreHelper; sourceTree = ""; @@ -1914,6 +2232,11 @@ 3468FFB01D90C9DE00A69723 /* JiaCoreTool */ = { isa = PBXGroup; children = ( + 34F83C991D9B9EB60085A540 /* JiaNewWork */, + 34F83C8C1D9B58030085A540 /* YYCache */, + 34919F751D98EA6E004B7307 /* JSPatch */, + 34919F711D98E7AB004B7307 /* GVUserDefaults */, + 3479FC5B1D94D9A70084C9AB /* FLEX */, 34732A5E1D93772C00EE0D14 /* CocoaLumberjack */, 3468FFB11D90CA1A00A69723 /* MBProgressHUD */, 3468FFB61D90CA1A00A69723 /* RealReachability */, @@ -2001,6 +2324,7 @@ 3468FFE71D90EE7500A69723 /* Resource */ = { isa = PBXGroup; children = ( + 341F2D431D9A373B00379D48 /* designerImages.xcassets */, ); path = Resource; sourceTree = ""; @@ -2008,6 +2332,10 @@ 3468FFE81D90EF0000A69723 /* Other */ = { isa = PBXGroup; children = ( + 341F2D3E1D9A368D00379D48 /* JiaUserConfigManager.h */, + 341F2D3F1D9A368D00379D48 /* JiaUserConfigManager.m */, + 341F2D411D9A36B800379D48 /* userModulePrefixHeader.h */, + 341F2D421D9A36DD00379D48 /* userModuleMacros.h */, ); path = Other; sourceTree = ""; @@ -2015,6 +2343,7 @@ 3468FFE91D90EF1400A69723 /* Resource */ = { isa = PBXGroup; children = ( + 341F2D451D9A374C00379D48 /* userImages.xcassets */, ); path = Resource; sourceTree = ""; @@ -2022,6 +2351,10 @@ 3468FFEA1D90EF2E00A69723 /* Other */ = { isa = PBXGroup; children = ( + 341F2D471D9A377200379D48 /* JiaProjectConfigManager.h */, + 341F2D481D9A377200379D48 /* JiaProjectConfigManager.m */, + 341F2D4A1D9A378A00379D48 /* projectModuleMacros.h */, + 341F2D4B1D9A37A700379D48 /* projectModulePrefixHeader.h */, ); path = Other; sourceTree = ""; @@ -2029,40 +2362,15 @@ 3468FFEB1D90EF3800A69723 /* Resource */ = { isa = PBXGroup; children = ( + 341F2D4C1D9A37BD00379D48 /* projectImages.xcassets */, ); path = Resource; sourceTree = ""; }; - 3468FFF21D91561200A69723 /* YTKNetwork */ = { - isa = PBXGroup; - children = ( - 343EB3891D92178C00110CE5 /* YTKBaseRequest.h */, - 343EB38A1D92178C00110CE5 /* YTKBaseRequest.m */, - 343EB38B1D92178C00110CE5 /* YTKBatchRequest.h */, - 343EB38C1D92178C00110CE5 /* YTKBatchRequest.m */, - 343EB38D1D92178C00110CE5 /* YTKBatchRequestAgent.h */, - 343EB38E1D92178C00110CE5 /* YTKBatchRequestAgent.m */, - 343EB38F1D92178C00110CE5 /* YTKChainRequest.h */, - 343EB3901D92178C00110CE5 /* YTKChainRequest.m */, - 343EB3911D92178C00110CE5 /* YTKChainRequestAgent.h */, - 343EB3921D92178C00110CE5 /* YTKChainRequestAgent.m */, - 343EB3931D92178C00110CE5 /* YTKNetwork.h */, - 343EB3941D92178C00110CE5 /* YTKNetworkAgent.h */, - 343EB3951D92178C00110CE5 /* YTKNetworkAgent.m */, - 343EB3961D92178C00110CE5 /* YTKNetworkConfig.h */, - 343EB3971D92178C00110CE5 /* YTKNetworkConfig.m */, - 343EB3981D92178C00110CE5 /* YTKNetworkPrivate.h */, - 343EB3991D92178C00110CE5 /* YTKNetworkPrivate.m */, - 343EB39A1D92178C00110CE5 /* YTKRequest.h */, - 343EB39B1D92178C00110CE5 /* YTKRequest.m */, - ); - path = YTKNetwork; - sourceTree = ""; - }; 34732A5E1D93772C00EE0D14 /* CocoaLumberjack */ = { isa = PBXGroup; children = ( - 34732A831D93781500EE0D14 /* CLI */, + 3411DD3D1D93D3CB00077FAD /* CLI */, 34732A881D93781500EE0D14 /* DDAbstractDatabaseLogger.h */, 34732A891D93781500EE0D14 /* DDAbstractDatabaseLogger.m */, 34732A8A1D93781500EE0D14 /* DDASLLogCapture.h */, @@ -2084,15 +2392,6 @@ path = CocoaLumberjack; sourceTree = ""; }; - 34732A831D93781500EE0D14 /* CLI */ = { - isa = PBXGroup; - children = ( - 34732A841D93781500EE0D14 /* CLIColor.h */, - 34732A851D93781500EE0D14 /* CLIColor.m */, - ); - path = CLI; - sourceTree = ""; - }; 34732A981D93781500EE0D14 /* Extensions */ = { isa = PBXGroup; children = ( @@ -2118,6 +2417,273 @@ path = JiaLoggerHelper; sourceTree = ""; }; + 3479FC5B1D94D9A70084C9AB /* FLEX */ = { + isa = PBXGroup; + children = ( + 3479FC5C1D94D9D50084C9AB /* Editing */, + 3479FC841D94D9D60084C9AB /* ExplorerInterface */, + 3479FC891D94D9D60084C9AB /* FLEX.h */, + 3479FC8A1D94D9D60084C9AB /* FLEXManager.h */, + 3479FC8B1D94D9D60084C9AB /* GlobalStateExplorers */, + 3479FCBB1D94D9D60084C9AB /* Manager */, + 3479FCBE1D94D9D60084C9AB /* Network */, + 3479FCD11D94D9D60084C9AB /* ObjectExplorers */, + 3479FCEA1D94D9D60084C9AB /* Toolbar */, + 3479FCEF1D94D9D60084C9AB /* Utility */, + 3479FCFE1D94D9D60084C9AB /* ViewHierarchy */, + ); + path = FLEX; + sourceTree = ""; + }; + 3479FC5C1D94D9D50084C9AB /* Editing */ = { + isa = PBXGroup; + children = ( + 3479FC5D1D94D9D50084C9AB /* ArgumentInputViews */, + 3479FC781D94D9D60084C9AB /* FLEXDefaultEditorViewController.h */, + 3479FC791D94D9D60084C9AB /* FLEXDefaultEditorViewController.m */, + 3479FC7A1D94D9D60084C9AB /* FLEXFieldEditorView.h */, + 3479FC7B1D94D9D60084C9AB /* FLEXFieldEditorView.m */, + 3479FC7C1D94D9D60084C9AB /* FLEXFieldEditorViewController.h */, + 3479FC7D1D94D9D60084C9AB /* FLEXFieldEditorViewController.m */, + 3479FC7E1D94D9D60084C9AB /* FLEXIvarEditorViewController.h */, + 3479FC7F1D94D9D60084C9AB /* FLEXIvarEditorViewController.m */, + 3479FC801D94D9D60084C9AB /* FLEXMethodCallingViewController.h */, + 3479FC811D94D9D60084C9AB /* FLEXMethodCallingViewController.m */, + 3479FC821D94D9D60084C9AB /* FLEXPropertyEditorViewController.h */, + 3479FC831D94D9D60084C9AB /* FLEXPropertyEditorViewController.m */, + ); + path = Editing; + sourceTree = ""; + }; + 3479FC5D1D94D9D50084C9AB /* ArgumentInputViews */ = { + isa = PBXGroup; + children = ( + 3479FC5E1D94D9D50084C9AB /* FLEXArgumentInputColorView.h */, + 3479FC5F1D94D9D50084C9AB /* FLEXArgumentInputColorView.m */, + 3479FC601D94D9D50084C9AB /* FLEXArgumentInputDateView.h */, + 3479FC611D94D9D50084C9AB /* FLEXArgumentInputDateView.m */, + 3479FC621D94D9D50084C9AB /* FLEXArgumentInputFontsPickerView.h */, + 3479FC631D94D9D50084C9AB /* FLEXArgumentInputFontsPickerView.m */, + 3479FC641D94D9D50084C9AB /* FLEXArgumentInputFontView.h */, + 3479FC651D94D9D50084C9AB /* FLEXArgumentInputFontView.m */, + 3479FC661D94D9D50084C9AB /* FLEXArgumentInputJSONObjectView.h */, + 3479FC671D94D9D50084C9AB /* FLEXArgumentInputJSONObjectView.m */, + 3479FC681D94D9D50084C9AB /* FLEXArgumentInputNotSupportedView.h */, + 3479FC691D94D9D50084C9AB /* FLEXArgumentInputNotSupportedView.m */, + 3479FC6A1D94D9D50084C9AB /* FLEXArgumentInputNumberView.h */, + 3479FC6B1D94D9D60084C9AB /* FLEXArgumentInputNumberView.m */, + 3479FC6C1D94D9D60084C9AB /* FLEXArgumentInputStringView.h */, + 3479FC6D1D94D9D60084C9AB /* FLEXArgumentInputStringView.m */, + 3479FC6E1D94D9D60084C9AB /* FLEXArgumentInputStructView.h */, + 3479FC6F1D94D9D60084C9AB /* FLEXArgumentInputStructView.m */, + 3479FC701D94D9D60084C9AB /* FLEXArgumentInputSwitchView.h */, + 3479FC711D94D9D60084C9AB /* FLEXArgumentInputSwitchView.m */, + 3479FC721D94D9D60084C9AB /* FLEXArgumentInputTextView.h */, + 3479FC731D94D9D60084C9AB /* FLEXArgumentInputTextView.m */, + 3479FC741D94D9D60084C9AB /* FLEXArgumentInputView.h */, + 3479FC751D94D9D60084C9AB /* FLEXArgumentInputView.m */, + 3479FC761D94D9D60084C9AB /* FLEXArgumentInputViewFactory.h */, + 3479FC771D94D9D60084C9AB /* FLEXArgumentInputViewFactory.m */, + ); + path = ArgumentInputViews; + sourceTree = ""; + }; + 3479FC841D94D9D60084C9AB /* ExplorerInterface */ = { + isa = PBXGroup; + children = ( + 3479FC851D94D9D60084C9AB /* FLEXExplorerViewController.h */, + 3479FC861D94D9D60084C9AB /* FLEXExplorerViewController.m */, + 3479FC871D94D9D60084C9AB /* FLEXWindow.h */, + 3479FC881D94D9D60084C9AB /* FLEXWindow.m */, + ); + path = ExplorerInterface; + sourceTree = ""; + }; + 3479FC8B1D94D9D60084C9AB /* GlobalStateExplorers */ = { + isa = PBXGroup; + children = ( + 3479FC8C1D94D9D60084C9AB /* DatabaseBrowser */, + 3479FCA01D94D9D60084C9AB /* FLEXClassesTableViewController.h */, + 3479FCA11D94D9D60084C9AB /* FLEXClassesTableViewController.m */, + 3479FCA21D94D9D60084C9AB /* FLEXCookiesTableViewController.h */, + 3479FCA31D94D9D60084C9AB /* FLEXCookiesTableViewController.m */, + 3479FCA41D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.h */, + 3479FCA51D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.m */, + 3479FCA61D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.h */, + 3479FCA71D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.m */, + 3479FCA81D94D9D60084C9AB /* FLEXFileBrowserTableViewController.h */, + 3479FCA91D94D9D60084C9AB /* FLEXFileBrowserTableViewController.m */, + 3479FCAA1D94D9D60084C9AB /* FLEXGlobalsTableViewController.h */, + 3479FCAB1D94D9D60084C9AB /* FLEXGlobalsTableViewController.m */, + 3479FCAC1D94D9D60084C9AB /* FLEXInstancesTableViewController.h */, + 3479FCAD1D94D9D60084C9AB /* FLEXInstancesTableViewController.m */, + 3479FCAE1D94D9D60084C9AB /* FLEXLibrariesTableViewController.h */, + 3479FCAF1D94D9D60084C9AB /* FLEXLibrariesTableViewController.m */, + 3479FCB01D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.h */, + 3479FCB11D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.m */, + 3479FCB21D94D9D60084C9AB /* FLEXWebViewController.h */, + 3479FCB31D94D9D60084C9AB /* FLEXWebViewController.m */, + 3479FCB41D94D9D60084C9AB /* SystemLog */, + ); + path = GlobalStateExplorers; + sourceTree = ""; + }; + 3479FC8C1D94D9D60084C9AB /* DatabaseBrowser */ = { + isa = PBXGroup; + children = ( + 3479FC8D1D94D9D60084C9AB /* FLEXDatabaseManager.h */, + 3479FC8E1D94D9D60084C9AB /* FLEXMultiColumnTableView.h */, + 3479FC8F1D94D9D60084C9AB /* FLEXMultiColumnTableView.m */, + 3479FC901D94D9D60084C9AB /* FLEXRealmDatabaseManager.h */, + 3479FC911D94D9D60084C9AB /* FLEXRealmDatabaseManager.m */, + 3479FC921D94D9D60084C9AB /* FLEXRealmDefines.h */, + 3479FC931D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.h */, + 3479FC941D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.m */, + 3479FC951D94D9D60084C9AB /* FLEXTableColumnHeader.h */, + 3479FC961D94D9D60084C9AB /* FLEXTableColumnHeader.m */, + 3479FC971D94D9D60084C9AB /* FLEXTableContentCell.h */, + 3479FC981D94D9D60084C9AB /* FLEXTableContentCell.m */, + 3479FC991D94D9D60084C9AB /* FLEXTableContentViewController.h */, + 3479FC9A1D94D9D60084C9AB /* FLEXTableContentViewController.m */, + 3479FC9B1D94D9D60084C9AB /* FLEXTableLeftCell.h */, + 3479FC9C1D94D9D60084C9AB /* FLEXTableLeftCell.m */, + 3479FC9D1D94D9D60084C9AB /* FLEXTableListViewController.h */, + 3479FC9E1D94D9D60084C9AB /* FLEXTableListViewController.m */, + 3479FC9F1D94D9D60084C9AB /* LICENSE */, + ); + path = DatabaseBrowser; + sourceTree = ""; + }; + 3479FCB41D94D9D60084C9AB /* SystemLog */ = { + isa = PBXGroup; + children = ( + 3479FCB51D94D9D60084C9AB /* FLEXSystemLogMessage.h */, + 3479FCB61D94D9D60084C9AB /* FLEXSystemLogMessage.m */, + 3479FCB71D94D9D60084C9AB /* FLEXSystemLogTableViewCell.h */, + 3479FCB81D94D9D60084C9AB /* FLEXSystemLogTableViewCell.m */, + 3479FCB91D94D9D60084C9AB /* FLEXSystemLogTableViewController.h */, + 3479FCBA1D94D9D60084C9AB /* FLEXSystemLogTableViewController.m */, + ); + path = SystemLog; + sourceTree = ""; + }; + 3479FCBB1D94D9D60084C9AB /* Manager */ = { + isa = PBXGroup; + children = ( + 3479FCBC1D94D9D60084C9AB /* FLEXManager+Private.h */, + 3479FCBD1D94D9D60084C9AB /* FLEXManager.m */, + ); + path = Manager; + sourceTree = ""; + }; + 3479FCBE1D94D9D60084C9AB /* Network */ = { + isa = PBXGroup; + children = ( + 3479FCBF1D94D9D60084C9AB /* FLEXNetworkCurlLogger.h */, + 3479FCC01D94D9D60084C9AB /* FLEXNetworkCurlLogger.m */, + 3479FCC11D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.h */, + 3479FCC21D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.m */, + 3479FCC31D94D9D60084C9AB /* FLEXNetworkRecorder.h */, + 3479FCC41D94D9D60084C9AB /* FLEXNetworkRecorder.m */, + 3479FCC51D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.h */, + 3479FCC61D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.m */, + 3479FCC71D94D9D60084C9AB /* FLEXNetworkTransaction.h */, + 3479FCC81D94D9D60084C9AB /* FLEXNetworkTransaction.m */, + 3479FCC91D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.h */, + 3479FCCA1D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.m */, + 3479FCCB1D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.h */, + 3479FCCC1D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.m */, + 3479FCCD1D94D9D60084C9AB /* PonyDebugger */, + ); + path = Network; + sourceTree = ""; + }; + 3479FCCD1D94D9D60084C9AB /* PonyDebugger */ = { + isa = PBXGroup; + children = ( + 3479FCCE1D94D9D60084C9AB /* FLEXNetworkObserver.h */, + 3479FCCF1D94D9D60084C9AB /* FLEXNetworkObserver.m */, + 3479FCD01D94D9D60084C9AB /* LICENSE */, + ); + path = PonyDebugger; + sourceTree = ""; + }; + 3479FCD11D94D9D60084C9AB /* ObjectExplorers */ = { + isa = PBXGroup; + children = ( + 3479FCD21D94D9D60084C9AB /* FLEXArrayExplorerViewController.h */, + 3479FCD31D94D9D60084C9AB /* FLEXArrayExplorerViewController.m */, + 3479FCD41D94D9D60084C9AB /* FLEXClassExplorerViewController.h */, + 3479FCD51D94D9D60084C9AB /* FLEXClassExplorerViewController.m */, + 3479FCD61D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.h */, + 3479FCD71D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.m */, + 3479FCD81D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.h */, + 3479FCD91D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.m */, + 3479FCDA1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.h */, + 3479FCDB1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.m */, + 3479FCDC1D94D9D60084C9AB /* FLEXImageExplorerViewController.h */, + 3479FCDD1D94D9D60084C9AB /* FLEXImageExplorerViewController.m */, + 3479FCDE1D94D9D60084C9AB /* FLEXLayerExplorerViewController.h */, + 3479FCDF1D94D9D60084C9AB /* FLEXLayerExplorerViewController.m */, + 3479FCE01D94D9D60084C9AB /* FLEXObjectExplorerFactory.h */, + 3479FCE11D94D9D60084C9AB /* FLEXObjectExplorerFactory.m */, + 3479FCE21D94D9D60084C9AB /* FLEXObjectExplorerViewController.h */, + 3479FCE31D94D9D60084C9AB /* FLEXObjectExplorerViewController.m */, + 3479FCE41D94D9D60084C9AB /* FLEXSetExplorerViewController.h */, + 3479FCE51D94D9D60084C9AB /* FLEXSetExplorerViewController.m */, + 3479FCE61D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.h */, + 3479FCE71D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.m */, + 3479FCE81D94D9D60084C9AB /* FLEXViewExplorerViewController.h */, + 3479FCE91D94D9D60084C9AB /* FLEXViewExplorerViewController.m */, + ); + path = ObjectExplorers; + sourceTree = ""; + }; + 3479FCEA1D94D9D60084C9AB /* Toolbar */ = { + isa = PBXGroup; + children = ( + 3479FCEB1D94D9D60084C9AB /* FLEXExplorerToolbar.h */, + 3479FCEC1D94D9D60084C9AB /* FLEXExplorerToolbar.m */, + 3479FCED1D94D9D60084C9AB /* FLEXToolbarItem.h */, + 3479FCEE1D94D9D60084C9AB /* FLEXToolbarItem.m */, + ); + path = Toolbar; + sourceTree = ""; + }; + 3479FCEF1D94D9D60084C9AB /* Utility */ = { + isa = PBXGroup; + children = ( + 3479FCF01D94D9D60084C9AB /* FLEXHeapEnumerator.h */, + 3479FCF11D94D9D60084C9AB /* FLEXHeapEnumerator.m */, + 3479FCF21D94D9D60084C9AB /* FLEXKeyboardHelpViewController.h */, + 3479FCF31D94D9D60084C9AB /* FLEXKeyboardHelpViewController.m */, + 3479FCF41D94D9D60084C9AB /* FLEXKeyboardShortcutManager.h */, + 3479FCF51D94D9D60084C9AB /* FLEXKeyboardShortcutManager.m */, + 3479FCF61D94D9D60084C9AB /* FLEXMultilineTableViewCell.h */, + 3479FCF71D94D9D60084C9AB /* FLEXMultilineTableViewCell.m */, + 3479FCF81D94D9D60084C9AB /* FLEXResources.h */, + 3479FCF91D94D9D60084C9AB /* FLEXResources.m */, + 3479FCFA1D94D9D60084C9AB /* FLEXRuntimeUtility.h */, + 3479FCFB1D94D9D60084C9AB /* FLEXRuntimeUtility.m */, + 3479FCFC1D94D9D60084C9AB /* FLEXUtility.h */, + 3479FCFD1D94D9D60084C9AB /* FLEXUtility.m */, + ); + path = Utility; + sourceTree = ""; + }; + 3479FCFE1D94D9D60084C9AB /* ViewHierarchy */ = { + isa = PBXGroup; + children = ( + 3479FCFF1D94D9D60084C9AB /* FLEXHierarchyTableViewCell.h */, + 3479FD001D94D9D60084C9AB /* FLEXHierarchyTableViewCell.m */, + 3479FD011D94D9D60084C9AB /* FLEXHierarchyTableViewController.h */, + 3479FD021D94D9D60084C9AB /* FLEXHierarchyTableViewController.m */, + 3479FD031D94D9D60084C9AB /* FLEXImagePreviewViewController.h */, + 3479FD041D94D9D60084C9AB /* FLEXImagePreviewViewController.m */, + ); + path = ViewHierarchy; + sourceTree = ""; + }; 347BAF941D87E30200D12F0B = { isa = PBXGroup; children = ( @@ -2185,27 +2751,16 @@ 347BAFD31D87E55E00D12F0B /* BaseModule */ = { isa = PBXGroup; children = ( + 3411DD3C1D93D2DC00077FAD /* JiaAnalytics */, 340C3D791D8FE48700E3BACD /* JiaGT */, 347BAFDA1D87E6DB00D12F0B /* JiaCore */, 347BAFD91D87E6BC00D12F0B /* JiaTool */, 347BAFD81D87E65A00D12F0B /* JiaConst */, - 347BAFD71D87E61200D12F0B /* JiaMacros */, 347BAFD61D87E5F700D12F0B /* JiaCategory */, - 347BAFD51D87E5D100D12F0B /* JiaNetWork */, ); path = BaseModule; sourceTree = ""; }; - 347BAFD51D87E5D100D12F0B /* JiaNetWork */ = { - isa = PBXGroup; - children = ( - 343EB3A51D9217DE00110CE5 /* AFDownloadRequestOperation */, - 3468FFF21D91561200A69723 /* YTKNetwork */, - ); - name = JiaNetWork; - path = JiaNewWork; - sourceTree = ""; - }; 347BAFD61D87E5F700D12F0B /* JiaCategory */ = { isa = PBXGroup; children = ( @@ -2218,14 +2773,6 @@ path = JiaCategory; sourceTree = ""; }; - 347BAFD71D87E61200D12F0B /* JiaMacros */ = { - isa = PBXGroup; - children = ( - 346800121D915C4D00A69723 /* JiaMacros.h */, - ); - path = JiaMacros; - sourceTree = ""; - }; 347BAFD81D87E65A00D12F0B /* JiaConst */ = { isa = PBXGroup; children = ( @@ -2243,6 +2790,7 @@ 347BAFDA1D87E6DB00D12F0B /* JiaCore */ = { isa = PBXGroup; children = ( + 3411DD3A1D93AE8D00077FAD /* JiaMacros */, 3468FFE31D90D2D900A69723 /* JiaMediator */, 3468FFB01D90C9DE00A69723 /* JiaCoreTool */, 3468FFAF1D90C5D700A69723 /* JiaCoreHelper */, @@ -2250,6 +2798,7 @@ 34F1A3831D88E9C400931645 /* JiaBaseViewController.m */, 340C3D761D8FDD8D00E3BACD /* JiaAppDelegate.h */, 340C3D771D8FDD8D00E3BACD /* JiaAppDelegate.m */, + 34F83CBE1D9B9F080085A540 /* JiaCore.h */, ); path = JiaCore; sourceTree = ""; @@ -2311,6 +2860,8 @@ 347BAFDF1D87E84F00D12F0B /* View */ = { isa = PBXGroup; children = ( + 341F2D511D9A42B400379D48 /* DesignerHeaderView.h */, + 341F2D521D9A42B400379D48 /* DesignerHeaderView.m */, ); path = View; sourceTree = ""; @@ -2318,6 +2869,8 @@ 347BAFE01D87E85800D12F0B /* Model */ = { isa = PBXGroup; children = ( + 341F2D4E1D9A429C00379D48 /* DesignerDetailModel.h */, + 341F2D4F1D9A429C00379D48 /* DesignerDetailModel.m */, ); path = Model; sourceTree = ""; @@ -2445,6 +2998,36 @@ path = View; sourceTree = ""; }; + 34919F711D98E7AB004B7307 /* GVUserDefaults */ = { + isa = PBXGroup; + children = ( + 34919F721D98E7AB004B7307 /* GVUserDefaults.h */, + 34919F731D98E7AB004B7307 /* GVUserDefaults.m */, + ); + path = GVUserDefaults; + sourceTree = ""; + }; + 34919F751D98EA6E004B7307 /* JSPatch */ = { + isa = PBXGroup; + children = ( + 34919F761D98EA6E004B7307 /* JPEngine.h */, + 34919F771D98EA6E004B7307 /* JPEngine.m */, + 34919F781D98EA6E004B7307 /* JSPatch.js */, + ); + path = JSPatch; + sourceTree = ""; + }; + 34919F801D990134004B7307 /* JiaPathchHelper */ = { + isa = PBXGroup; + children = ( + 34919F8E1D990F1E004B7307 /* JiaPathchHelper.h */, + 34919F8F1D990F1E004B7307 /* JiaPathchHelper.m */, + 34919F911D990FFE004B7307 /* JiaPathchModel.h */, + 34919F921D990FFE004B7307 /* JiaPathchModel.m */, + ); + path = JiaPathchHelper; + sourceTree = ""; + }; 34F1A37F1D88DE9A00931645 /* Other */ = { isa = PBXGroup; children = ( @@ -2457,6 +3040,67 @@ path = Other; sourceTree = ""; }; + 34F83C8C1D9B58030085A540 /* YYCache */ = { + isa = PBXGroup; + children = ( + 34F83C8D1D9B58030085A540 /* YYCache.h */, + 34F83C8E1D9B58030085A540 /* YYCache.m */, + 34F83C8F1D9B58030085A540 /* YYDiskCache.h */, + 34F83C901D9B58030085A540 /* YYDiskCache.m */, + 34F83C911D9B58030085A540 /* YYKVStorage.h */, + 34F83C921D9B58030085A540 /* YYKVStorage.m */, + 34F83C931D9B58030085A540 /* YYMemoryCache.h */, + 34F83C941D9B58030085A540 /* YYMemoryCache.m */, + ); + path = YYCache; + sourceTree = ""; + }; + 34F83C991D9B9EB60085A540 /* JiaNewWork */ = { + isa = PBXGroup; + children = ( + 34F83C9A1D9B9EB60085A540 /* AFDownloadRequestOperation */, + 34F83C9D1D9B9EB60085A540 /* JiaBaseRequest.h */, + 34F83C9E1D9B9EB60085A540 /* JiaBaseRequest.m */, + 34F83C9F1D9B9EB60085A540 /* YTKNetwork */, + ); + path = JiaNewWork; + sourceTree = ""; + }; + 34F83C9A1D9B9EB60085A540 /* AFDownloadRequestOperation */ = { + isa = PBXGroup; + children = ( + 34F83C9B1D9B9EB60085A540 /* AFDownloadRequestOperation.h */, + 34F83C9C1D9B9EB60085A540 /* AFDownloadRequestOperation.m */, + ); + path = AFDownloadRequestOperation; + sourceTree = ""; + }; + 34F83C9F1D9B9EB60085A540 /* YTKNetwork */ = { + isa = PBXGroup; + children = ( + 34F83CA01D9B9EB60085A540 /* YTKBaseRequest.h */, + 34F83CA11D9B9EB60085A540 /* YTKBaseRequest.m */, + 34F83CA21D9B9EB60085A540 /* YTKBatchRequest.h */, + 34F83CA31D9B9EB60085A540 /* YTKBatchRequest.m */, + 34F83CA41D9B9EB60085A540 /* YTKBatchRequestAgent.h */, + 34F83CA51D9B9EB60085A540 /* YTKBatchRequestAgent.m */, + 34F83CA61D9B9EB60085A540 /* YTKChainRequest.h */, + 34F83CA71D9B9EB60085A540 /* YTKChainRequest.m */, + 34F83CA81D9B9EB60085A540 /* YTKChainRequestAgent.h */, + 34F83CA91D9B9EB60085A540 /* YTKChainRequestAgent.m */, + 34F83CAA1D9B9EB60085A540 /* YTKNetwork.h */, + 34F83CAB1D9B9EB60085A540 /* YTKNetworkAgent.h */, + 34F83CAC1D9B9EB60085A540 /* YTKNetworkAgent.m */, + 34F83CAD1D9B9EB60085A540 /* YTKNetworkConfig.h */, + 34F83CAE1D9B9EB60085A540 /* YTKNetworkConfig.m */, + 34F83CAF1D9B9EB60085A540 /* YTKNetworkPrivate.h */, + 34F83CB01D9B9EB60085A540 /* YTKNetworkPrivate.m */, + 34F83CB11D9B9EB60085A540 /* YTKRequest.h */, + 34F83CB21D9B9EB60085A540 /* YTKRequest.m */, + ); + path = YTKNetwork; + sourceTree = ""; + }; 60F98656C79E768F08EEFB6D /* Pods */ = { isa = PBXGroup; children = ( @@ -2469,6 +3113,7 @@ B7203E403AEBDA14A5F197ED /* Frameworks */ = { isa = PBXGroup; children = ( + 34919F7B1D98EAB0004B7307 /* JavaScriptCore.framework */, 3471536C1D8F9E4700BDB632 /* CoreGraphics.framework */, 6109480D64D9F6F4E2BC07CB /* libPods.a */, ); @@ -2586,9 +3231,16 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 341F2D3D1D9A35E800379D48 /* JiaApp.xcassets in Resources */, + 34919F7A1D98EA6E004B7307 /* JSPatch.js in Resources */, + 341F2D441D9A373B00379D48 /* designerImages.xcassets in Resources */, 343EB5DE1D922C2B00110CE5 /* NSDateTimeAgo.bundle in Resources */, + 341F2D461D9A374C00379D48 /* userImages.xcassets in Resources */, 347BAFB01D87E30200D12F0B /* LaunchScreen.storyboard in Resources */, + 3479FD221D94D9D60084C9AB /* LICENSE in Resources */, + 341F2D4D1D9A37BD00379D48 /* projectImages.xcassets in Resources */, 347BAFAD1D87E30200D12F0B /* Assets.xcassets in Resources */, + 3479FD391D94D9D60084C9AB /* LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2661,18 +3313,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 343EB3A41D92178C00110CE5 /* YTKRequest.m in Sources */, 343EB66C1D922C2C00110CE5 /* UIScrollView+APParallaxHeader.m in Sources */, + 3479FD201D94D9D60084C9AB /* FLEXTableLeftCell.m in Sources */, + 3479FD4E1D94D9D60084C9AB /* FLEXUtility.m in Sources */, 343EB68E1D922C2C00110CE5 /* UIView+ViewController.m in Sources */, + 34919F741D98E7AB004B7307 /* GVUserDefaults.m in Sources */, + 3479FD1E1D94D9D60084C9AB /* FLEXTableContentCell.m in Sources */, 343EB6271D922C2C00110CE5 /* UIApplication+KeyboardFrame.m in Sources */, 343EB6B21D92550300110CE5 /* NSData+APNSToken.m in Sources */, 3468FFD91D90CA1A00A69723 /* ReachState.m in Sources */, + 3479FD2A1D94D9D60084C9AB /* FLEXLibrariesTableViewController.m in Sources */, + 34919F791D98EA6E004B7307 /* JPEngine.m in Sources */, + 3479FD081D94D9D60084C9AB /* FLEXArgumentInputFontView.m in Sources */, 343EB6921D922C2C00110CE5 /* UIViewController+BackButtonTouched.m in Sources */, + 3479FD361D94D9D60084C9AB /* FLEXNetworkTransactionDetailTableViewController.m in Sources */, 343EB6851D922C2C00110CE5 /* UIView+FDCollapsibleConstraints.m in Sources */, 343EB6371D922C2C00110CE5 /* UIColor+Gradient.m in Sources */, + 3479FD481D94D9D60084C9AB /* FLEXHeapEnumerator.m in Sources */, 343EB5D81D922C2B00110CE5 /* NSDate+Extension.m in Sources */, 343EB6B41D92550300110CE5 /* NSData+Encrypt.m in Sources */, 343EB6551D922C2C00110CE5 /* UIImageView+FaceAwareFill.m in Sources */, + 3479FD411D94D9D60084C9AB /* FLEXObjectExplorerFactory.m in Sources */, 343EB6051D922C2B00110CE5 /* NSString+Encrypt.m in Sources */, 343EB6071D922C2B00110CE5 /* NSString+Matcher.m in Sources */, 347BB0041D87EB7700D12F0B /* Target_Project.m in Sources */, @@ -2683,37 +3344,47 @@ 343EB6641D922C2C00110CE5 /* UINavigationItem+Lock.m in Sources */, 343EB65E1D922C2C00110CE5 /* UINavigationController+BATransitions.m in Sources */, 343EB5FB1D922C2B00110CE5 /* NSObject+MKBlockTimer.m in Sources */, + 3479FD4B1D94D9D60084C9AB /* FLEXMultilineTableViewCell.m in Sources */, + 3479FD271D94D9D60084C9AB /* FLEXFileBrowserTableViewController.m in Sources */, 343EB6621D922C2C00110CE5 /* UINavigationController+StackManager.m in Sources */, 343EB66E1D922C2C00110CE5 /* UIScrollView+Pages.m in Sources */, 343EB6991D922C2C00110CE5 /* UIWebView+Alert.m in Sources */, 343EB5CD1D922C2B00110CE5 /* NSArray+Block.m in Sources */, + 3479FD461D94D9D60084C9AB /* FLEXExplorerToolbar.m in Sources */, 343EB62B1D922C2C00110CE5 /* UIBezierPath+BasicShapes.m in Sources */, + 341F2D491D9A377200379D48 /* JiaProjectConfigManager.m in Sources */, 343EB5E81D922C2B00110CE5 /* NSFileManager+Paths.m in Sources */, + 3479FD4A1D94D9D60084C9AB /* FLEXKeyboardShortcutManager.m in Sources */, 343EB5DF1D922C2B00110CE5 /* NSDateFormatter+Make.m in Sources */, 343EB6041D922C2B00110CE5 /* NSString+Emoji.m in Sources */, 343EB6731D922C2C00110CE5 /* UITableView+FDKeyedHeightCache.m in Sources */, 347BB00D1D87EBEF00D12F0B /* DesignerViewController.m in Sources */, 347BAFF51D87EAE100D12F0B /* JiaMediator+DesignerModuleActions.m in Sources */, 343EB64B1D922C2C00110CE5 /* UIImage+GIF.m in Sources */, + 3479FD1F1D94D9D60084C9AB /* FLEXTableContentViewController.m in Sources */, + 3479FD291D94D9D60084C9AB /* FLEXInstancesTableViewController.m in Sources */, 34732AA11D93781500EE0D14 /* DDAbstractDatabaseLogger.m in Sources */, + 3479FD1D1D94D9D60084C9AB /* FLEXTableColumnHeader.m in Sources */, 343EB6B71D92550300110CE5 /* NSData+SDDataCache.m in Sources */, + 3479FD1C1D94D9D60084C9AB /* FLEXSQLiteDatabaseManager.m in Sources */, 343EB6B61D92550300110CE5 /* NSData+Hash.m in Sources */, 343EB5EA1D922C2B00110CE5 /* NSIndexPath+Offset.m in Sources */, 347BAFFE1D87EB4900D12F0B /* Target_Designer.m in Sources */, 347BAFFB1D87EB1C00D12F0B /* JiaMediator+ProjectModuleActions.m in Sources */, - 343EB39D1D92178C00110CE5 /* YTKBatchRequest.m in Sources */, + 34F83C971D9B58030085A540 /* YYKVStorage.m in Sources */, 343EB6601D922C2C00110CE5 /* UINavigationController+JZExtension.m in Sources */, 343EB6451D922C2C00110CE5 /* UIImage+BetterFace.m in Sources */, 343EB5ED1D922C2B00110CE5 /* NSNotificationCenter+MainThread.m in Sources */, 343EB69F1D922C2C00110CE5 /* UIWebView+Style.m in Sources */, - 343EB39C1D92178C00110CE5 /* YTKBaseRequest.m in Sources */, 343EB6081D922C2B00110CE5 /* NSString+MIME.m in Sources */, 343EB6511D922C2C00110CE5 /* UIImage+RoundedCorner.m in Sources */, 343EB6BF1D92568700110CE5 /* JiaGTConfigManager.m in Sources */, - 343EB39E1D92178C00110CE5 /* YTKBatchRequestAgent.m in Sources */, + 34F83C951D9B58030085A540 /* YYCache.m in Sources */, + 3479FD061D94D9D60084C9AB /* FLEXArgumentInputDateView.m in Sources */, 343EB6471D922C2C00110CE5 /* UIImage+Capture.m in Sources */, 343EB5E71D922C2B00110CE5 /* NSFileHandle+readLine.m in Sources */, 343EB6981D922C2C00110CE5 /* UIViewController+Visible.m in Sources */, + 3479FD4F1D94D9D60084C9AB /* FLEXHierarchyTableViewCell.m in Sources */, 343EB65B1D922C2C00110CE5 /* UILabel+ESAdjustableLabel.m in Sources */, 343EB63F1D922C2C00110CE5 /* UIDevice+PasscodeStatus.m in Sources */, 34732AAD1D93795700EE0D14 /* JiaFileLogger.m in Sources */, @@ -2722,31 +3393,43 @@ 343EB6771D922C2C00110CE5 /* UITableViewCell+TS_delaysContentTouches.m in Sources */, 343EB6421D922C2C00110CE5 /* UIFont-TTF.m in Sources */, 3468FFE21D90CA1A00A69723 /* RealReachability.m in Sources */, + 34F83CB91D9B9EB60085A540 /* YTKChainRequestAgent.m in Sources */, 343EB60D1D922C2B00110CE5 /* NSString+Score.m in Sources */, 343EB63C1D922C2C00110CE5 /* UIControl+ActionBlocks.m in Sources */, 343EB62E1D922C2C00110CE5 /* UIBezierPath+SVG.m in Sources */, 343EB5E31D922C2B00110CE5 /* NSDictionary+SafeAccess.m in Sources */, 343EB6631D922C2C00110CE5 /* UINavigationItem+Loading.m in Sources */, 343EB69C1D922C2C00110CE5 /* UIWebView+JS.m in Sources */, - 343EB3A21D92178C00110CE5 /* YTKNetworkConfig.m in Sources */, + 3479FD341D94D9D60084C9AB /* FLEXNetworkSettingsTableViewController.m in Sources */, + 3479FD0A1D94D9D60084C9AB /* FLEXArgumentInputNotSupportedView.m in Sources */, 343EB6591D922C2C00110CE5 /* UILabel+AutomaticWriting.m in Sources */, 343EB6891D922C2C00110CE5 /* UIView+Nib.m in Sources */, + 3479FD501D94D9D60084C9AB /* FLEXHierarchyTableViewController.m in Sources */, 343EB6131D922C2B00110CE5 /* NSTimer+Addition.m in Sources */, 343EB68B1D922C2C00110CE5 /* UIView+Screenshot.m in Sources */, + 3479FD351D94D9D60084C9AB /* FLEXNetworkTransaction.m in Sources */, 343EB5E11D922C2B00110CE5 /* NSDictionary+JSONString.m in Sources */, 343EB6281D922C2C00110CE5 /* UIApplication+NetworkActivityIndicator.m in Sources */, + 3479FD231D94D9D60084C9AB /* FLEXClassesTableViewController.m in Sources */, 343EB64E1D922C2C00110CE5 /* UIImage+PDF.m in Sources */, 343EB5F11D922C2B00110CE5 /* NSNumber+RomanNumerals.m in Sources */, 343EB5EE1D922C2B00110CE5 /* NSDecimalNumber+CalculatingByString.m in Sources */, 3468FFD51D90CA1A00A69723 /* MBProgressHUD.m in Sources */, 343EB63E1D922C2C00110CE5 /* UIDevice+Hardware.m in Sources */, + 34F83CBA1D9B9EB60085A540 /* YTKNetworkAgent.m in Sources */, 343EB6A11D922C2C00110CE5 /* WebView+Debug.m in Sources */, + 3479FD251D94D9D60084C9AB /* FLEXFileBrowserFileOperationController.m in Sources */, 343EB5EF1D922C2B00110CE5 /* NSDecimalNumber+Extensions.m in Sources */, - 343EB39F1D92178C00110CE5 /* YTKChainRequest.m in Sources */, 343EB64D1D922C2C00110CE5 /* UIImage+Orientation.m in Sources */, 343EB6B31D92550300110CE5 /* NSData+Base64.m in Sources */, + 3479FD161D94D9D60084C9AB /* FLEXMethodCallingViewController.m in Sources */, + 3479FD381D94D9D60084C9AB /* FLEXNetworkObserver.m in Sources */, + 34F83C981D9B58030085A540 /* YYMemoryCache.m in Sources */, + 3479FD241D94D9D60084C9AB /* FLEXCookiesTableViewController.m in Sources */, + 3479FD431D94D9D60084C9AB /* FLEXSetExplorerViewController.m in Sources */, 343EB6681D922C2C00110CE5 /* UIResponder+FirstResponder.m in Sources */, 343EB5E91D922C2B00110CE5 /* NSHTTPCookieStorage+FreezeDry.m in Sources */, + 3479FD101D94D9D60084C9AB /* FLEXArgumentInputView.m in Sources */, 340C3D781D8FDD8D00E3BACD /* JiaAppDelegate.m in Sources */, 343EB6751D922C2C00110CE5 /* UITableView+FDTemplateLayoutCellDebug.m in Sources */, 343EB5DA1D922C2B00110CE5 /* NSDate+InternetDateTime.m in Sources */, @@ -2755,15 +3438,23 @@ 343EB6701D922C2C00110CE5 /* UISplitViewController+QuickAccess.m in Sources */, 3468FFDD1D90CA1A00A69723 /* ReachStateWIFI.m in Sources */, 343EB6091D922C2B00110CE5 /* NSString+Pinyin.m in Sources */, + 3479FD3C1D94D9D60084C9AB /* FLEXDefaultsExplorerViewController.m in Sources */, 343EB6711D922C2C00110CE5 /* UITableView+iOS7Style.m in Sources */, 343EB6461D922C2C00110CE5 /* UIImage+Blur.m in Sources */, 343EB6361D922C2C00110CE5 /* UIButton+TouchAreaInsets.m in Sources */, + 3479FD321D94D9D60084C9AB /* FLEXNetworkHistoryTableViewController.m in Sources */, + 3479FD491D94D9D60084C9AB /* FLEXKeyboardHelpViewController.m in Sources */, 343EB6301D922C2C00110CE5 /* UIButton+BackgroundColor.m in Sources */, + 3479FD3B1D94D9D60084C9AB /* FLEXClassExplorerViewController.m in Sources */, 343EB6201D922C2C00110CE5 /* CAAnimation+EasingEquations.m in Sources */, + 3479FD141D94D9D60084C9AB /* FLEXFieldEditorViewController.m in Sources */, 343EB69A1D922C2C00110CE5 /* UIWebView+Blocks.m in Sources */, - 343EB3A81D92180500110CE5 /* AFDownloadRequestOperation.m in Sources */, 343EB5D71D922C2B00110CE5 /* NSDate+CupertinoYankee.m in Sources */, + 3479FD3E1D94D9D60084C9AB /* FLEXGlobalsTableViewControllerEntry.m in Sources */, 343EB6721D922C2C00110CE5 /* UITableView+FDIndexPathHeightCache.m in Sources */, + 3479FD211D94D9D60084C9AB /* FLEXTableListViewController.m in Sources */, + 3479FD451D94D9D60084C9AB /* FLEXViewExplorerViewController.m in Sources */, + 34F83CB81D9B9EB60085A540 /* YTKChainRequest.m in Sources */, 343EB6331D922C2C00110CE5 /* UIButton+Indicator.m in Sources */, 343EB66B1D922C2C00110CE5 /* UIScrollView+Addition.m in Sources */, 34732A5D1D9368FB00EE0D14 /* JiaCoreConfigManager.m in Sources */, @@ -2772,40 +3463,55 @@ 343EB5F31D922C2B00110CE5 /* NSObject+AddProperty.m in Sources */, 343EB6931D922C2C00110CE5 /* UIViewController+BlockSegue.m in Sources */, 343EB62F1D922C2C00110CE5 /* UIBezierPath+Symbol.m in Sources */, + 3479FD0F1D94D9D60084C9AB /* FLEXArgumentInputTextView.m in Sources */, 343EB6831D922C2C00110CE5 /* UIView+Debug.m in Sources */, 343EB6861D922C2C00110CE5 /* UIView+Find.m in Sources */, 343EB5F01D922C2B00110CE5 /* NSNumber+CGFloat.m in Sources */, 343EB6A21D922C2C00110CE5 /* UIWindow+Hierarchy.m in Sources */, + 3479FD181D94D9D60084C9AB /* FLEXExplorerViewController.m in Sources */, + 3479FD471D94D9D60084C9AB /* FLEXToolbarItem.m in Sources */, + 3479FD0B1D94D9D60084C9AB /* FLEXArgumentInputNumberView.m in Sources */, + 3479FD2E1D94D9D60084C9AB /* FLEXSystemLogTableViewCell.m in Sources */, 34732AA21D93781500EE0D14 /* DDASLLogCapture.m in Sources */, 343EB6391D922C2C00110CE5 /* UIColor+Modify.m in Sources */, 343EB6561D922C2C00110CE5 /* UIImageView+GeometryConversion.m in Sources */, 343EB5EC1D922C2B00110CE5 /* NSInvocation+Block.m in Sources */, + 3479FD3F1D94D9D60084C9AB /* FLEXImageExplorerViewController.m in Sources */, 34732AB01D93796F00EE0D14 /* JiaLoggerFormatter.m in Sources */, + 34919F931D990FFE004B7307 /* JiaPathchModel.m in Sources */, 343EB6241D922C2C00110CE5 /* CATransaction+AnimateWithDuration.m in Sources */, 343EB6541D922C2C00110CE5 /* UIImageView+BetterFace.m in Sources */, + 3479FD441D94D9D60084C9AB /* FLEXViewControllerExplorerViewController.m in Sources */, 343EB6691D922C2C00110CE5 /* UIResponder+UIAdapt.m in Sources */, 343EB61A1D922C2B00110CE5 /* NSUserDefaults+iCloudSync.m in Sources */, 343EB66D1D922C2C00110CE5 /* UIScrollView+EmptyDataSet.m in Sources */, - 343EB3A31D92178C00110CE5 /* YTKNetworkPrivate.m in Sources */, + 3479FD091D94D9D60084C9AB /* FLEXArgumentInputJSONObjectView.m in Sources */, 343EB6901D922C2C00110CE5 /* UIViewController+BackButtonHandler.m in Sources */, 343EB5DD1D922C2B00110CE5 /* NSDate+Utilities.m in Sources */, + 341F2D531D9A42B400379D48 /* DesignerHeaderView.m in Sources */, 343EB68F1D922C2C00110CE5 /* UIView+Visuals.m in Sources */, + 3479FD171D94D9D60084C9AB /* FLEXPropertyEditorViewController.m in Sources */, 343EB65D1D922C2C00110CE5 /* UINavigationBar+Awesome.m in Sources */, 34732AA31D93781500EE0D14 /* DDASLLogger.m in Sources */, 3468FFE61D90D2D900A69723 /* JiaMediator.m in Sources */, 343EB6381D922C2C00110CE5 /* UIColor+HEX.m in Sources */, + 34F83CB71D9B9EB60085A540 /* YTKBatchRequestAgent.m in Sources */, + 3479FD1A1D94D9D60084C9AB /* FLEXMultiColumnTableView.m in Sources */, 343EB60F1D922C2B00110CE5 /* NSString+Trims.m in Sources */, 343EB68C1D922C2C00110CE5 /* UIView+Shake.m in Sources */, 343EB5F71D922C2B00110CE5 /* NSObject+Blocks.m in Sources */, 343EB6961D922C2C00110CE5 /* UIViewController+StoreKit.m in Sources */, + 3479FD2F1D94D9D60084C9AB /* FLEXSystemLogTableViewController.m in Sources */, 343EB64F1D922C2C00110CE5 /* UIImage+RemoteSize.m in Sources */, 34F1A3841D88E9C400931645 /* JiaBaseViewController.m in Sources */, 343EB6501D922C2C00110CE5 /* UIImage+Resize.m in Sources */, + 34F83CB41D9B9EB60085A540 /* JiaBaseRequest.m in Sources */, 343EB6231D922C2C00110CE5 /* CAShapeLayer+UIBezierPath.m in Sources */, 343EB5D91D922C2B00110CE5 /* NSDate+Formatter.m in Sources */, 343EB6441D922C2C00110CE5 /* UIImage+animatedGIF.m in Sources */, 343EB5FD1D922C2B00110CE5 /* NSObject+Runtime.m in Sources */, 343EB5FF1D922C2B00110CE5 /* NSSet+Block.m in Sources */, + 3479FD1B1D94D9D60084C9AB /* FLEXRealmDatabaseManager.m in Sources */, 343EB3B11D9220B300110CE5 /* DesignerServiceApi.m in Sources */, 343EB61B1D922C2B00110CE5 /* NSUserDefaults+SafeAccess.m in Sources */, 343EB6261D922C2C00110CE5 /* UIApplication+ApplicationSize.m in Sources */, @@ -2815,17 +3521,26 @@ 34732AA91D93781500EE0D14 /* DDMultiFormatter.m in Sources */, 343EB6291D922C2C00110CE5 /* UIApplication+Permissions.m in Sources */, 343EB69B1D922C2C00110CE5 /* UIWebView+Canvas.m in Sources */, + 34F83CBD1D9B9EB60085A540 /* YTKRequest.m in Sources */, 343EB60A1D922C2B00110CE5 /* NSString+RegexCategory.m in Sources */, + 341F2D401D9A368D00379D48 /* JiaUserConfigManager.m in Sources */, + 3479FD121D94D9D60084C9AB /* FLEXDefaultEditorViewController.m in Sources */, 3468FFE11D90CA1A00A69723 /* README.md in Sources */, 343EB5F41D922C2B00110CE5 /* NSObject+AppInfo.m in Sources */, + 3479FD2B1D94D9D60084C9AB /* FLEXLiveObjectsTableViewController.m in Sources */, + 3479FD301D94D9D60084C9AB /* FLEXManager.m in Sources */, + 3479FD2C1D94D9D60084C9AB /* FLEXWebViewController.m in Sources */, 3468FFDB1D90CA1A00A69723 /* ReachStateUnloaded.m in Sources */, 343EB6431D922C2C00110CE5 /* UIImage+Alpha.m in Sources */, 343EB6351D922C2C00110CE5 /* UIButton+Submitting.m in Sources */, + 34F83CBC1D9B9EB60085A540 /* YTKNetworkPrivate.m in Sources */, 343EB6951D922C2C00110CE5 /* UIViewController+MJPopupViewController.m in Sources */, 343EB68D1D922C2C00110CE5 /* UIView+Toast.m in Sources */, 343EB5DC1D922C2B00110CE5 /* NSDate+TimeAgo.m in Sources */, + 3411DD401D93D3CB00077FAD /* CLIColor.m in Sources */, 343EB62D1D922C2C00110CE5 /* UIBezierPath+LxThroughPointsBezier.m in Sources */, 343EB3BB1D922BC900110CE5 /* AppDelegate.m in Sources */, + 3479FD511D94D9D60084C9AB /* FLEXImagePreviewViewController.m in Sources */, 343EB5DB1D922C2B00110CE5 /* NSDate+Reporting.m in Sources */, 343EB6B81D92550300110CE5 /* NSData+zlib.m in Sources */, 343EB6141D922C2B00110CE5 /* NSTimer+Blocks.m in Sources */, @@ -2845,17 +3560,23 @@ 343EB6311D922C2C00110CE5 /* UIButton+Block.m in Sources */, 343EB65F1D922C2C00110CE5 /* UINavigationController+FDFullscreenPopGesture.m in Sources */, 343EB67D1D922C2C00110CE5 /* UITextView+PlaceHolder.m in Sources */, + 3479FD3D1D94D9D60084C9AB /* FLEXDictionaryExplorerViewController.m in Sources */, + 3479FD051D94D9D60084C9AB /* FLEXArgumentInputColorView.m in Sources */, 343EB67F1D922C2C00110CE5 /* UIView+Animation.m in Sources */, + 3411DD421D93DA4300077FAD /* XAspect-AnalyticsAppDelegate.m in Sources */, 343EB6521D922C2C00110CE5 /* UIImage+Vector.m in Sources */, 3468FFD41D90CA1A00A69723 /* MBProgressHUD+MP.m in Sources */, 343EB6821D922C2C00110CE5 /* UIView+CustomBorder.m in Sources */, + 3479FD371D94D9D60084C9AB /* FLEXNetworkTransactionTableViewCell.m in Sources */, 343EB63A1D922C2C00110CE5 /* UIColor+Random.m in Sources */, 343EB6671D922C2C00110CE5 /* UIResponder+Chain.m in Sources */, 343EB5FA1D922C2B00110CE5 /* NSObject+KVOBlocks.m in Sources */, + 3479FD0E1D94D9D60084C9AB /* FLEXArgumentInputSwitchView.m in Sources */, 343EB6161D922C2B00110CE5 /* NSURL+QueryDictionary.m in Sources */, 347BAFF81D87EB0500D12F0B /* JiaMediator+UserModuleActions.m in Sources */, 343EB6871D922C2C00110CE5 /* UIView+Frame.m in Sources */, 343EB61D1D922C2B00110CE5 /* MKMapView+MoveLogo.m in Sources */, + 3479FD3A1D94D9D60084C9AB /* FLEXArrayExplorerViewController.m in Sources */, 343EB6791D922C2C00110CE5 /* UITextField+History.m in Sources */, 347BB0011D87EB5D00D12F0B /* Target_User.m in Sources */, 343EB5F81D922C2B00110CE5 /* NSObject+EasyCopy.m in Sources */, @@ -2867,18 +3588,28 @@ 343EB6781D922C2C00110CE5 /* UITextField+Blocks.m in Sources */, 34732AA61D93781500EE0D14 /* DDTTYLogger.m in Sources */, 343EB6661D922C2C00110CE5 /* UIPopoverController+iPhone.m in Sources */, + 3479FD0C1D94D9D60084C9AB /* FLEXArgumentInputStringView.m in Sources */, 3468FFDC1D90CA1A00A69723 /* ReachStateUnReachable.m in Sources */, + 34919F901D990F1E004B7307 /* JiaPathchHelper.m in Sources */, 343EB6801D922C2C00110CE5 /* UIView+BlockGesture.m in Sources */, + 3479FD261D94D9D60084C9AB /* FLEXFileBrowserSearchOperation.m in Sources */, 3468FFDF1D90CA1A00A69723 /* PingFoundation.m in Sources */, 343EB69E1D922C2C00110CE5 /* UIWebView+MetaParser.m in Sources */, 343EB5CB1D922C2B00110CE5 /* CLLocation+CH1903.m in Sources */, + 34F83CBB1D9B9EB60085A540 /* YTKNetworkConfig.m in Sources */, + 34F83CB31D9B9EB60085A540 /* AFDownloadRequestOperation.m in Sources */, 343EB6491D922C2C00110CE5 /* UIImage+FileName.m in Sources */, 3468FFD71D90CA1A00A69723 /* FSMEngine.m in Sources */, 3468FFDA1D90CA1A00A69723 /* ReachStateLoading.m in Sources */, 343EB61E1D922C2B00110CE5 /* MKMapView+ZoomLevel.m in Sources */, + 3479FD0D1D94D9D60084C9AB /* FLEXArgumentInputStructView.m in Sources */, 343EB6011D922C2B00110CE5 /* NSString+Base64.m in Sources */, - 343EB3A01D92178C00110CE5 /* YTKChainRequestAgent.m in Sources */, + 3479FD151D94D9D60084C9AB /* FLEXIvarEditorViewController.m in Sources */, + 3479FD281D94D9D60084C9AB /* FLEXGlobalsTableViewController.m in Sources */, + 34F83CB61D9B9EB60085A540 /* YTKBatchRequest.m in Sources */, + 3479FD111D94D9D60084C9AB /* FLEXArgumentInputViewFactory.m in Sources */, 343EB6881D922C2C00110CE5 /* UIView+GestureCallback.m in Sources */, + 3411DD451D93DBCD00077FAD /* JiaAnalyticsConfigManager.m in Sources */, 343EB6BE1D92568700110CE5 /* JiaAppDelegate+myGt.m in Sources */, 343EB6191D922C2B00110CE5 /* NSURLRequest+ParamsFromDictionary.m in Sources */, 343EB5E51D922C2B00110CE5 /* NSDictionary+XML.m in Sources */, @@ -2891,38 +3622,52 @@ 343EB5F21D922C2B00110CE5 /* NSNumber+Round.m in Sources */, 343EB3B51D92226500110CE5 /* JiaBaseRequest+App.m in Sources */, 343EB63B1D922C2C00110CE5 /* UIColor+Web.m in Sources */, + 3479FD421D94D9D60084C9AB /* FLEXObjectExplorerViewController.m in Sources */, 343EB5E21D922C2B00110CE5 /* NSDictionary+Merge.m in Sources */, 343EB6481D922C2C00110CE5 /* UIImage+Color.m in Sources */, 343EB64A1D922C2C00110CE5 /* UIImage+FX.m in Sources */, 343EB6001D922C2B00110CE5 /* NSMutableString+Ruby.m in Sources */, 343EB6171D922C2B00110CE5 /* NSURLConnection+SelfSigned.m in Sources */, 347BB00A1D87EBD800D12F0B /* UserViewController.m in Sources */, + 341F2D501D9A429C00379D48 /* DesignerDetailModel.m in Sources */, 343EB5F51D922C2B00110CE5 /* NSObject+AssociatedObject.m in Sources */, + 3479FD191D94D9D60084C9AB /* FLEXWindow.m in Sources */, 343EB65C1D922C2C00110CE5 /* UILabel+SuggestSize.m in Sources */, 343EB6121D922C2B00110CE5 /* NSString+XML.m in Sources */, 343EB67B1D922C2C00110CE5 /* UITextField+Shake.m in Sources */, 343EB62C1D922C2C00110CE5 /* UIBezierPath+Length.m in Sources */, 343EB6211D922C2C00110CE5 /* CALayer+UIColor.m in Sources */, 3468FFD61D90CA1A00A69723 /* LocalConnection.m in Sources */, - 34732A9F1D93781500EE0D14 /* CLIColor.m in Sources */, 343EB67A1D922C2C00110CE5 /* UITextField+Select.m in Sources */, 343EB5EB1D922C2B00110CE5 /* NSInvocation+Bb.m in Sources */, 343EB5E61D922C2B00110CE5 /* NSException+Trace.m in Sources */, 343EB6A01D922C2C00110CE5 /* UIWebVIew+SwipeGesture.m in Sources */, + 3479FD071D94D9D60084C9AB /* FLEXArgumentInputFontsPickerView.m in Sources */, + 3479FD2D1D94D9D60084C9AB /* FLEXSystemLogMessage.m in Sources */, + 3479FD131D94D9D60084C9AB /* FLEXFieldEditorView.m in Sources */, 343EB6411D922C2C00110CE5 /* UIFont+WDCustomLoader.m in Sources */, 343EB6761D922C2C00110CE5 /* UITableViewCell+NIB.m in Sources */, 343EB6811D922C2C00110CE5 /* UIView+Constraints.m in Sources */, 343EB5FC1D922C2B00110CE5 /* NSObject+Reflection.m in Sources */, + 3479FD311D94D9D60084C9AB /* FLEXNetworkCurlLogger.m in Sources */, + 3479FD331D94D9D60084C9AB /* FLEXNetworkRecorder.m in Sources */, 347BAFA21D87E30200D12F0B /* main.m in Sources */, + 34F83C961D9B58030085A540 /* YYDiskCache.m in Sources */, + 3479FD401D94D9D60084C9AB /* FLEXLayerExplorerViewController.m in Sources */, + 3411DD481D93DCD700077FAD /* JiaAnalyticsHelper.m in Sources */, 343EB67C1D922C2C00110CE5 /* UITextView+PinchZoom.m in Sources */, 343EB3BC1D922BC900110CE5 /* ViewController.m in Sources */, 34732AB41D9383C300EE0D14 /* JiaCoreHelper.m in Sources */, 3468FFD81D90CA1A00A69723 /* FSMStateUtil.m in Sources */, + 3479FD4D1D94D9D60084C9AB /* FLEXRuntimeUtility.m in Sources */, 343EB5CF1D922C2B00110CE5 /* NSBundle+AppIcon.m in Sources */, 343EB6841D922C2C00110CE5 /* UIView+draggable.m in Sources */, 34732AA71D93781500EE0D14 /* DDContextFilterLogFormatter.m in Sources */, + 3479FD4C1D94D9D60084C9AB /* FLEXResources.m in Sources */, + 34F83CB51D9B9EB60085A540 /* YTKBaseRequest.m in Sources */, 34732AA41D93781500EE0D14 /* DDFileLogger.m in Sources */, 343EB60B1D922C2B00110CE5 /* NSString+RemoveEmoji.m in Sources */, + 34919F961D991241004B7307 /* GVUserDefaults+JiaCore.m in Sources */, 343EB6251D922C2C00110CE5 /* UIAlertView+Block.m in Sources */, 343EB6321D922C2C00110CE5 /* UIButton+CountDown.m in Sources */, 343EB69D1D922C2C00110CE5 /* UIWebView+Load.m in Sources */, @@ -2933,8 +3678,6 @@ 343EB65A1D922C2C00110CE5 /* UILabel+AutoSize.m in Sources */, 347BB0071D87EBB700D12F0B /* ProjectViewController.m in Sources */, 3468FFEE1D91541A00A69723 /* jiaDesignerConfigManager.m in Sources */, - 343EB3A11D92178C00110CE5 /* YTKNetworkAgent.m in Sources */, - 343EB3AB1D921E1200110CE5 /* JiaBaseRequest.m in Sources */, 343EB6911D922C2C00110CE5 /* UIViewController+BackButtonItemTitle.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/jiaModuleDemo/App/AppDelegate.h b/jiaModuleDemo/App/AppDelegate.h index 39c7ad6..aeccde8 100644 --- a/jiaModuleDemo/App/AppDelegate.h +++ b/jiaModuleDemo/App/AppDelegate.h @@ -9,6 +9,7 @@ #import #import "JiaAppDelegate.h" +#import "JiaPathchModel.h" @interface AppDelegate : JiaAppDelegate diff --git a/jiaModuleDemo/App/AppDelegate.m b/jiaModuleDemo/App/AppDelegate.m index a1b7106..1adf183 100644 --- a/jiaModuleDemo/App/AppDelegate.m +++ b/jiaModuleDemo/App/AppDelegate.m @@ -13,6 +13,9 @@ #import "jiaGTConfigManager.h" #import "jiaDesignerConfigManager.h" +#import "JiaAnalyticsConfigManager.h" +#import "JiaAnalyticsHelper.h" + @interface AppDelegate () @end @@ -25,19 +28,53 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( //JiaCore基础模块相关配置 JiaCoreConfigManager *jiaCoreConfig=[JiaCoreConfigManager sharedInstance]; jiaCoreConfig.recordlogger=YES; + jiaCoreConfig.openDebug=NO; + + //热更新内容 + JiaPathchModel *sample=[[JiaPathchModel alloc]init]; + sample.patchId = @"patchId_sample1"; + sample.md5 = @"2cf1c6f6c5632dc21224bf42c698706b"; + sample.url = @"http://test.qshmall.net:9090/demo1.js"; + sample.ver = @"1"; + + JiaPathchModel *sample1=[[JiaPathchModel alloc]init]; + sample1.patchId = @"patchId_sample2"; + sample1.md5 = @"e8a4eaeadce5a4598fb9a868e09c75fd"; + sample1.url = @"http://test.qshmall.net:9090/demo2.js"; + sample1.ver = @"1"; + jiaCoreConfig.jSPatchMutableArray=[@[sample,sample1] mutableCopy]; //设置模块jiaDesigner相关配置 jiaDesignerConfigManager *jiaDesignerConfig=[jiaDesignerConfigManager sharedInstance]; jiaDesignerConfig.prefixNetWorkUrl=@"http://private.com/"; + //设置个推模块的配置 JiaGTConfigManager *gtConfig=[JiaGTConfigManager sharedInstance]; gtConfig.jiaGTAppId=@"0uuwznWonIANoK07JeRWgAs"; gtConfig.jiaGTAppKey=@"26LeO4stbrA7TeyMUJdXlx3"; gtConfig.jiaGTAppSecret=@"2282vl0IwZd9KL3ZpDyoUL7"; + + //友盟统计设置 + JiaAnalyticsConfigManager *jiaAnalyticsConfig=[JiaAnalyticsConfigManager sharedInstance]; + jiaAnalyticsConfig.analyticsAppKey=@"57e3f1cbe0f55a42080011ec"; + jiaAnalyticsConfig.analyticsChannelID=@"App Store"; + jiaAnalyticsConfig.analyticsLogEnabled=YES; + +// //要统计页面的前缀 +// jiaAnalyticsConfig.prefixFilterArray=@[@"ZU",@"DB"]; +// //不符合前缀 但也要被统计进来的页面 +// jiaAnalyticsConfig.fileterNameArray=@[@"defaultViewController",@"nativeViewController"]; +// //符合页面的前缀 但不要进行统计的页面 +// jiaAnalyticsConfig.noFileterNameArray=@[@"ZUDeaultViewcontroller"]; + + //开始AOP方式统计 + [JiaAnalyticsHelper jiaAnalyticsViewController]; + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; ViewController *vc = [[ViewController alloc]init]; UINavigationController *navc = [[UINavigationController alloc]initWithRootViewController:vc]; @@ -45,6 +82,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; + + + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } diff --git a/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.h b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.h new file mode 100644 index 0000000..72e4e1f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.h @@ -0,0 +1,30 @@ +// +// JiaAnalyticsConfigManager.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/22. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +#define JiaAnalyticsConfigManagerInstance [JiaAnalyticsConfigManager sharedInstance] + +@interface JiaAnalyticsConfigManager : NSObject + ++ (JiaAnalyticsConfigManager *)sharedInstance; + +//友盟统计配置 友盟key,chanel,是否开启SDK调试,是否开启闪退记录 +@property (strong, nonatomic) NSString *analyticsAppKey; +@property (strong, nonatomic) NSString *analyticsChannelID; +@property (nonatomic,getter=isLogEnabled) BOOL analyticsLogEnabled; +@property(nonatomic) BOOL bCrashReportEnabled; + +//要统计的开头页面的前缀字符串数组 比如"CF" +@property(strong,nonatomic)NSArray *prefixFilterArray; +//要统计的页面名称字符串数组 比如"detailViewController" +@property(strong,nonatomic)NSArray *fileterNameArray; +//不统计的页面名称字符串数组 +@property(strong,nonatomic)NSArray *noFileterNameArray; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.m b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.m new file mode 100644 index 0000000..0f5ed8c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsConfigManager.m @@ -0,0 +1,24 @@ +// +// JiaAnalyticsConfigManager.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/22. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaAnalyticsConfigManager.h" + +@implementation JiaAnalyticsConfigManager + ++ (JiaAnalyticsConfigManager *)sharedInstance +{ + static JiaAnalyticsConfigManager* instance = nil; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [JiaAnalyticsConfigManager new]; + }); + return instance; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.h b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.h new file mode 100644 index 0000000..b8db8b8 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.h @@ -0,0 +1,38 @@ +// +// JiaAnalyticsHelper.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/22. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface JiaAnalyticsHelper : NSObject + +//统计进入跟离开viewController ++(void)jiaAnalyticsViewController; + +/// 在viewWillAppear调用,才能够获取正确的页面访问路径、访问深度(PV)的数据 ++ (void)beginLogPageView:(__unsafe_unretained Class)pageView; + +/// 在viewDidDisappeary调用,才能够获取正确的页面访问路径、访问深度(PV)的数据 ++ (void)endLogPageView:(__unsafe_unretained Class)pageView; + + +/*! + * 自定义名称 + */ +/// 在viewWillAppear调用,才能够获取正确的页面访问路径、访问深度(PV)的数据 ++(void)beginLogPageViewName:(NSString *)pageViewName; + +/// 在viewDidDisappeary调用,才能够获取正确的页面访问路径、访问深度(PV)的数据 ++(void)endLogPageViewName:(NSString *)pageViewName; + + +/// 自定义事件 ++(void)logEvent:(NSString*)eventId; + ++(void)logEvent:(NSString*)eventId attributes:(NSDictionary *)attributes; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.m b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.m new file mode 100644 index 0000000..53d3c53 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaAnalytics/JiaAnalyticsHelper.m @@ -0,0 +1,107 @@ +// +// JiaAnalyticsHelper.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/22. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaAnalyticsHelper.h" +#import "UMMobClick/MobClick.h" +#import "JiaAnalyticsConfigManager.h" +#import "Aspects.h" + +@implementation JiaAnalyticsHelper + ++(void)jiaAnalyticsViewController +{ + //放到异步线程去执行 + __weak typeof(self) ws = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + [UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id info, BOOL animated){ + UIViewController *controller = [info instance]; + BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])]; + if (filterResult) { + [ws beginLogPageView:[controller class]]; + } + } error:NULL]; + + [UIViewController aspect_hookSelector:@selector(viewWillDisappear:) withOptions:AspectPositionAfter usingBlock:^(id info, BOOL animated){ + UIViewController *controller = [info instance]; + BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])]; + if (filterResult) { + [ws endLogPageView:[controller class]]; + } + } error:NULL]; + }); +} + ++ (void)beginLogPageView:(__unsafe_unretained Class)pageView { + [MobClick beginLogPageView:NSStringFromClass(pageView)]; + return; +} + ++ (void)endLogPageView:(__unsafe_unretained Class)pageView { + [MobClick endLogPageView:NSStringFromClass(pageView)]; + return; +} + ++(void)beginLogPageViewName:(NSString *)pageViewName +{ + [MobClick beginLogPageView:pageViewName]; + return; +} + ++(void)endLogPageViewName:(NSString *)pageViewName +{ + [MobClick endLogPageView:pageViewName]; + return; +} + ++(void)logEvent:(NSString*)eventId +{ + [MobClick event:eventId]; +} + ++(void)logEvent:(NSString*)eventId attributes:(NSDictionary *)attributes +{ + [MobClick event:eventId attributes:attributes]; +} + +#pragma mark 自定义代码区 + ++(BOOL)fileterWithControllerName:(NSString *)controllerName +{ + BOOL Result=NO; + + if (JiaAnalyticsConfigManagerInstance.prefixFilterArray.count==0&&JiaAnalyticsConfigManagerInstance.noFileterNameArray.count==0&&JiaAnalyticsConfigManagerInstance.fileterNameArray.count==0) { + return YES; + } + + //判断是否在符合前缀里面 + if (JiaAnalyticsConfigManagerInstance.prefixFilterArray) { + for (NSString *prefixItem in JiaAnalyticsConfigManagerInstance.prefixFilterArray) { + if ([controllerName hasPrefix:prefixItem]) { + Result=YES; + break; + } + } + } + //若有符合前缀则执行下面的内容 再进行判断当前页面是否要被省略掉的页面 + if (Result) { + if ([JiaAnalyticsConfigManagerInstance.noFileterNameArray containsObject:controllerName]) { + Result=NO; + } + } + else + { + if ([JiaAnalyticsConfigManagerInstance.fileterNameArray containsObject:controllerName]) { + Result=YES; + } + } + + return Result; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaAnalytics/XAspect-AnalyticsAppDelegate.m b/jiaModuleDemo/BaseModule/JiaAnalytics/XAspect-AnalyticsAppDelegate.m new file mode 100644 index 0000000..9449667 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaAnalytics/XAspect-AnalyticsAppDelegate.m @@ -0,0 +1,42 @@ +// +// XAspect-LogAppDelegate.m +// MobileProject 抽离原本应在AppDelegate友盟统计内容 +// +// Created by wujunyang on 16/6/22. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaAppDelegate.h" +#import "XAspect.h" +#import "UMMobClick/MobClick.h" +#import "JiaAnalyticsConfigManager.h" + +#define AtAspect AnalyticsAppDelegate + +#define AtAspectOfClass JiaAppDelegate +@classPatchField(JiaAppDelegate) + +AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) +{ + NSLog(@"成功加载友盟统计"); + + UMConfigInstance.appKey=JiaAnalyticsConfigManagerInstance.analyticsAppKey; + UMConfigInstance.channelId=JiaAnalyticsConfigManagerInstance.analyticsChannelID; + UMConfigInstance.bCrashReportEnabled=!JiaAnalyticsConfigManagerInstance.bCrashReportEnabled?NO:YES; + [MobClick startWithConfigure:UMConfigInstance]; + // version标识 + NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; + [MobClick setAppVersion:version]; + + if(JiaAnalyticsConfigManagerInstance.isLogEnabled) + { + [MobClick setLogEnabled:YES]; + } + + + return XAMessageForward(application:application didFinishLaunchingWithOptions:launchOptions); +} + +@end +#undef AtAspectOfClass +#undef AtAspect diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.h b/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.h index 24bcf3f..3c5138a 100644 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.h +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.h @@ -11,6 +11,7 @@ #import "JiaFileLogger.h" #import "JiaCoreConfigManager.h" #import "JiaCoreHelper.h" +#import "FLEXManager.h" @interface JiaAppDelegate : UIResponder diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.m b/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.m index 5ad5e25..115dd6d 100644 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.m +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaAppDelegate.m @@ -16,12 +16,18 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [GLobalRealReachability startNotifier]; //是否开始日志记录功能 - if([JiaCoreConfigManager sharedInstance].isRecordlogger) + if(JiaCoreConfigManagerInstance.isRecordlogger) { NSLog(@"开启日志记录功能"); [JiaFileLogger sharedManager]; } + if(JiaCoreConfigManagerInstance.isOpenDebug) + { + NSLog(@"开启调试插件功能"); + [[FLEXManager sharedManager] showExplorer]; + } + return YES; } diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCore.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCore.h new file mode 100644 index 0000000..4fae81e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCore.h @@ -0,0 +1,28 @@ +// +// JiaCore.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/28. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#ifndef JiaCore_h +#define JiaCore_h + + +#import "MBProgressHUD+MP.h" +#import "RealReachability.h" +#import "YYCache.h" +#import "JiaCocoaLumberjack.h" +#import "GVUserDefaults.h" +#import "YTKNetwork.h" + +#import "JiaBaseViewController.h" +#import "JiaAppDelegate.h" +#import "JiaMediator.h" +#import "JiaCoreConfigManager.h" +#import "JiaBaseRequest.h" + +#import "JiaPathchModel.h" + +#endif /* JiaCore_h */ diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.h new file mode 100644 index 0000000..e000c98 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.h @@ -0,0 +1,15 @@ +// +// GVUserDefaults+JiaCore.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "GVUserDefaults.h" + +#define JiaCoreUserDefault [GVUserDefaults standardUserDefaults] + +@interface GVUserDefaults (JiaCore) + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.m new file mode 100644 index 0000000..22b4507 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/GVUserDefaults+JiaCore.m @@ -0,0 +1,13 @@ +// +// GVUserDefaults+JiaCore.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "GVUserDefaults+JiaCore.h" + +@implementation GVUserDefaults (JiaCore) + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.h index d3e0e0a..d7ba4aa 100644 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.h +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.h @@ -8,17 +8,7 @@ #import -//日志记录等级 -typedef NS_ENUM(NSInteger, JiaCoreLoggerLevel) { - JiaCoreLoggerLevelOff, - JiaCoreLoggerLevelErro, - JiaCoreLoggerLevelWarning, - JiaCoreLoggerLevelInfo, - JiaCoreLoggerLevelDebug, - JiaCoreLoggerLevelVerbose, - JiaCoreLoggerLevelAll -}; - +#define JiaCoreConfigManagerInstance [JiaCoreConfigManager sharedInstance] @interface JiaCoreConfigManager : NSObject @@ -26,5 +16,9 @@ typedef NS_ENUM(NSInteger, JiaCoreLoggerLevel) { //是否开启日志记录 @property(nonatomic, assign, getter = isRecordlogger) BOOL recordlogger; +//是否开启调试插件 +@property(nonatomic, assign, getter = isOpenDebug) BOOL openDebug; +//设置Patcth 传入JiaPathchModel类型的数组 有值则会启动JSPatch热更新功能 +@property(nonatomic,strong) NSMutableArray *jSPatchMutableArray; @end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.m index a4d9a24..55d2f7d 100644 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.m +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaCoreConfigManager.m @@ -7,6 +7,7 @@ // #import "JiaCoreConfigManager.h" +#import "JiaPathchHelper.h" @implementation JiaCoreConfigManager @@ -22,4 +23,14 @@ + (JiaCoreConfigManager *)sharedInstance return instance; } +-(void)setJSPatchMutableArray:(NSMutableArray *)jSPatchMutableArray +{ + if (jSPatchMutableArray.count>0) { + NSLog(@"开启热更新功能"); + + JiaPathchHelper *helper=[[JiaPathchHelper alloc]initWithPatchArray:jSPatchMutableArray]; + [helper loadPathchFile]; + } +} + @end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.h new file mode 100644 index 0000000..cca4253 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.h @@ -0,0 +1,19 @@ +// +// JiaPathchHelper.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface JiaPathchHelper : NSObject + +//是关于JiaPathchModel的数组 +- (instancetype)initWithPatchArray:(NSMutableArray *)array; + +//加载热更新文件 +-(void)loadPathchFile; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.m new file mode 100644 index 0000000..0028613 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchHelper.m @@ -0,0 +1,362 @@ +// +// JiaPathchHelper.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaPathchHelper.h" +#include +#import "JPEngine.h" +#import "JiaPathchModel.h" +#import "GVUserDefaults+JiaCore.h" +#import "JiaMacros.h" +#import +#import "YYCache.h" + +@interface JiaPathchHelper() + +@property(strong,nonatomic)NSMutableArray *mcPatchs; +@property(strong,nonatomic)NSMutableArray *mcLocalPatchs; //本地补丁的信息 +@property (readonly, nonatomic, copy) NSString * mcPatchCacheKey; //!< 补丁缓存时用的key值. +@end + + +@implementation JiaPathchHelper + +- (instancetype)initWithPatchArray:(NSMutableArray *)array +{ + self = [super init]; + if (self) { + self.mcPatchs=array; + } + return self; +} + + +-(void)setMcPatchs:(NSArray *)mcPatchs +{ + if (0==mcPatchs.count) { + return; + } + + if (!_mcLocalPatchs) { + _mcLocalPatchs=[[NSMutableArray alloc]init]; + } + + //获得本地缓存的值 + YYCache *myCache=[YYCache cacheWithName:self.mcPatchCacheKey]; + if ([myCache objectForKey:self.mcPatchCacheKey]) { + _mcLocalPatchs=(NSMutableArray *)[myCache objectForKey:self.mcPatchCacheKey]; + } + + //先处理要删除的文件 + for (JiaPathchModel *item in _mcLocalPatchs) { + if (![self existWithArray:mcPatchs model:item]) { + //不存在 + if ([self deleteFileWithJiaPathchModel:item]) { + [_mcLocalPatchs removeObject:item]; + } + } + } + + //接着对新补丁进行写入 + for (JiaPathchModel *item in mcPatchs) { + item.status=JiaPatchModelStatusUnInstall; + if (![self existWithArray:_mcLocalPatchs model:item]&&[item.ver isEqualToString:[self mcCurrentVer]]) { + //不存在 要进行下载 并只对正确的版本进行 + [self mcUpdatePatchFile:item]; + [_mcLocalPatchs addObject:item]; + } + } + + //重新赋值 + [myCache setObject:_mcLocalPatchs forKey:self.mcPatchCacheKey]; +} + + +-(void)loadPathchFile +{ + //然后进行安装 + [self mcUpdateAllLocalPatchFiles]; +} + +/** + * @author wujunyang, 16-09-27 15:09:59 + * + * @brief 判断本地是否存在 + * + * @param array 本地数组 + * @param model 新对象 + * + * @return YES对象存在 NO对象不存在 + */ +-(BOOL)existWithArray:(NSArray *)array model:(JiaPathchModel *)model +{ + BOOL result=NO; + if (array.count==0) { + return result; + } + + if (!model) { + return result; + } + + for (JiaPathchModel *item in array) + { + if ([model.patchId isEqualToString:item.patchId]&&[model.md5 isEqualToString:item.md5]) { + result=YES; + break; + } + } + + return result; +} + +/** + * @author wujunyang, 16-09-27 16:09:55 + * + * @brief 删除文件 + * + * @param model <#model description#> + */ +-(BOOL)deleteFileWithJiaPathchModel:(JiaPathchModel *)model +{ + if (!model) { + return NO; + } + + //文件是否存在的路径 + NSString * filePath = [self mcPathForModel:model]; + NSFileManager *fm = [NSFileManager defaultManager]; + if ([fm fileExistsAtPath:filePath]) { + return [fm removeItemAtPath:filePath error:nil]; + } + + return NO; +} + +- (NSString *)mcPatchCacheKey +{ + return @"mcPatchCacheKey"; +} + +/** + * @author wujunyang, 16-09-27 13:09:37 + * + * @brief 更新单个补丁的补丁文件. + * + * @param patch 补丁模型 + */ +- (void) mcUpdatePatchFile: (JiaPathchModel *) patch +{ + if (JiaPatchModelStatusSuccess==patch.status) { + return; + } + + NSString * url = patch.url; + + NSString * savePath =[self mcPathForModel:patch]; + + //使用AFNetWork下载在服务器的js文件 + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; + AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; + NSURL *URL = [NSURL URLWithString:url]; + NSURLRequest *request = [NSURLRequest requestWithURL:URL]; + NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) + { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + if (httpResponse.statusCode==200) { + patch.status = JiaPatchModelStatusUnInstall; + //保存到本地 Library/Caches目录下 + return [NSURL fileURLWithPath:savePath]; + } + else + { + return nil; + } + } + completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) + { + if(!error){ + NSLog(@"下载完成 to: %@", filePath);} + }]; + [downloadTask resume]; +} + +/** + * 更新本地所有需要更新的补丁的补丁文件. + * + * + * @return sendNext: 文件已被更新的补丁. + */ +-(void)mcUpdateAllLocalPatchFiles +{ + if (0==self.mcLocalPatchs.count) { + return; + } + JiaCoreWeakSelf(self); + [self.mcLocalPatchs enumerateObjectsUsingBlock:^(JiaPathchModel *obj, NSUInteger idx, BOOL * _Nonnull stop) { + JiaCoreStrongSelf(self); + [self mcInstallPatch:obj]; + }]; +} + +/** + * 安装单个补丁. + * + * @param patch 补丁. + * + */ +- (void) mcInstallPatch: (JiaPathchModel *) patch +{ + // 仅安装为"未安装状态的"补丁. + if (JiaPatchModelStatusUnInstall != patch.status) { + return; + } + + NSString * path = [self mcPathForModel: patch]; + + /* 本地补丁是否存在? */ + if (YES != [[NSFileManager defaultManager] fileExistsAtPath: path]) { + patch.status = JiaPatchModelStatusFileNotExit; + + return; + } + + /* md5校验,匹配吗? */ + if (YES != [self mcVerify:path Md5: patch.md5]) { + patch.status = JiaPatchModelStatusFileNotMatch; + + return; + } + + /* 补丁安装成功了吗? */ + if (YES != [self mcEvaluateScriptFile: path]) { + patch.status = JiaPatchModelStatusUnKnownError; + + return; + } + + patch.status = JiaPatchModelStatusSuccess; +} + + +/** + * 执行某个JS文件. + * + * @param path JS文件路径. + * + * @return YES,执行成功;NO,执行失败. + */ +- (BOOL) mcEvaluateScriptFile: (NSString *) path +{ + /* 打开JSPathc引擎. */ + [JPEngine startEngine]; + + NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error: NULL]; + NSLog(@"修复内容:%@",script); + if (nil != script) { + [JPEngine evaluateScript:script]; + + // 修复成功. + return YES; + } + + return NO; +} + +/** + * 当前版本号. + * + * @return 当前版本号. + */ +- (NSString *) mcCurrentVer +{ + NSString * ver = [[NSBundle mainBundle].infoDictionary objectForKey:(NSString *)kCFBundleVersionKey]; + + return ver; +} + +/** + * 验证文件的md5值是否与给定的md5匹配. + * + * @param filePath 本地文件路径. + * @param md5 应该具有的md5值. + * + * @return YES,文件md5与给定的md5匹配;NO,不匹配或文件不存在. + */ +- (BOOL)mcVerify:(NSString *)filePath Md5: (NSString *)md5 +{ + NSString * fileMd5 = [self mcMd5HashOfPath: filePath]; + + BOOL result = [md5 isEqualToString:fileMd5]; + + return result; +} + +/** + * 获取文件的md5信息. + * + * @param path 文件路径. + * + * @return 文件的md5值. + */ +-(NSString *)mcMd5HashOfPath:(NSString *)path +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + + // 确保文件存在. + if( [fileManager fileExistsAtPath:path isDirectory:nil] ) + { + NSData *data = [NSData dataWithContentsOfFile:path]; + unsigned char digest[CC_MD5_DIGEST_LENGTH]; + CC_MD5( data.bytes, (CC_LONG)data.length, digest ); + + NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; + + for( int i = 0; i < CC_MD5_DIGEST_LENGTH; i++ ) + { + [output appendFormat:@"%02x", digest[i]]; + } + + return output; + } + else + { + return @""; + } +} + +/** + * 获取某个补丁的本地存储路径. + * + * 注意: 此方法仅会根据既定规则计算出补丁应具有的路径,但是该路径下可能暂无对应文件. + * + * @param model 补丁模型. + * + * @return 补丁的本地存储路径. + */ +- (NSString *) mcPathForModel: (JiaPathchModel *) model +{ + + NSArray * paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString * libCachePath = [[paths objectAtIndex:0] stringByAppendingFormat:@"/Caches"]; + + NSString * patchRootPath = [libCachePath stringByAppendingString:[NSString stringWithFormat:@"/patch/%@", [self mcCurrentVer]]]; + + if ( NO == [[NSFileManager defaultManager] fileExistsAtPath:patchRootPath] ) + { + [[NSFileManager defaultManager] createDirectoryAtPath:patchRootPath + withIntermediateDirectories:YES + attributes:nil + error:NULL]; + } + + NSString * path = [patchRootPath stringByAppendingString:[NSString stringWithFormat:@"/%@", model.patchId]]; + + return path; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.h new file mode 100644 index 0000000..c8f16bf --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.h @@ -0,0 +1,32 @@ +// +// JiaPathchModel.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +//补丁状态枚举 +typedef enum : NSUInteger { + JiaPatchModelStatusUnKnownError, //!< 未知错误. + JiaPatchModelStatusUnInstall, //!< 尚未开始安装.应用初始时,所有本地补丁状态均为此;补丁更新或新增的补丁;在下载完成后,状态也会设置为此. + JiaPatchModelStatusSuccess, //!< 安装成功. + JiaPatchModelStatusFileNotExit, //!< 本地补丁文件不存在. + JiaPatchModelStatusFileNotMatch, //!< 本地补丁MD5与给定的MD5值不匹配. + JiaPatchModelStatusUpdate, //!< 此补丁有更新.即服务器最新返回的补丁列表中包含此补丁,但补丁的md5或url已改变. + JiaPatchModelStatusAdd //!< 此补丁为新增的.即服务器最新返回的补丁列表中新添加的补丁. +} JiaPatchModelStatus; + + + +@interface JiaPathchModel : NSObject + +@property (copy, nonatomic) NSString * patchId; //补丁id.用于唯一标记一个补丁.因为补丁,后期可能需要更新,删除,添加等操作. +@property (copy, nonatomic) NSString * md5; //文件的md5值,用于校验. +@property (copy, nonatomic) NSString * url; //文件的URL路径. +@property (copy, nonatomic) NSString * ver; //补丁对应的APP版本.不需要服务器返回,但需要本地存储此值.这个值在涉及到多个版本的补丁共存时,在应用升级时会很有价值. +@property (assign, nonatomic) JiaPatchModelStatus status; //补丁状态.此状态值由本地管理和维护. + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.m new file mode 100644 index 0000000..b866bc5 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaPathchHelper/JiaPathchModel.m @@ -0,0 +1,13 @@ +// +// JiaPathchModel.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/26. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaPathchModel.h" + +@implementation JiaPathchModel + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h new file mode 100755 index 0000000..ab3bd7b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputColorView.h +// Flipboard +// +// Created by Ryan Olson on 6/30/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputColorView : FLEXArgumentInputView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m new file mode 100755 index 0000000..af9ae46 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m @@ -0,0 +1,329 @@ +// +// FLEXArgumentInputColorView.m +// Flipboard +// +// Created by Ryan Olson on 6/30/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputColorView.h" +#import "FLEXUtility.h" +#import "FLEXRuntimeUtility.h" + +@protocol FLEXColorComponentInputViewDelegate; + +@interface FLEXColorComponentInputView : UIView + +@property (nonatomic, strong) UISlider *slider; +@property (nonatomic, strong) UILabel *valueLabel; + +@property (nonatomic, weak) id delegate; + +@end + +@protocol FLEXColorComponentInputViewDelegate + +- (void)colorComponentInputViewValueDidChange:(FLEXColorComponentInputView *)colorComponentInputView; + +@end + + +@implementation FLEXColorComponentInputView + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.slider = [[UISlider alloc] init]; + self.slider.backgroundColor = self.backgroundColor; + [self.slider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged]; + [self addSubview:self.slider]; + + self.valueLabel = [[UILabel alloc] init]; + self.valueLabel.backgroundColor = self.backgroundColor; + self.valueLabel.font = [FLEXUtility defaultFontOfSize:14.0]; + self.valueLabel.textAlignment = NSTextAlignmentRight; + [self addSubview:self.valueLabel]; + + [self updateValueLabel]; + } + return self; +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + self.slider.backgroundColor = backgroundColor; + self.valueLabel.backgroundColor = backgroundColor; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + const CGFloat kValueLabelWidth = 50.0; + + [self.slider sizeToFit]; + CGFloat sliderWidth = self.bounds.size.width - kValueLabelWidth; + self.slider.frame = CGRectMake(0, 0, sliderWidth, self.slider.frame.size.height); + + [self.valueLabel sizeToFit]; + CGFloat valueLabelOriginX = CGRectGetMaxX(self.slider.frame); + CGFloat valueLabelOriginY = FLEXFloor((self.slider.frame.size.height - self.valueLabel.frame.size.height) / 2.0); + self.valueLabel.frame = CGRectMake(valueLabelOriginX, valueLabelOriginY, kValueLabelWidth, self.valueLabel.frame.size.height); +} + +- (void)sliderChanged:(id)sender +{ + [self.delegate colorComponentInputViewValueDidChange:self]; + [self updateValueLabel]; +} + +- (void)updateValueLabel +{ + self.valueLabel.text = [NSString stringWithFormat:@"%.3f", self.slider.value]; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat height = [self.slider sizeThatFits:size].height; + return CGSizeMake(size.width, height); +} + +@end + +@interface FLEXColorPreviewBox : UIView + +@property (nonatomic, strong) UIColor *color; + +@property (nonatomic, strong) UIView *colorOverlayView; + +@end + +@implementation FLEXColorPreviewBox + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.layer.borderWidth = 1.0; + self.layer.borderColor = [[UIColor blackColor] CGColor]; + self.backgroundColor = [UIColor colorWithPatternImage:[[self class] backgroundPatternImage]]; + + self.colorOverlayView = [[UIView alloc] initWithFrame:self.bounds]; + self.colorOverlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.colorOverlayView.backgroundColor = [UIColor clearColor]; + [self addSubview:self.colorOverlayView]; + } + return self; +} + +- (void)setColor:(UIColor *)color +{ + self.colorOverlayView.backgroundColor = color; +} + +- (UIColor *)color +{ + return self.colorOverlayView.backgroundColor; +} + ++ (UIImage *)backgroundPatternImage +{ + const CGFloat kSquareDimension = 5.0; + CGSize squareSize = CGSizeMake(kSquareDimension, kSquareDimension); + CGSize imageSize = CGSizeMake(2.0 * kSquareDimension, 2.0 * kSquareDimension); + + UIGraphicsBeginImageContextWithOptions(imageSize, YES, [[UIScreen mainScreen] scale]); + + [[UIColor whiteColor] setFill]; + UIRectFill(CGRectMake(0, 0, imageSize.width, imageSize.height)); + + [[UIColor grayColor] setFill]; + UIRectFill(CGRectMake(squareSize.width, 0, squareSize.width, squareSize.height)); + UIRectFill(CGRectMake(0, squareSize.height, squareSize.width, squareSize.height)); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + +@end + +@interface FLEXArgumentInputColorView () + +@property (nonatomic, strong) FLEXColorPreviewBox *colorPreviewBox; +@property (nonatomic, strong) UILabel *hexLabel; +@property (nonatomic, strong) FLEXColorComponentInputView *alphaInput; +@property (nonatomic, strong) FLEXColorComponentInputView *redInput; +@property (nonatomic, strong) FLEXColorComponentInputView *greenInput; +@property (nonatomic, strong) FLEXColorComponentInputView *blueInput; + +@end + +@implementation FLEXArgumentInputColorView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.colorPreviewBox = [[FLEXColorPreviewBox alloc] init]; + [self addSubview:self.colorPreviewBox]; + + self.hexLabel = [[UILabel alloc] init]; + self.hexLabel.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9]; + self.hexLabel.textAlignment = NSTextAlignmentCenter; + self.hexLabel.font = [FLEXUtility defaultFontOfSize:12.0]; + [self addSubview:self.hexLabel]; + + self.alphaInput = [[FLEXColorComponentInputView alloc] init]; + self.alphaInput.slider.minimumTrackTintColor = [UIColor blackColor]; + self.alphaInput.delegate = self; + [self addSubview:self.alphaInput]; + + self.redInput = [[FLEXColorComponentInputView alloc] init]; + self.redInput.slider.minimumTrackTintColor = [UIColor redColor]; + self.redInput.delegate = self; + [self addSubview:self.redInput]; + + self.greenInput = [[FLEXColorComponentInputView alloc] init]; + self.greenInput.slider.minimumTrackTintColor = [UIColor greenColor]; + self.greenInput.delegate = self; + [self addSubview:self.greenInput]; + + self.blueInput = [[FLEXColorComponentInputView alloc] init]; + self.blueInput.slider.minimumTrackTintColor = [UIColor blueColor]; + self.blueInput.delegate = self; + [self addSubview:self.blueInput]; + } + return self; +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + self.alphaInput.backgroundColor = backgroundColor; + self.redInput.backgroundColor = backgroundColor; + self.greenInput.backgroundColor = backgroundColor; + self.blueInput.backgroundColor = backgroundColor; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat runningOriginY = 0; + CGSize constrainSize = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX); + + self.colorPreviewBox.frame = CGRectMake(0, runningOriginY, self.bounds.size.width, [[self class] colorPreviewBoxHeight]); + runningOriginY = CGRectGetMaxY(self.colorPreviewBox.frame) + [[self class] inputViewVerticalPadding]; + + [self.hexLabel sizeToFit]; + const CGFloat kLabelVerticalOutsetAmount = 0.0; + const CGFloat kLabelHorizonalOutsetAmount = 2.0; + UIEdgeInsets labelOutset = UIEdgeInsetsMake(-kLabelVerticalOutsetAmount, -kLabelHorizonalOutsetAmount, -kLabelVerticalOutsetAmount, -kLabelHorizonalOutsetAmount); + self.hexLabel.frame = UIEdgeInsetsInsetRect(self.hexLabel.frame, labelOutset); + CGFloat hexLabelOriginX = self.colorPreviewBox.layer.borderWidth; + CGFloat hexLabelOriginY = CGRectGetMaxY(self.colorPreviewBox.frame) - self.colorPreviewBox.layer.borderWidth - self.hexLabel.frame.size.height; + self.hexLabel.frame = CGRectMake(hexLabelOriginX, hexLabelOriginY, self.hexLabel.frame.size.width, self.hexLabel.frame.size.height); + + NSArray *colorComponentInputViews = @[self.alphaInput, self.redInput, self.greenInput, self.blueInput]; + for (FLEXColorComponentInputView *inputView in colorComponentInputViews) { + CGSize fitSize = [inputView sizeThatFits:constrainSize]; + inputView.frame = CGRectMake(0, runningOriginY, fitSize.width, fitSize.height); + runningOriginY = CGRectGetMaxY(inputView.frame) + [[self class] inputViewVerticalPadding]; + } +} + +- (void)setInputValue:(id)inputValue +{ + if ([inputValue isKindOfClass:[UIColor class]]) { + [self updateWithColor:inputValue]; + } else if ([inputValue isKindOfClass:[NSValue class]]) { + const char *type = [inputValue objCType]; + if (strcmp(type, @encode(CGColorRef)) == 0) { + CGColorRef colorRef; + [inputValue getValue:&colorRef]; + UIColor *color = [[UIColor alloc] initWithCGColor:colorRef]; + [self updateWithColor:color]; + } + } +} + +- (id)inputValue +{ + return [UIColor colorWithRed:self.redInput.slider.value green:self.greenInput.slider.value blue:self.blueInput.slider.value alpha:self.alphaInput.slider.value]; +} + +- (void)colorComponentInputViewValueDidChange:(FLEXColorComponentInputView *)colorComponentInputView +{ + [self updateColorPreview]; +} + +- (void)updateWithColor:(UIColor *)color +{ + CGFloat red, green, blue, white, alpha; + if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) { + self.alphaInput.slider.value = alpha; + [self.alphaInput updateValueLabel]; + self.redInput.slider.value = red; + [self.redInput updateValueLabel]; + self.greenInput.slider.value = green; + [self.greenInput updateValueLabel]; + self.blueInput.slider.value = blue; + [self.blueInput updateValueLabel]; + } else if ([color getWhite:&white alpha:&alpha]) { + self.alphaInput.slider.value = alpha; + [self.alphaInput updateValueLabel]; + self.redInput.slider.value = white; + [self.redInput updateValueLabel]; + self.greenInput.slider.value = white; + [self.greenInput updateValueLabel]; + self.blueInput.slider.value = white; + [self.blueInput updateValueLabel]; + } + [self updateColorPreview]; +} + +- (void)updateColorPreview +{ + self.colorPreviewBox.color = self.inputValue; + unsigned char redByte = self.redInput.slider.value * 255; + unsigned char greenByte = self.greenInput.slider.value * 255; + unsigned char blueByte = self.blueInput.slider.value * 255; + self.hexLabel.text = [NSString stringWithFormat:@"#%02X%02X%02X", redByte, greenByte, blueByte]; + [self setNeedsLayout]; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat height = 0; + height += [[self class] colorPreviewBoxHeight]; + height += [[self class] inputViewVerticalPadding]; + height += [self.alphaInput sizeThatFits:size].height; + height += [[self class] inputViewVerticalPadding]; + height += [self.redInput sizeThatFits:size].height; + height += [[self class] inputViewVerticalPadding]; + height += [self.greenInput sizeThatFits:size].height; + height += [[self class] inputViewVerticalPadding]; + height += [self.blueInput sizeThatFits:size].height; + return CGSizeMake(size.width, height); +} + ++ (CGFloat)inputViewVerticalPadding +{ + return 10.0; +} + ++ (CGFloat)colorPreviewBoxHeight +{ + return 40.0; +} + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + return (type && (strcmp(type, @encode(CGColorRef)) == 0 || strcmp(type, FLEXEncodeClass(UIColor)) == 0)) || [value isKindOfClass:[UIColor class]]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h new file mode 100755 index 0000000..54e63a9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputDataView.h +// Flipboard +// +// Created by Daniel Rodriguez Troitino on 2/14/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputDateView : FLEXArgumentInputView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m new file mode 100755 index 0000000..0907d21 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m @@ -0,0 +1,63 @@ +// +// FLEXArgumentInputDataView.m +// Flipboard +// +// Created by Daniel Rodriguez Troitino on 2/14/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputDateView.h" +#import "FLEXRuntimeUtility.h" + +@interface FLEXArgumentInputDateView () + +@property (nonatomic, strong) UIDatePicker *datePicker; + +@end + +@implementation FLEXArgumentInputDateView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.datePicker = [[UIDatePicker alloc] init]; + self.datePicker.datePickerMode = UIDatePickerModeDateAndTime; + // Using UTC, because that's what the NSDate description prints + self.datePicker.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; + self.datePicker.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + [self addSubview:self.datePicker]; + } + return self; +} + +- (void)setInputValue:(id)inputValue +{ + if ([inputValue isKindOfClass:[NSDate class]]) { + self.datePicker.date = inputValue; + } +} + +- (id)inputValue +{ + return self.datePicker.date; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + self.datePicker.frame = self.bounds; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat height = [self.datePicker sizeThatFits:size].height; + return CGSizeMake(size.width, height); +} + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + return (type && (strcmp(type, FLEXEncodeClass(NSDate)) == 0)) || [value isKindOfClass:[NSDate class]]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h new file mode 100755 index 0000000..11847e6 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputFontView.h +// Flipboard +// +// Created by Ryan Olson on 6/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputFontView : FLEXArgumentInputView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m new file mode 100755 index 0000000..803b76f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m @@ -0,0 +1,121 @@ +// +// FLEXArgumentInputFontView.m +// Flipboard +// +// Created by Ryan Olson on 6/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputFontView.h" +#import "FLEXArgumentInputViewFactory.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXArgumentInputFontsPickerView.h" + +@interface FLEXArgumentInputFontView () + +@property (nonatomic, strong) FLEXArgumentInputView *fontNameInput; +@property (nonatomic, strong) FLEXArgumentInputView *pointSizeInput; + +@end + +@implementation FLEXArgumentInputFontView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.fontNameInput = [[FLEXArgumentInputFontsPickerView alloc] initWithArgumentTypeEncoding:FLEXEncodeClass(NSString)]; + self.fontNameInput.backgroundColor = self.backgroundColor; + self.fontNameInput.targetSize = FLEXArgumentInputViewSizeSmall; + self.fontNameInput.title = @"Font Name:"; + [self addSubview:self.fontNameInput]; + + self.pointSizeInput = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:@encode(CGFloat)]; + self.pointSizeInput.backgroundColor = self.backgroundColor; + self.pointSizeInput.targetSize = FLEXArgumentInputViewSizeSmall; + self.pointSizeInput.title = @"Point Size:"; + [self addSubview:self.pointSizeInput]; + } + return self; +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + self.fontNameInput.backgroundColor = backgroundColor; + self.pointSizeInput.backgroundColor = backgroundColor; +} + +- (void)setInputValue:(id)inputValue +{ + if ([inputValue isKindOfClass:[UIFont class]]) { + UIFont *font = (UIFont *)inputValue; + self.fontNameInput.inputValue = font.fontName; + self.pointSizeInput.inputValue = @(font.pointSize); + } +} + +- (id)inputValue +{ + CGFloat pointSize = 0; + if ([self.pointSizeInput.inputValue isKindOfClass:[NSValue class]]) { + NSValue *pointSizeValue = (NSValue *)self.pointSizeInput.inputValue; + if (strcmp([pointSizeValue objCType], @encode(CGFloat)) == 0) { + [pointSizeValue getValue:&pointSize]; + } + } + return [UIFont fontWithName:self.fontNameInput.inputValue size:pointSize]; +} + +- (BOOL)inputViewIsFirstResponder +{ + return [self.fontNameInput inputViewIsFirstResponder] || [self.pointSizeInput inputViewIsFirstResponder]; +} + + +#pragma mark - Layout and Sizing + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat runningOriginY = self.topInputFieldVerticalLayoutGuide; + + CGSize fontNameFitSize = [self.fontNameInput sizeThatFits:self.bounds.size]; + self.fontNameInput.frame = CGRectMake(0, runningOriginY, fontNameFitSize.width, fontNameFitSize.height); + runningOriginY = CGRectGetMaxY(self.fontNameInput.frame) + [[self class] verticalPaddingBetweenFields]; + + CGSize pointSizeFitSize = [self.pointSizeInput sizeThatFits:self.bounds.size]; + self.pointSizeInput.frame = CGRectMake(0, runningOriginY, pointSizeFitSize.width, pointSizeFitSize.height); +} + ++ (CGFloat)verticalPaddingBetweenFields +{ + return 10.0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGSize fitSize = [super sizeThatFits:size]; + + CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); + + CGFloat height = fitSize.height; + height += [self.fontNameInput sizeThatFits:constrainSize].height; + height += [[self class] verticalPaddingBetweenFields]; + height += [self.pointSizeInput sizeThatFits:constrainSize].height; + + return CGSizeMake(fitSize.width, height); +} + + +#pragma mark - + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + BOOL supported = type && strcmp(type, FLEXEncodeClass(UIFont)) == 0; + supported = supported || (value && [value isKindOfClass:[UIFont class]]); + return supported; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h new file mode 100755 index 0000000..6912e6e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h @@ -0,0 +1,12 @@ +// +// FLEXArgumentInputFontsPickerView.h +// UICatalog +// +// Created by 啟倫 陳 on 2014/7/27. +// Copyright (c) 2014年 f. All rights reserved. +// + +#import "FLEXArgumentInputTextView.h" + +@interface FLEXArgumentInputFontsPickerView : FLEXArgumentInputTextView +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m new file mode 100755 index 0000000..421a078 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m @@ -0,0 +1,105 @@ +// +// FLEXArgumentInputFontsPickerView.m +// UICatalog +// +// Created by 啟倫 陳 on 2014/7/27. +// Copyright (c) 2014年 f. All rights reserved. +// + +#import "FLEXArgumentInputFontsPickerView.h" +#import "FLEXRuntimeUtility.h" + +@interface FLEXArgumentInputFontsPickerView () + +@property (nonatomic, strong) NSMutableArray *availableFonts; + +@end + + +@implementation FLEXArgumentInputFontsPickerView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.targetSize = FLEXArgumentInputViewSizeSmall; + [self createAvailableFonts]; + self.inputTextView.inputView = [self createFontsPicker]; + } + return self; +} + +- (void)setInputValue:(id)inputValue +{ + self.inputTextView.text = inputValue; + if ([self.availableFonts indexOfObject:inputValue] == NSNotFound) { + [self.availableFonts insertObject:inputValue atIndex:0]; + } + [(UIPickerView*)self.inputTextView.inputView selectRow:[self.availableFonts indexOfObject:inputValue] inComponent:0 animated:NO]; +} + +- (id)inputValue +{ + return [self.inputTextView.text length] > 0 ? [self.inputTextView.text copy] : nil; +} + +#pragma mark - private + +- (UIPickerView*)createFontsPicker +{ + UIPickerView *fontsPicker = [UIPickerView new]; + fontsPicker.dataSource = self; + fontsPicker.delegate = self; + fontsPicker.showsSelectionIndicator = YES; + return fontsPicker; +} + +- (void)createAvailableFonts +{ + NSMutableArray *unsortedFontsArray = [NSMutableArray array]; + for (NSString *eachFontFamily in [UIFont familyNames]) { + for (NSString *eachFontName in [UIFont fontNamesForFamilyName:eachFontFamily]) { + [unsortedFontsArray addObject:eachFontName]; + } + } + self.availableFonts = [NSMutableArray arrayWithArray:[unsortedFontsArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]]; +} + +#pragma mark - UIPickerViewDataSource + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return [self.availableFonts count]; +} + +#pragma mark - UIPickerViewDelegate + +- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view +{ + UILabel *fontLabel; + if (!view) { + fontLabel = [UILabel new]; + fontLabel.backgroundColor = [UIColor clearColor]; + fontLabel.textAlignment = NSTextAlignmentCenter; + } else { + fontLabel = (UILabel*)view; + } + UIFont *font = [UIFont fontWithName:self.availableFonts[row] size:15.0]; + NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + NSAttributedString *attributesString = [[NSAttributedString alloc] initWithString:self.availableFonts[row] attributes:attributesDictionary]; + fontLabel.attributedText = attributesString; + [fontLabel sizeToFit]; + return fontLabel; +} + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + self.inputTextView.text = self.availableFonts[row]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.h new file mode 100755 index 0000000..5776d3a --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputJSONObjectView.h +// Flipboard +// +// Created by Ryan Olson on 6/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputTextView.h" + +@interface FLEXArgumentInputJSONObjectView : FLEXArgumentInputTextView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.m new file mode 100755 index 0000000..32c11a6 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputJSONObjectView.m @@ -0,0 +1,65 @@ +// +// FLEXArgumentInputJSONObjectView.m +// Flipboard +// +// Created by Ryan Olson on 6/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputJSONObjectView.h" +#import "FLEXRuntimeUtility.h" + +@implementation FLEXArgumentInputJSONObjectView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + // Start with the numbers and punctuation keyboard since quotes, curly braces, or + // square brackets are likely to be the first characters type for the JSON. + self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation; + self.targetSize = FLEXArgumentInputViewSizeLarge; + } + return self; +} + +- (void)setInputValue:(id)inputValue +{ + self.inputTextView.text = [FLEXRuntimeUtility editableJSONStringForObject:inputValue]; +} + +- (id)inputValue +{ + return [FLEXRuntimeUtility objectValueFromEditableJSONString:self.inputTextView.text]; +} + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + // Must be object type. + BOOL supported = type && type[0] == '@'; + + if (supported) { + if (value) { + // If there's a current value, it must be serializable to JSON + supported = [FLEXRuntimeUtility editableJSONStringForObject:value] != nil; + } else { + // Otherwise, see if we have more type information than just 'id'. + // If we do, make sure the encoding is something serializable to JSON. + // Properties and ivars keep more detailed type encoding information than method arguments. + if (strcmp(type, @encode(id)) != 0) { + BOOL isJSONSerializableType = NO; + // Note: we can't use @encode(NSString) here because that drops the string information and just goes to @encode(id). + isJSONSerializableType = isJSONSerializableType || strcmp(type, FLEXEncodeClass(NSString)) == 0; + isJSONSerializableType = isJSONSerializableType || strcmp(type, FLEXEncodeClass(NSNumber)) == 0; + isJSONSerializableType = isJSONSerializableType || strcmp(type, FLEXEncodeClass(NSArray)) == 0; + isJSONSerializableType = isJSONSerializableType || strcmp(type, FLEXEncodeClass(NSDictionary)) == 0; + + supported = isJSONSerializableType; + } + } + } + + return supported; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h new file mode 100755 index 0000000..77923ef --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputNotSupportedView.h +// Flipboard +// +// Created by Ryan Olson on 6/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputTextView.h" + +@interface FLEXArgumentInputNotSupportedView : FLEXArgumentInputTextView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m new file mode 100755 index 0000000..b494575 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m @@ -0,0 +1,25 @@ +// +// FLEXArgumentInputNotSupportedView.m +// Flipboard +// +// Created by Ryan Olson on 6/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputNotSupportedView.h" + +@implementation FLEXArgumentInputNotSupportedView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.inputTextView.userInteractionEnabled = NO; + self.inputTextView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:1.0]; + self.inputTextView.text = @"nil"; + self.targetSize = FLEXArgumentInputViewSizeSmall; + } + return self; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h new file mode 100755 index 0000000..754ea61 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputNumberView.h +// Flipboard +// +// Created by Ryan Olson on 6/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputTextView.h" + +@interface FLEXArgumentInputNumberView : FLEXArgumentInputTextView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m new file mode 100755 index 0000000..9b9d7bc --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m @@ -0,0 +1,57 @@ +// +// FLEXArgumentInputNumberView.m +// Flipboard +// +// Created by Ryan Olson on 6/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputNumberView.h" +#import "FLEXRuntimeUtility.h" + +@implementation FLEXArgumentInputNumberView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation; + self.targetSize = FLEXArgumentInputViewSizeSmall; + } + return self; +} + +- (void)setInputValue:(id)inputValue +{ + if ([inputValue respondsToSelector:@selector(stringValue)]) { + self.inputTextView.text = [inputValue stringValue]; + } +} + +- (id)inputValue +{ + return [FLEXRuntimeUtility valueForNumberWithObjCType:[self.typeEncoding UTF8String] fromInputString:self.inputTextView.text]; +} + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + static NSArray *primitiveTypes = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + primitiveTypes = @[@(@encode(char)), + @(@encode(int)), + @(@encode(short)), + @(@encode(long)), + @(@encode(long long)), + @(@encode(unsigned char)), + @(@encode(unsigned int)), + @(@encode(unsigned short)), + @(@encode(unsigned long)), + @(@encode(unsigned long long)), + @(@encode(float)), + @(@encode(double))]; + }); + return type && [primitiveTypes containsObject:@(type)]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h new file mode 100755 index 0000000..2c16b6c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputStringView.h +// Flipboard +// +// Created by Ryan Olson on 6/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputTextView.h" + +@interface FLEXArgumentInputStringView : FLEXArgumentInputTextView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m new file mode 100755 index 0000000..291fe09 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m @@ -0,0 +1,45 @@ +// +// FLEXArgumentInputStringView.m +// Flipboard +// +// Created by Ryan Olson on 6/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputStringView.h" +#import "FLEXRuntimeUtility.h" + +@implementation FLEXArgumentInputStringView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.targetSize = FLEXArgumentInputViewSizeLarge; + } + return self; +} + +- (void)setInputValue:(id)inputValue +{ + self.inputTextView.text = inputValue; +} + +- (id)inputValue +{ + // Interpret empty string as nil. We loose the ablitiy to set empty string as a string value, + // but we accept that tradeoff in exchange for not having to type quotes for every string. + return [self.inputTextView.text length] > 0 ? [self.inputTextView.text copy] : nil; +} + + +#pragma mark - + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + BOOL supported = type && strcmp(type, FLEXEncodeClass(NSString)) == 0; + supported = supported || (value && [value isKindOfClass:[NSString class]]); + return supported; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h new file mode 100755 index 0000000..3e3b6f9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputStructView.h +// Flipboard +// +// Created by Ryan Olson on 6/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputStructView : FLEXArgumentInputView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m new file mode 100755 index 0000000..a66ccd8 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m @@ -0,0 +1,210 @@ +// +// FLEXArgumentInputStructView.m +// Flipboard +// +// Created by Ryan Olson on 6/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputStructView.h" +#import "FLEXArgumentInputViewFactory.h" +#import "FLEXRuntimeUtility.h" + +@interface FLEXArgumentInputStructView () + +@property (nonatomic, strong) NSArray *argumentInputViews; + +@end + +@implementation FLEXArgumentInputStructView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + NSMutableArray *inputViews = [NSMutableArray array]; + NSArray *customTitles = [[self class] customFieldTitlesForTypeEncoding:typeEncoding]; + [FLEXRuntimeUtility enumerateTypesInStructEncoding:typeEncoding usingBlock:^(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset) { + + FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:fieldTypeEncoding]; + inputView.backgroundColor = self.backgroundColor; + inputView.targetSize = FLEXArgumentInputViewSizeSmall; + + if (fieldIndex < [customTitles count]) { + inputView.title = customTitles[fieldIndex]; + } else { + inputView.title = [NSString stringWithFormat:@"%@ field %lu (%@)", structName, (unsigned long)fieldIndex, prettyTypeEncoding]; + } + + [inputViews addObject:inputView]; + [self addSubview:inputView]; + }]; + self.argumentInputViews = inputViews; + } + return self; +} + + +#pragma mark - Superclass Overrides + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + for (FLEXArgumentInputView *inputView in self.argumentInputViews) { + inputView.backgroundColor = backgroundColor; + } +} + +- (void)setInputValue:(id)inputValue +{ + if ([inputValue isKindOfClass:[NSValue class]]) { + const char *structTypeEncoding = [inputValue objCType]; + if (strcmp([self.typeEncoding UTF8String], structTypeEncoding) == 0) { + NSUInteger valueSize = 0; + @try { + // NSGetSizeAndAlignment barfs on type encoding for bitfields. + NSGetSizeAndAlignment(structTypeEncoding, &valueSize, NULL); + } @catch (NSException *exception) { } + + if (valueSize > 0) { + void *unboxedValue = malloc(valueSize); + [inputValue getValue:unboxedValue]; + [FLEXRuntimeUtility enumerateTypesInStructEncoding:structTypeEncoding usingBlock:^(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset) { + + void *fieldPointer = unboxedValue + fieldOffset; + FLEXArgumentInputView *inputView = self.argumentInputViews[fieldIndex]; + + if (fieldTypeEncoding[0] == @encode(id)[0] || fieldTypeEncoding[0] == @encode(Class)[0]) { + inputView.inputValue = (__bridge id)fieldPointer; + } else { + NSValue *boxedField = [FLEXRuntimeUtility valueForPrimitivePointer:fieldPointer objCType:fieldTypeEncoding]; + inputView.inputValue = boxedField; + } + }]; + free(unboxedValue); + } + } + } +} + +- (id)inputValue +{ + NSValue *boxedStruct = nil; + const char *structTypeEncoding = [self.typeEncoding UTF8String]; + NSUInteger structSize = 0; + @try { + // NSGetSizeAndAlignment barfs on type encoding for bitfields. + NSGetSizeAndAlignment(structTypeEncoding, &structSize, NULL); + } @catch (NSException *exception) { } + + if (structSize > 0) { + void *unboxedStruct = malloc(structSize); + [FLEXRuntimeUtility enumerateTypesInStructEncoding:structTypeEncoding usingBlock:^(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset) { + + void *fieldPointer = unboxedStruct + fieldOffset; + FLEXArgumentInputView *inputView = self.argumentInputViews[fieldIndex]; + + if (fieldTypeEncoding[0] == @encode(id)[0] || fieldTypeEncoding[0] == @encode(Class)[0]) { + // Object fields + memcpy(fieldPointer, (__bridge void *)inputView.inputValue, sizeof(id)); + } else { + // Boxed primitive/struct fields + id inputValue = inputView.inputValue; + if ([inputValue isKindOfClass:[NSValue class]] && strcmp([inputValue objCType], fieldTypeEncoding) == 0) { + [inputValue getValue:fieldPointer]; + } + } + }]; + + boxedStruct = [NSValue value:unboxedStruct withObjCType:structTypeEncoding]; + free(unboxedStruct); + } + + return boxedStruct; +} + +- (BOOL)inputViewIsFirstResponder +{ + BOOL isFirstResponder = NO; + for (FLEXArgumentInputView *inputView in self.argumentInputViews) { + if ([inputView inputViewIsFirstResponder]) { + isFirstResponder = YES; + break; + } + } + return isFirstResponder; +} + + +#pragma mark - Layout and Sizing + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat runningOriginY = self.topInputFieldVerticalLayoutGuide; + + for (FLEXArgumentInputView *inputView in self.argumentInputViews) { + CGSize inputFitSize = [inputView sizeThatFits:self.bounds.size]; + inputView.frame = CGRectMake(0, runningOriginY, inputFitSize.width, inputFitSize.height); + runningOriginY = CGRectGetMaxY(inputView.frame) + [[self class] verticalPaddingBetweenFields]; + } +} + ++ (CGFloat)verticalPaddingBetweenFields +{ + return 10.0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGSize fitSize = [super sizeThatFits:size]; + + CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); + CGFloat height = fitSize.height; + + for (FLEXArgumentInputView *inputView in self.argumentInputViews) { + height += [inputView sizeThatFits:constrainSize].height; + height += [[self class] verticalPaddingBetweenFields]; + } + + return CGSizeMake(fitSize.width, height); +} + + +#pragma mark - Class Helpers + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + return type && type[0] == '{'; +} + ++ (NSArray *)customFieldTitlesForTypeEncoding:(const char *)typeEncoding +{ + NSArray *customTitles = nil; + if (strcmp(typeEncoding, @encode(CGRect)) == 0) { + customTitles = @[@"CGPoint origin", @"CGSize size"]; + } else if (strcmp(typeEncoding, @encode(CGPoint)) == 0) { + customTitles = @[@"CGFloat x", @"CGFloat y"]; + } else if (strcmp(typeEncoding, @encode(CGSize)) == 0) { + customTitles = @[@"CGFloat width", @"CGFloat height"]; + } else if (strcmp(typeEncoding, @encode(UIEdgeInsets)) == 0) { + customTitles = @[@"CGFloat top", @"CGFloat left", @"CGFloat bottom", @"CGFloat right"]; + } else if (strcmp(typeEncoding, @encode(UIOffset)) == 0) { + customTitles = @[@"CGFloat horizontal", @"CGFloat vertical"]; + } else if (strcmp(typeEncoding, @encode(NSRange)) == 0) { + customTitles = @[@"NSUInteger location", @"NSUInteger length"]; + } else if (strcmp(typeEncoding, @encode(CATransform3D)) == 0) { + customTitles = @[@"CGFloat m11", @"CGFloat m12", @"CGFloat m13", @"CGFloat m14", + @"CGFloat m21", @"CGFloat m22", @"CGFloat m23", @"CGFloat m24", + @"CGFloat m31", @"CGFloat m32", @"CGFloat m33", @"CGFloat m34", + @"CGFloat m41", @"CGFloat m42", @"CGFloat m43", @"CGFloat m44"]; + } else if (strcmp(typeEncoding, @encode(CGAffineTransform)) == 0) { + customTitles = @[@"CGFloat a", @"CGFloat b", + @"CGFloat c", @"CGFloat d", + @"CGFloat tx", @"CGFloat ty"]; + } + return customTitles; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h new file mode 100755 index 0000000..973639d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h @@ -0,0 +1,13 @@ +// +// FLEXArgumentInputSwitchView.h +// Flipboard +// +// Created by Ryan Olson on 6/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputSwitchView : FLEXArgumentInputView + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m new file mode 100755 index 0000000..b5ee840 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m @@ -0,0 +1,87 @@ +// +// FLEXArgumentInputSwitchView.m +// Flipboard +// +// Created by Ryan Olson on 6/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputSwitchView.h" + +@interface FLEXArgumentInputSwitchView () + +@property (nonatomic, strong) UISwitch *inputSwitch; + +@end + +@implementation FLEXArgumentInputSwitchView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.inputSwitch = [[UISwitch alloc] init]; + [self.inputSwitch addTarget:self action:@selector(switchValueDidChange:) forControlEvents:UIControlEventValueChanged]; + [self.inputSwitch sizeToFit]; + [self addSubview:self.inputSwitch]; + } + return self; +} + + +#pragma mark Input/Output + +- (void)setInputValue:(id)inputValue +{ + BOOL on = NO; + if ([inputValue isKindOfClass:[NSNumber class]]) { + NSNumber *number = (NSNumber *)inputValue; + on = [number boolValue]; + } else if ([inputValue isKindOfClass:[NSValue class]]) { + NSValue *value = (NSValue *)inputValue; + if (strcmp([value objCType], @encode(BOOL)) == 0) { + [value getValue:&on]; + } + } + self.inputSwitch.on = on; +} + +- (id)inputValue +{ + BOOL isOn = [self.inputSwitch isOn]; + NSValue *boxedBool = [NSValue value:&isOn withObjCType:@encode(BOOL)]; + return boxedBool; +} + +- (void)switchValueDidChange:(id)sender +{ + [self.delegate argumentInputViewValueDidChange:self]; +} + + +#pragma mark - Layout and Sizing + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.inputSwitch.frame = CGRectMake(0, self.topInputFieldVerticalLayoutGuide, self.inputSwitch.frame.size.width, self.inputSwitch.frame.size.height); +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGSize fitSize = [super sizeThatFits:size]; + fitSize.height += self.inputSwitch.frame.size.height; + return fitSize; +} + + +#pragma mark - Class Helpers + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + // Only BOOLs. Current value is irrelevant. + return type && strcmp(type, @encode(BOOL)) == 0; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h new file mode 100755 index 0000000..b76f1d4 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h @@ -0,0 +1,17 @@ +// +// FLEXArgumentInputTextView.h +// FLEXInjected +// +// Created by Ryan Olson on 6/15/14. +// +// + +#import "FLEXArgumentInputView.h" + +@interface FLEXArgumentInputTextView : FLEXArgumentInputView + +// For subclass eyes only + +@property (nonatomic, strong, readonly) UITextView *inputTextView; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m new file mode 100755 index 0000000..220f41c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m @@ -0,0 +1,121 @@ +// +// FLEXArgumentInputTextView.m +// FLEXInjected +// +// Created by Ryan Olson on 6/15/14. +// +// + +#import "FLEXArgumentInputTextView.h" +#import "FLEXUtility.h" + +@interface FLEXArgumentInputTextView () + +@property (nonatomic, strong) UITextView *inputTextView; +@property (nonatomic, readonly) NSUInteger numberOfInputLines; + +@end + +@implementation FLEXArgumentInputTextView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithArgumentTypeEncoding:typeEncoding]; + if (self) { + self.inputTextView = [[UITextView alloc] init]; + self.inputTextView.font = [[self class] inputFont]; + self.inputTextView.backgroundColor = [UIColor whiteColor]; + self.inputTextView.layer.borderColor = [[UIColor blackColor] CGColor]; + self.inputTextView.layer.borderWidth = 1.0; + self.inputTextView.autocapitalizationType = UITextAutocapitalizationTypeNone; + self.inputTextView.autocorrectionType = UITextAutocorrectionTypeNo; + self.inputTextView.delegate = self; + self.inputTextView.inputAccessoryView = [self createToolBar]; + [self addSubview:self.inputTextView]; + } + return self; +} + +#pragma mark - private + +- (UIToolbar*)createToolBar +{ + UIToolbar *toolBar = [UIToolbar new]; + [toolBar sizeToFit]; + UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(textViewDone)]; + toolBar.items = @[spaceItem, doneItem]; + return toolBar; +} + +- (void)textViewDone +{ + [self.inputTextView resignFirstResponder]; +} + + +#pragma mark - Text View Changes + +- (void)textViewDidChange:(UITextView *)textView +{ + [self.delegate argumentInputViewValueDidChange:self]; +} + + +#pragma mark - Superclass Overrides + +- (BOOL)inputViewIsFirstResponder +{ + return self.inputTextView.isFirstResponder; +} + + +#pragma mark - Layout and Sizing + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.inputTextView.frame = CGRectMake(0, self.topInputFieldVerticalLayoutGuide, self.bounds.size.width, [self inputTextViewHeight]); +} + +- (NSUInteger)numberOfInputLines +{ + NSUInteger numberOfInputLines = 0; + switch (self.targetSize) { + case FLEXArgumentInputViewSizeDefault: + numberOfInputLines = 2; + break; + + case FLEXArgumentInputViewSizeSmall: + numberOfInputLines = 1; + break; + + case FLEXArgumentInputViewSizeLarge: + numberOfInputLines = 8; + break; + } + return numberOfInputLines; +} + +- (CGFloat)inputTextViewHeight +{ + return ceil([[self class] inputFont].lineHeight * self.numberOfInputLines) + 16.0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGSize fitSize = [super sizeThatFits:size]; + fitSize.height += [self inputTextViewHeight]; + return fitSize; +} + + +#pragma mark - Class Helpers + ++ (UIFont *)inputFont +{ + return [FLEXUtility defaultFontOfSize:14.0]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.h new file mode 100755 index 0000000..3c14c35 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.h @@ -0,0 +1,60 @@ +// +// FLEXArgumentInputView.h +// Flipboard +// +// Created by Ryan Olson on 5/30/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +typedef NS_ENUM(NSUInteger, FLEXArgumentInputViewSize) { + FLEXArgumentInputViewSizeDefault = 0, + FLEXArgumentInputViewSizeSmall, + FLEXArgumentInputViewSizeLarge +}; + +@protocol FLEXArgumentInputViewDelegate; + +@interface FLEXArgumentInputView : UIView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding; + +/// The name of the field. Optional (can be nil). +@property (nonatomic, copy) NSString *title; + +/// To populate the filed with an initial value, set this property. +/// To reteive the value input by the user, access the property. +/// Primitive types and structs should/will be boxed in NSValue containers. +/// Concrete subclasses *must* override both the setter and getter for this property. +@property (nonatomic) id inputValue; + +/// Setting this value to large will make some argument input views increase the size of their input field(s). +/// Useful to increase the use of space if there is only one input view on screen (i.e. for property and ivar editing). +@property (nonatomic, assign) FLEXArgumentInputViewSize targetSize; + +/// Users of the input view can get delegate callbacks for incremental changes in user input. +@property (nonatomic, weak) id delegate; + +// Subclasses can override + +/// If the input view has one or more text views, returns YES when one of them is focused. +@property (nonatomic, readonly) BOOL inputViewIsFirstResponder; + +/// For subclasses to indicate that they can handle editing a field the give type and value. +/// Used by FLEXArgumentInputViewFactory to create appropriate input views. ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value; + +// For subclass eyes only + +@property (nonatomic, strong, readonly) UILabel *titleLabel; +@property (nonatomic, strong, readonly) NSString *typeEncoding; +@property (nonatomic, readonly) CGFloat topInputFieldVerticalLayoutGuide; + +@end + +@protocol FLEXArgumentInputViewDelegate + +- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.m new file mode 100755 index 0000000..2379e09 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputView.m @@ -0,0 +1,137 @@ +// +// FLEXArgumentInputView.m +// Flipboard +// +// Created by Ryan Olson on 5/30/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArgumentInputView.h" +#import "FLEXUtility.h" + +@interface FLEXArgumentInputView () + +@property (nonatomic, strong) UILabel *titleLabel; +@property (nonatomic, strong) NSString *typeEncoding; + +@end + +@implementation FLEXArgumentInputView + +- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding +{ + self = [super initWithFrame:CGRectZero]; + if (self) { + self.typeEncoding = @(typeEncoding); + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + if (self.showsTitle) { + CGSize constrainSize = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX); + CGSize labelSize = [self.titleLabel sizeThatFits:constrainSize]; + self.titleLabel.frame = CGRectMake(0, 0, labelSize.width, labelSize.height); + } +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + self.titleLabel.backgroundColor = backgroundColor; +} + +- (void)setTitle:(NSString *)title +{ + if (![_title isEqual:title]) { + _title = title; + self.titleLabel.text = title; + [self setNeedsLayout]; + } +} + +- (UILabel *)titleLabel +{ + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [[self class] titleFont]; + _titleLabel.backgroundColor = self.backgroundColor; + _titleLabel.textColor = [UIColor colorWithWhite:0.3 alpha:1.0]; + _titleLabel.numberOfLines = 0; + [self addSubview:_titleLabel]; + } + return _titleLabel; +} + +- (BOOL)showsTitle +{ + return [self.title length] > 0; +} + +- (CGFloat)topInputFieldVerticalLayoutGuide +{ + CGFloat verticalLayoutGuide = 0; + if (self.showsTitle) { + CGFloat titleHeight = [self.titleLabel sizeThatFits:self.bounds.size].height; + verticalLayoutGuide = titleHeight + [[self class] titleBottomPadding]; + } + return verticalLayoutGuide; +} + + +#pragma mark - Subclasses Can Override + +- (BOOL)inputViewIsFirstResponder +{ + return NO; +} + +- (void)setInputValue:(id)inputValue +{ + // Subclasses should override. +} + +- (id)inputValue +{ + // Subclasses should override. + return nil; +} + ++ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value +{ + return NO; +} + + +#pragma mark - Class Helpers + ++ (UIFont *)titleFont +{ + return [FLEXUtility defaultFontOfSize:12.0]; +} + ++ (CGFloat)titleBottomPadding +{ + return 4.0; +} + + +#pragma mark - Sizing + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat height = 0; + + if ([self.title length] > 0) { + CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); + height += ceil([self.titleLabel sizeThatFits:constrainSize].height); + height += [[self class] titleBottomPadding]; + } + + return CGSizeMake(size.width, height); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.h new file mode 100755 index 0000000..0680903 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.h @@ -0,0 +1,25 @@ +// +// FLEXArgumentInputViewFactory.h +// FLEXInjected +// +// Created by Ryan Olson on 6/15/14. +// +// + +#import + +@class FLEXArgumentInputView; + +@interface FLEXArgumentInputViewFactory : NSObject + +/// Forwards to argumentInputViewForTypeEncoding:currentValue: with a nil currentValue. ++ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding; + +/// The main factory method for making argument input view subclasses that are the best fit for the type. ++ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue; + +/// A way to check if we should try editing a filed given its type encoding and value. +/// Useful when deciding whether to edit or explore a property, ivar, or NSUserDefaults value. ++ (BOOL)canEditFieldWithTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.m new file mode 100755 index 0000000..cbb6bae --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/ArgumentInputViews/FLEXArgumentInputViewFactory.m @@ -0,0 +1,72 @@ +// +// FLEXArgumentInputViewFactory.m +// FLEXInjected +// +// Created by Ryan Olson on 6/15/14. +// +// + +#import "FLEXArgumentInputViewFactory.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputJSONObjectView.h" +#import "FLEXArgumentInputNumberView.h" +#import "FLEXArgumentInputSwitchView.h" +#import "FLEXArgumentInputStructView.h" +#import "FLEXArgumentInputNotSupportedView.h" +#import "FLEXArgumentInputStringView.h" +#import "FLEXArgumentInputFontView.h" +#import "FLEXArgumentInputColorView.h" +#import "FLEXArgumentInputDateView.h" + +@implementation FLEXArgumentInputViewFactory + ++ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding +{ + return [self argumentInputViewForTypeEncoding:typeEncoding currentValue:nil]; +} + ++ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue +{ + Class subclass = [self argumentInputViewSubclassForTypeEncoding:typeEncoding currentValue:currentValue]; + if (!subclass) { + // Fall back to a FLEXArgumentInputNotSupportedView if we can't find a subclass that fits the type encoding. + // The unsupported view shows "nil" and does not allow user input. + subclass = [FLEXArgumentInputNotSupportedView class]; + } + return [[subclass alloc] initWithArgumentTypeEncoding:typeEncoding]; +} + ++ (Class)argumentInputViewSubclassForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue +{ + Class argumentInputViewSubclass = nil; + + // Note that order is important here since multiple subclasses may support the same type. + // An example is the number subclass and the bool subclass for the type @encode(BOOL). + // Both work, but we'd prefer to use the bool subclass. + if ([FLEXArgumentInputColorView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputColorView class]; + } else if ([FLEXArgumentInputFontView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputFontView class]; + } else if ([FLEXArgumentInputStringView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputStringView class]; + } else if ([FLEXArgumentInputStructView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputStructView class]; + } else if ([FLEXArgumentInputSwitchView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputSwitchView class]; + } else if ([FLEXArgumentInputDateView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputDateView class]; + } else if ([FLEXArgumentInputNumberView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputNumberView class]; + } else if ([FLEXArgumentInputJSONObjectView supportsObjCType:typeEncoding withCurrentValue:currentValue]) { + argumentInputViewSubclass = [FLEXArgumentInputJSONObjectView class]; + } + + return argumentInputViewSubclass; +} + ++ (BOOL)canEditFieldWithTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue +{ + return [self argumentInputViewSubclassForTypeEncoding:typeEncoding currentValue:currentValue] != nil; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.h new file mode 100755 index 0000000..2e9e6c9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.h @@ -0,0 +1,17 @@ +// +// FLEXDefaultEditorViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorViewController.h" + +@interface FLEXDefaultEditorViewController : FLEXFieldEditorViewController + +- (id)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key; + ++ (BOOL)canEditDefaultWithValue:(id)currentValue; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.m new file mode 100755 index 0000000..4d309db --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXDefaultEditorViewController.m @@ -0,0 +1,72 @@ +// +// FLEXDefaultEditorViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXDefaultEditorViewController.h" +#import "FLEXFieldEditorView.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputViewFactory.h" + +@interface FLEXDefaultEditorViewController () + +@property (nonatomic, readonly) NSUserDefaults *defaults; +@property (nonatomic, strong) NSString *key; + +@end + +@implementation FLEXDefaultEditorViewController + +- (id)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key +{ + self = [super initWithTarget:defaults]; + if (self) { + self.key = key; + self.title = @"Edit Default"; + } + return self; +} + +- (NSUserDefaults *)defaults +{ + return [self.target isKindOfClass:[NSUserDefaults class]] ? self.target : nil; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.fieldEditorView.fieldDescription = self.key; + + id currentValue = [self.defaults objectForKey:self.key]; + FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:@encode(id) currentValue:currentValue]; + inputView.backgroundColor = self.view.backgroundColor; + inputView.inputValue = currentValue; + self.fieldEditorView.argumentInputViews = @[inputView]; +} + +- (void)actionButtonPressed:(id)sender +{ + [super actionButtonPressed:sender]; + + id value = self.firstInputView.inputValue; + if (value) { + [self.defaults setObject:value forKey:self.key]; + } else { + [self.defaults removeObjectForKey:self.key]; + } + [self.defaults synchronize]; + + self.firstInputView.inputValue = [self.defaults objectForKey:self.key]; +} + ++ (BOOL)canEditDefaultWithValue:(id)currentValue +{ + return [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:@encode(id) currentValue:currentValue]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.h new file mode 100755 index 0000000..673abb6 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.h @@ -0,0 +1,18 @@ +// +// FLEXFieldEditorView.h +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXFieldEditorView : UIView + +@property (nonatomic, copy) NSString *targetDescription; +@property (nonatomic, copy) NSString *fieldDescription; + +@property (nonatomic, strong) NSArray *argumentInputViews; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.m new file mode 100755 index 0000000..b9ac93a --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorView.m @@ -0,0 +1,184 @@ +// +// FLEXFieldEditorView.m +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorView.h" +#import "FLEXArgumentInputView.h" +#import "FLEXUtility.h" + +@interface FLEXFieldEditorView () + +@property (nonatomic, strong) UILabel *targetDescriptionLabel; +@property (nonatomic, strong) UIView *targetDescriptionDivider; +@property (nonatomic, strong) UILabel *fieldDescriptionLabel; +@property (nonatomic, strong) UIView *fieldDescriptionDivider; + +@end + +@implementation FLEXFieldEditorView + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.targetDescriptionLabel = [[UILabel alloc] init]; + self.targetDescriptionLabel.numberOfLines = 0; + self.targetDescriptionLabel.font = [[self class] labelFont]; + [self addSubview:self.targetDescriptionLabel]; + + self.targetDescriptionDivider = [[self class] dividerView]; + [self addSubview:self.targetDescriptionDivider]; + + self.fieldDescriptionLabel = [[UILabel alloc] init]; + self.fieldDescriptionLabel.numberOfLines = 0; + self.fieldDescriptionLabel.font = [[self class] labelFont]; + [self addSubview:self.fieldDescriptionLabel]; + + self.fieldDescriptionDivider = [[self class] dividerView]; + [self addSubview:self.fieldDescriptionDivider]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat horizontalPadding = [[self class] horizontalPadding]; + CGFloat verticalPadding = [[self class] verticalPadding]; + CGFloat dividerLineHeight = [[self class] dividerLineHeight]; + + CGFloat originY = verticalPadding; + CGFloat originX = horizontalPadding; + CGFloat contentWidth = self.bounds.size.width - 2.0 * horizontalPadding; + CGSize constrainSize = CGSizeMake(contentWidth, CGFLOAT_MAX); + + CGSize instanceDescriptionSize = [self.targetDescriptionLabel sizeThatFits:constrainSize]; + self.targetDescriptionLabel.frame = CGRectMake(originX, originY, instanceDescriptionSize.width, instanceDescriptionSize.height); + originY = CGRectGetMaxY(self.targetDescriptionLabel.frame) + verticalPadding; + + self.targetDescriptionDivider.frame = CGRectMake(originX, originY, contentWidth, dividerLineHeight); + originY = CGRectGetMaxY(self.targetDescriptionDivider.frame) + verticalPadding; + + CGSize fieldDescriptionSize = [self.fieldDescriptionLabel sizeThatFits:constrainSize]; + self.fieldDescriptionLabel.frame = CGRectMake(originX, originY, fieldDescriptionSize.width, fieldDescriptionSize.height); + originY = CGRectGetMaxY(self.fieldDescriptionLabel.frame) + verticalPadding; + + self.fieldDescriptionDivider.frame = CGRectMake(originX, originY, contentWidth, dividerLineHeight); + originY = CGRectGetMaxY(self.fieldDescriptionDivider.frame) + verticalPadding; + + for (UIView *argumentInputView in self.argumentInputViews) { + CGSize inputViewSize = [argumentInputView sizeThatFits:constrainSize]; + argumentInputView.frame = CGRectMake(originX, originY, inputViewSize.width, inputViewSize.height); + originY = CGRectGetMaxY(argumentInputView.frame) + verticalPadding; + } +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + self.targetDescriptionLabel.backgroundColor = backgroundColor; + self.fieldDescriptionLabel.backgroundColor = backgroundColor; +} + +- (void)setTargetDescription:(NSString *)targetDescription +{ + if (![_targetDescription isEqual:targetDescription]) { + _targetDescription = targetDescription; + self.targetDescriptionLabel.text = targetDescription; + [self setNeedsLayout]; + } +} + +- (void)setFieldDescription:(NSString *)fieldDescription +{ + if (![_fieldDescription isEqual:fieldDescription]) { + _fieldDescription = fieldDescription; + self.fieldDescriptionLabel.text = fieldDescription; + [self setNeedsLayout]; + } +} + +- (void)setArgumentInputViews:(NSArray *)argumentInputViews +{ + if (![_argumentInputViews isEqual:argumentInputViews]) { + + for (FLEXArgumentInputView *inputView in _argumentInputViews) { + [inputView removeFromSuperview]; + } + + _argumentInputViews = argumentInputViews; + + for (FLEXArgumentInputView *newInputView in argumentInputViews) { + [self addSubview:newInputView]; + } + + [self setNeedsLayout]; + } +} + ++ (UIView *)dividerView +{ + UIView *dividerView = [[UIView alloc] init]; + dividerView.backgroundColor = [self dividerColor]; + return dividerView; +} + ++ (UIColor *)dividerColor +{ + return [UIColor lightGrayColor]; +} + ++ (CGFloat)horizontalPadding +{ + return 10.0; +} + ++ (CGFloat)verticalPadding +{ + return 20.0; +} + ++ (UIFont *)labelFont +{ + return [FLEXUtility defaultFontOfSize:14.0]; +} + ++ (CGFloat)dividerLineHeight +{ + return 1.0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat horizontalPadding = [[self class] horizontalPadding]; + CGFloat verticalPadding = [[self class] verticalPadding]; + CGFloat dividerLineHeight = [[self class] dividerLineHeight]; + + CGFloat height = 0; + CGFloat availableWidth = size.width - 2.0 * horizontalPadding; + CGSize constrainSize = CGSizeMake(availableWidth, CGFLOAT_MAX); + + height += verticalPadding; + height += ceil([self.targetDescriptionLabel sizeThatFits:constrainSize].height); + height += verticalPadding; + height += dividerLineHeight; + height += verticalPadding; + height += ceil([self.fieldDescriptionLabel sizeThatFits:constrainSize].height); + height += verticalPadding; + height += dividerLineHeight; + height += verticalPadding; + + for (FLEXArgumentInputView *inputView in self.argumentInputViews) { + height += [inputView sizeThatFits:constrainSize].height; + height += verticalPadding; + } + + return CGSizeMake(size.width, height); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.h new file mode 100755 index 0000000..13c011d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.h @@ -0,0 +1,28 @@ +// +// FLEXFieldEditorViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@class FLEXFieldEditorView; +@class FLEXArgumentInputView; + +@interface FLEXFieldEditorViewController : UIViewController + +- (id)initWithTarget:(id)target; + +// Convenience accessor since many subclasses only use one input view +@property (nonatomic, readonly) FLEXArgumentInputView *firstInputView; + +// For subclass use only. +@property (nonatomic, strong, readonly) id target; +@property (nonatomic, strong, readonly) FLEXFieldEditorView *fieldEditorView; +@property (nonatomic, strong, readonly) UIBarButtonItem *setterButton; +- (void)actionButtonPressed:(id)sender; +- (NSString *)titleForActionButton; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.m new file mode 100755 index 0000000..6ab029c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXFieldEditorViewController.m @@ -0,0 +1,117 @@ +// +// FLEXFieldEditorViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorViewController.h" +#import "FLEXFieldEditorView.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXUtility.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputViewFactory.h" + +@interface FLEXFieldEditorViewController () + +@property (nonatomic, strong) UIScrollView *scrollView; + +@property (nonatomic, strong, readwrite) id target; +@property (nonatomic, strong, readwrite) FLEXFieldEditorView *fieldEditorView; +@property (nonatomic, strong, readwrite) UIBarButtonItem *setterButton; + +@end + +@implementation FLEXFieldEditorViewController + +- (id)initWithTarget:(id)target +{ + self = [super initWithNibName:nil bundle:nil]; + if (self) { + self.target = target; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)keyboardDidShow:(NSNotification *)notification +{ + CGRect keyboardRectInWindow = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGSize keyboardSize = [self.view convertRect:keyboardRectInWindow fromView:nil].size; + UIEdgeInsets scrollInsets = self.scrollView.contentInset; + scrollInsets.bottom = keyboardSize.height; + self.scrollView.contentInset = scrollInsets; + self.scrollView.scrollIndicatorInsets = scrollInsets; + + // Find the active input view and scroll to make sure it's visible. + for (FLEXArgumentInputView *argumentInputView in self.fieldEditorView.argumentInputViews) { + if (argumentInputView.inputViewIsFirstResponder) { + CGRect scrollToVisibleRect = [self.scrollView convertRect:argumentInputView.bounds fromView:argumentInputView]; + [self.scrollView scrollRectToVisible:scrollToVisibleRect animated:YES]; + break; + } + } +} + +- (void)keyboardWillHide:(NSNotification *)notification +{ + UIEdgeInsets scrollInsets = self.scrollView.contentInset; + scrollInsets.bottom = 0.0; + self.scrollView.contentInset = scrollInsets; + self.scrollView.scrollIndicatorInsets = scrollInsets; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.view.backgroundColor = [FLEXUtility scrollViewGrayColor]; + + self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; + self.scrollView.backgroundColor = self.view.backgroundColor; + self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.scrollView.delegate = self; + [self.view addSubview:self.scrollView]; + + self.fieldEditorView = [[FLEXFieldEditorView alloc] init]; + self.fieldEditorView.backgroundColor = self.view.backgroundColor; + self.fieldEditorView.targetDescription = [NSString stringWithFormat:@"%@ %p", [self.target class], self.target]; + [self.scrollView addSubview:self.fieldEditorView]; + + self.setterButton = [[UIBarButtonItem alloc] initWithTitle:[self titleForActionButton] style:UIBarButtonItemStyleDone target:self action:@selector(actionButtonPressed:)]; + self.navigationItem.rightBarButtonItem = self.setterButton; +} + +- (void)viewWillLayoutSubviews +{ + CGSize constrainSize = CGSizeMake(self.scrollView.bounds.size.width, CGFLOAT_MAX); + CGSize fieldEditorSize = [self.fieldEditorView sizeThatFits:constrainSize]; + self.fieldEditorView.frame = CGRectMake(0, 0, fieldEditorSize.width, fieldEditorSize.height); + self.scrollView.contentSize = fieldEditorSize; +} + +- (FLEXArgumentInputView *)firstInputView +{ + return [[self.fieldEditorView argumentInputViews] firstObject]; +} + +- (void)actionButtonPressed:(id)sender +{ + // Subclasses can override + [self.fieldEditorView endEditing:YES]; +} + +- (NSString *)titleForActionButton +{ + // Subclasses can override. + return @"Set"; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.h new file mode 100755 index 0000000..43f5698 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.h @@ -0,0 +1,18 @@ +// +// FLEXIvarEditorViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorViewController.h" +#import + +@interface FLEXIvarEditorViewController : FLEXFieldEditorViewController + +- (id)initWithTarget:(id)target ivar:(Ivar)ivar; + ++ (BOOL)canEditIvar:(Ivar)ivar currentValue:(id)value; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.m new file mode 100755 index 0000000..da6fa5d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXIvarEditorViewController.m @@ -0,0 +1,72 @@ +// +// FLEXIvarEditorViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXIvarEditorViewController.h" +#import "FLEXFieldEditorView.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputViewFactory.h" +#import "FLEXArgumentInputSwitchView.h" + +@interface FLEXIvarEditorViewController () + +@property (nonatomic, assign) Ivar ivar; + +@end + +@implementation FLEXIvarEditorViewController + +- (id)initWithTarget:(id)target ivar:(Ivar)ivar +{ + self = [super initWithTarget:target]; + if (self) { + self.ivar = ivar; + self.title = @"Instance Variable"; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.fieldEditorView.fieldDescription = [FLEXRuntimeUtility prettyNameForIvar:self.ivar]; + + FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:ivar_getTypeEncoding(self.ivar)]; + inputView.backgroundColor = self.view.backgroundColor; + inputView.inputValue = [FLEXRuntimeUtility valueForIvar:self.ivar onObject:self.target]; + inputView.delegate = self; + self.fieldEditorView.argumentInputViews = @[inputView]; + + // Don't show a "set" button for switches. Set the ivar when the switch toggles. + if ([inputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { + self.navigationItem.rightBarButtonItem = nil; + } +} + +- (void)actionButtonPressed:(id)sender +{ + [super actionButtonPressed:sender]; + + [FLEXRuntimeUtility setValue:self.firstInputView.inputValue forIvar:self.ivar onObject:self.target]; + self.firstInputView.inputValue = [FLEXRuntimeUtility valueForIvar:self.ivar onObject:self.target]; +} + +- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView +{ + if ([argumentInputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { + [self actionButtonPressed:nil]; + } +} + ++ (BOOL)canEditIvar:(Ivar)ivar currentValue:(id)value +{ + return [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:ivar_getTypeEncoding(ivar) currentValue:value]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.h new file mode 100755 index 0000000..66e7360 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.h @@ -0,0 +1,16 @@ +// +// FLEXMethodCallingViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorViewController.h" +#import + +@interface FLEXMethodCallingViewController : FLEXFieldEditorViewController + +- (id)initWithTarget:(id)target method:(Method)method; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.m new file mode 100755 index 0000000..2c6506b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXMethodCallingViewController.m @@ -0,0 +1,100 @@ +// +// FLEXMethodCallingViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXMethodCallingViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXFieldEditorView.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputViewFactory.h" + +@interface FLEXMethodCallingViewController () + +@property (nonatomic, assign) Method method; + +@end + +@implementation FLEXMethodCallingViewController + +- (id)initWithTarget:(id)target method:(Method)method +{ + self = [super initWithTarget:target]; + if (self) { + self.method = method; + self.title = [self isClassMethod] ? @"Class Method" : @"Method"; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.fieldEditorView.fieldDescription = [FLEXRuntimeUtility prettyNameForMethod:self.method isClassMethod:[self isClassMethod]]; + + NSArray *methodComponents = [FLEXRuntimeUtility prettyArgumentComponentsForMethod:self.method]; + NSMutableArray *argumentInputViews = [NSMutableArray array]; + unsigned int argumentIndex = kFLEXNumberOfImplicitArgs; + for (NSString *methodComponent in methodComponents) { + char *argumentTypeEncoding = method_copyArgumentType(self.method, argumentIndex); + FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:argumentTypeEncoding]; + free(argumentTypeEncoding); + + inputView.backgroundColor = self.view.backgroundColor; + inputView.title = methodComponent; + [argumentInputViews addObject:inputView]; + argumentIndex++; + } + self.fieldEditorView.argumentInputViews = argumentInputViews; +} + +- (BOOL)isClassMethod +{ + return self.target && self.target == [self.target class]; +} + +- (NSString *)titleForActionButton +{ + return @"Call"; +} + +- (void)actionButtonPressed:(id)sender +{ + [super actionButtonPressed:sender]; + + NSMutableArray *arguments = [NSMutableArray array]; + for (FLEXArgumentInputView *inputView in self.fieldEditorView.argumentInputViews) { + id argumentValue = inputView.inputValue; + if (!argumentValue) { + // Use NSNulls as placeholders in the array. They will be interpreted as nil arguments. + argumentValue = [NSNull null]; + } + [arguments addObject:argumentValue]; + } + + NSError *error = nil; + id returnedObject = [FLEXRuntimeUtility performSelector:method_getName(self.method) onObject:self.target withArguments:arguments error:&error]; + + if (error) { + NSString *title = @"Method Call Failed"; + NSString *message = [error localizedDescription]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alert show]; + } else if (returnedObject) { + // For non-nil (or void) return types, push an explorer view controller to display the returned object + FLEXObjectExplorerViewController *explorerViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:returnedObject]; + [self.navigationController pushViewController:explorerViewController animated:YES]; + } else { + // If we didn't get a returned object but the method call succeeded, + // pop this view controller off the stack to indicate that the call went through. + [self.navigationController popViewControllerAnimated:YES]; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.h new file mode 100755 index 0000000..8d42c8e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.h @@ -0,0 +1,18 @@ +// +// FLEXPropertyEditorViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/20/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXFieldEditorViewController.h" +#import + +@interface FLEXPropertyEditorViewController : FLEXFieldEditorViewController + +- (id)initWithTarget:(id)target property:(objc_property_t)property; + ++ (BOOL)canEditProperty:(objc_property_t)property currentValue:(id)value; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.m new file mode 100755 index 0000000..4b09d83 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Editing/FLEXPropertyEditorViewController.m @@ -0,0 +1,94 @@ +// +// FLEXPropertyEditorViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/20/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXPropertyEditorViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXFieldEditorView.h" +#import "FLEXArgumentInputView.h" +#import "FLEXArgumentInputViewFactory.h" +#import "FLEXArgumentInputSwitchView.h" + +@interface FLEXPropertyEditorViewController () + +@property (nonatomic, assign) objc_property_t property; + +@end + +@implementation FLEXPropertyEditorViewController + +- (id)initWithTarget:(id)target property:(objc_property_t)property +{ + self = [super initWithTarget:target]; + if (self) { + self.property = property; + self.title = @"Property"; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.fieldEditorView.fieldDescription = [FLEXRuntimeUtility fullDescriptionForProperty:self.property]; + id currentValue = [FLEXRuntimeUtility valueForProperty:self.property onObject:self.target]; + self.setterButton.enabled = [[self class] canEditProperty:self.property currentValue:currentValue]; + + const char *typeEncoding = [[FLEXRuntimeUtility typeEncodingForProperty:self.property] UTF8String]; + FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:typeEncoding]; + inputView.backgroundColor = self.view.backgroundColor; + inputView.inputValue = [FLEXRuntimeUtility valueForProperty:self.property onObject:self.target]; + inputView.delegate = self; + self.fieldEditorView.argumentInputViews = @[inputView]; + + // Don't show a "set" button for switches - just call the setter immediately after the switch toggles. + if ([inputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { + self.navigationItem.rightBarButtonItem = nil; + } +} + +- (void)actionButtonPressed:(id)sender +{ + [super actionButtonPressed:sender]; + + id userInputObject = self.firstInputView.inputValue; + NSArray *arguments = userInputObject ? @[userInputObject] : nil; + SEL setterSelector = [FLEXRuntimeUtility setterSelectorForProperty:self.property]; + NSError *error = nil; + [FLEXRuntimeUtility performSelector:setterSelector onObject:self.target withArguments:arguments error:&error]; + if (error) { + NSString *title = @"Property Setter Failed"; + NSString *message = [error localizedDescription]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alert show]; + self.firstInputView.inputValue = [FLEXRuntimeUtility valueForProperty:self.property onObject:self.target]; + } else { + // If the setter was called without error, pop the view controller to indicate that and make the user's life easier. + // Don't do this for simulated taps on the action button (i.e. from switch/BOOL editors). The experience is weird there. + if (sender) { + [self.navigationController popViewControllerAnimated:YES]; + } + } +} + +- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView +{ + if ([argumentInputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { + [self actionButtonPressed:nil]; + } +} + ++ (BOOL)canEditProperty:(objc_property_t)property currentValue:(id)value +{ + const char *typeEncoding = [[FLEXRuntimeUtility typeEncodingForProperty:property] UTF8String]; + BOOL canEditType = [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:typeEncoding currentValue:value]; + BOOL isReadonly = [FLEXRuntimeUtility isReadonlyProperty:property]; + return canEditType && !isReadonly; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.h new file mode 100755 index 0000000..0e41b7b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.h @@ -0,0 +1,37 @@ +// +// FLEXExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@protocol FLEXExplorerViewControllerDelegate; + +@interface FLEXExplorerViewController : UIViewController + +@property (nonatomic, weak) id delegate; + +- (BOOL)shouldReceiveTouchAtWindowPoint:(CGPoint)pointInWindowCoordinates; +- (BOOL)wantsWindowToBecomeKey; + +// Keyboard shortcut helpers + +- (void)toggleSelectTool; +- (void)toggleMoveTool; +- (void)toggleViewsTool; +- (void)toggleMenuTool; +- (void)handleDownArrowKeyPressed; +- (void)handleUpArrowKeyPressed; +- (void)handleRightArrowKeyPressed; +- (void)handleLeftArrowKeyPressed; + +@end + +@protocol FLEXExplorerViewControllerDelegate + +- (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerViewController; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.m new file mode 100755 index 0000000..980d6fd --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXExplorerViewController.m @@ -0,0 +1,908 @@ +// +// FLEXExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXExplorerViewController.h" +#import "FLEXExplorerToolbar.h" +#import "FLEXToolbarItem.h" +#import "FLEXUtility.h" +#import "FLEXHierarchyTableViewController.h" +#import "FLEXGlobalsTableViewController.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXNetworkHistoryTableViewController.h" + +typedef NS_ENUM(NSUInteger, FLEXExplorerMode) { + FLEXExplorerModeDefault, + FLEXExplorerModeSelect, + FLEXExplorerModeMove +}; + +@interface FLEXExplorerViewController () + +@property (nonatomic, strong) FLEXExplorerToolbar *explorerToolbar; + +/// Tracks the currently active tool/mode +@property (nonatomic, assign) FLEXExplorerMode currentMode; + +/// Gesture recognizer for dragging a view in move mode +@property (nonatomic, strong) UIPanGestureRecognizer *movePanGR; + +/// Gesture recognizer for showing additional details on the selected view +@property (nonatomic, strong) UITapGestureRecognizer *detailsTapGR; + +/// Only valid while a move pan gesture is in progress. +@property (nonatomic, assign) CGRect selectedViewFrameBeforeDragging; + +/// Only valid while a toolbar drag pan gesture is in progress. +@property (nonatomic, assign) CGRect toolbarFrameBeforeDragging; + +/// Borders of all the visible views in the hierarchy at the selection point. +/// The keys are NSValues with the correponding view (nonretained). +@property (nonatomic, strong) NSDictionary *outlineViewsForVisibleViews; + +/// The actual views at the selection point with the deepest view last. +@property (nonatomic, strong) NSArray *viewsAtTapPoint; + +/// The view that we're currently highlighting with an overlay and displaying details for. +@property (nonatomic, strong) UIView *selectedView; + +/// A colored transparent overlay to indicate that the view is selected. +@property (nonatomic, strong) UIView *selectedViewOverlay; + +/// Tracked so we can restore the key window after dismissing a modal. +/// We need to become key after modal presentation so we can correctly capture intput. +/// If we're just showing the toolbar, we want the main app's window to remain key so that we don't interfere with input, status bar, etc. +@property (nonatomic, strong) UIWindow *previousKeyWindow; + +/// Similar to the previousKeyWindow property above, we need to track status bar styling if +/// the app doesn't use view controller based status bar management. When we present a modal, +/// we want to change the status bar style to UIStausBarStyleDefault. Before changing, we stash +/// the current style. On dismissal, we return the staus bar to the style that the app was using previously. +@property (nonatomic, assign) UIStatusBarStyle previousStatusBarStyle; + +/// All views that we're KVOing. Used to help us clean up properly. +@property (nonatomic, strong) NSMutableSet *observedViews; + +@end + +@implementation FLEXExplorerViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.observedViews = [NSMutableSet set]; + } + return self; +} + +-(void)dealloc +{ + for (UIView *view in _observedViews) { + [self stopObservingView:view]; + } +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Toolbar + self.explorerToolbar = [[FLEXExplorerToolbar alloc] init]; + CGSize toolbarSize = [self.explorerToolbar sizeThatFits:self.view.bounds.size]; + // Start the toolbar off below any bars that may be at the top of the view. + CGFloat toolbarOriginY = 100.0; + self.explorerToolbar.frame = CGRectMake(0.0, toolbarOriginY, toolbarSize.width, toolbarSize.height); + self.explorerToolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin; + [self.view addSubview:self.explorerToolbar]; + [self setupToolbarActions]; + [self setupToolbarGestures]; + + // View selection + UITapGestureRecognizer *selectionTapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSelectionTap:)]; + [self.view addGestureRecognizer:selectionTapGR]; + + // View moving + self.movePanGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMovePan:)]; + self.movePanGR.enabled = self.currentMode == FLEXExplorerModeMove; + [self.view addGestureRecognizer:self.movePanGR]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + [self updateButtonStates]; +} + + +#pragma mark - Rotation + +- (UIViewController *)viewControllerForRotationAndOrientation +{ + UIWindow *window = self.previousKeyWindow ?: [[UIApplication sharedApplication] keyWindow]; + UIViewController *viewController = window.rootViewController; + NSString *viewControllerSelectorString = [@[@"_vie", @"wContro", @"llerFor", @"Supported", @"Interface", @"Orientations"] componentsJoinedByString:@""]; + SEL viewControllerSelector = NSSelectorFromString(viewControllerSelectorString); + if ([viewController respondsToSelector:viewControllerSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + viewController = [viewController performSelector:viewControllerSelector]; +#pragma clang diagnostic pop + } + return viewController; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations +{ + UIViewController *viewControllerToAsk = [self viewControllerForRotationAndOrientation]; + UIInterfaceOrientationMask supportedOrientations = [FLEXUtility infoPlistSupportedInterfaceOrientationsMask]; + if (viewControllerToAsk && viewControllerToAsk != self) { + supportedOrientations = [viewControllerToAsk supportedInterfaceOrientations]; + } + + // The UIViewController docs state that this method must not return zero. + // If we weren't able to get a valid value for the supported interface orientations, default to all supported. + if (supportedOrientations == 0) { + supportedOrientations = UIInterfaceOrientationMaskAll; + } + + return supportedOrientations; +} + +- (BOOL)shouldAutorotate +{ + UIViewController *viewControllerToAsk = [self viewControllerForRotationAndOrientation]; + BOOL shouldAutorotate = YES; + if (viewControllerToAsk && viewControllerToAsk != self) { + shouldAutorotate = [viewControllerToAsk shouldAutorotate]; + } + return shouldAutorotate; +} + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + for (UIView *outlineView in [self.outlineViewsForVisibleViews allValues]) { + outlineView.hidden = YES; + } + self.selectedViewOverlay.hidden = YES; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + for (UIView *view in self.viewsAtTapPoint) { + NSValue *key = [NSValue valueWithNonretainedObject:view]; + UIView *outlineView = self.outlineViewsForVisibleViews[key]; + outlineView.frame = [self frameInLocalCoordinatesForView:view]; + if (self.currentMode == FLEXExplorerModeSelect) { + outlineView.hidden = NO; + } + } + + if (self.selectedView) { + self.selectedViewOverlay.frame = [self frameInLocalCoordinatesForView:self.selectedView]; + self.selectedViewOverlay.hidden = NO; + } +} + + +#pragma mark - Setter Overrides + +- (void)setSelectedView:(UIView *)selectedView +{ + if (![_selectedView isEqual:selectedView]) { + if (![self.viewsAtTapPoint containsObject:_selectedView]) { + [self stopObservingView:_selectedView]; + } + + _selectedView = selectedView; + + [self beginObservingView:selectedView]; + + // Update the toolbar and selected overlay + self.explorerToolbar.selectedViewDescription = [FLEXUtility descriptionForView:selectedView includingFrame:YES]; + self.explorerToolbar.selectedViewOverlayColor = [FLEXUtility consistentRandomColorForObject:selectedView];; + + if (selectedView) { + if (!self.selectedViewOverlay) { + self.selectedViewOverlay = [[UIView alloc] init]; + [self.view addSubview:self.selectedViewOverlay]; + self.selectedViewOverlay.layer.borderWidth = 1.0; + } + UIColor *outlineColor = [FLEXUtility consistentRandomColorForObject:selectedView]; + self.selectedViewOverlay.backgroundColor = [outlineColor colorWithAlphaComponent:0.2]; + self.selectedViewOverlay.layer.borderColor = [outlineColor CGColor]; + self.selectedViewOverlay.frame = [self.view convertRect:selectedView.bounds fromView:selectedView]; + + // Make sure the selected overlay is in front of all the other subviews except the toolbar, which should always stay on top. + [self.view bringSubviewToFront:self.selectedViewOverlay]; + [self.view bringSubviewToFront:self.explorerToolbar]; + } else { + [self.selectedViewOverlay removeFromSuperview]; + self.selectedViewOverlay = nil; + } + + // Some of the button states depend on whether we have a selected view. + [self updateButtonStates]; + } +} + +- (void)setViewsAtTapPoint:(NSArray *)viewsAtTapPoint +{ + if (![_viewsAtTapPoint isEqual:viewsAtTapPoint]) { + for (UIView *view in _viewsAtTapPoint) { + if (view != self.selectedView) { + [self stopObservingView:view]; + } + } + + _viewsAtTapPoint = viewsAtTapPoint; + + for (UIView *view in viewsAtTapPoint) { + [self beginObservingView:view]; + } + } +} + +- (void)setCurrentMode:(FLEXExplorerMode)currentMode +{ + if (_currentMode != currentMode) { + _currentMode = currentMode; + switch (currentMode) { + case FLEXExplorerModeDefault: + [self removeAndClearOutlineViews]; + self.viewsAtTapPoint = nil; + self.selectedView = nil; + break; + + case FLEXExplorerModeSelect: + // Make sure the outline views are unhidden in case we came from the move mode. + for (id key in self.outlineViewsForVisibleViews) { + UIView *outlineView = self.outlineViewsForVisibleViews[key]; + outlineView.hidden = NO; + } + break; + + case FLEXExplorerModeMove: + // Hide all the outline views to focus on the selected view, which is the only one that will move. + for (id key in self.outlineViewsForVisibleViews) { + UIView *outlineView = self.outlineViewsForVisibleViews[key]; + outlineView.hidden = YES; + } + break; + } + self.movePanGR.enabled = currentMode == FLEXExplorerModeMove; + [self updateButtonStates]; + } +} + + +#pragma mark - View Tracking + +- (void)beginObservingView:(UIView *)view +{ + // Bail if we're already observing this view or if there's nothing to observe. + if (!view || [self.observedViews containsObject:view]) { + return; + } + + for (NSString *keyPath in [[self class] viewKeyPathsToTrack]) { + [view addObserver:self forKeyPath:keyPath options:0 context:NULL]; + } + + [self.observedViews addObject:view]; +} + +- (void)stopObservingView:(UIView *)view +{ + if (!view) { + return; + } + + for (NSString *keyPath in [[self class] viewKeyPathsToTrack]) { + [view removeObserver:self forKeyPath:keyPath]; + } + + [self.observedViews removeObject:view]; +} + ++ (NSArray *)viewKeyPathsToTrack +{ + static NSArray *trackedViewKeyPaths = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *frameKeyPath = NSStringFromSelector(@selector(frame)); + trackedViewKeyPaths = @[frameKeyPath]; + }); + return trackedViewKeyPaths; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + [self updateOverlayAndDescriptionForObjectIfNeeded:object]; +} + +- (void)updateOverlayAndDescriptionForObjectIfNeeded:(id)object +{ + NSUInteger indexOfView = [self.viewsAtTapPoint indexOfObject:object]; + if (indexOfView != NSNotFound) { + UIView *view = self.viewsAtTapPoint[indexOfView]; + NSValue *key = [NSValue valueWithNonretainedObject:view]; + UIView *outline = self.outlineViewsForVisibleViews[key]; + if (outline) { + outline.frame = [self frameInLocalCoordinatesForView:view]; + } + } + if (object == self.selectedView) { + // Update the selected view description since we show the frame value there. + self.explorerToolbar.selectedViewDescription = [FLEXUtility descriptionForView:self.selectedView includingFrame:YES]; + CGRect selectedViewOutlineFrame = [self frameInLocalCoordinatesForView:self.selectedView]; + self.selectedViewOverlay.frame = selectedViewOutlineFrame; + } +} + +- (CGRect)frameInLocalCoordinatesForView:(UIView *)view +{ + // First convert to window coordinates since the view may be in a different window than our view. + CGRect frameInWindow = [view convertRect:view.bounds toView:nil]; + // Then convert from the window to our view's coordinate space. + return [self.view convertRect:frameInWindow fromView:nil]; +} + + +#pragma mark - Toolbar Buttons + +- (void)setupToolbarActions +{ + [self.explorerToolbar.selectItem addTarget:self action:@selector(selectButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self.explorerToolbar.hierarchyItem addTarget:self action:@selector(hierarchyButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self.explorerToolbar.moveItem addTarget:self action:@selector(moveButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self.explorerToolbar.globalsItem addTarget:self action:@selector(globalsButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self.explorerToolbar.closeItem addTarget:self action:@selector(closeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; +} + +- (void)selectButtonTapped:(FLEXToolbarItem *)sender +{ + [self toggleSelectTool]; +} + +- (void)hierarchyButtonTapped:(FLEXToolbarItem *)sender +{ + [self toggleViewsTool]; +} + +- (NSArray *)allViewsInHierarchy +{ + NSMutableArray *allViews = [NSMutableArray array]; + NSArray *windows = [FLEXUtility allWindows]; + for (UIWindow *window in windows) { + if (window != self.view.window) { + [allViews addObject:window]; + [allViews addObjectsFromArray:[self allRecursiveSubviewsInView:window]]; + } + } + return allViews; +} + +- (UIWindow *)statusWindow +{ + NSString *statusBarString = [NSString stringWithFormat:@"%@arWindow", @"_statusB"]; + return [[UIApplication sharedApplication] valueForKey:statusBarString]; +} + +- (void)moveButtonTapped:(FLEXToolbarItem *)sender +{ + [self toggleMoveTool]; +} + +- (void)globalsButtonTapped:(FLEXToolbarItem *)sender +{ + [self toggleMenuTool]; +} + +- (void)closeButtonTapped:(FLEXToolbarItem *)sender +{ + self.currentMode = FLEXExplorerModeDefault; + [self.delegate explorerViewControllerDidFinish:self]; +} + +- (void)updateButtonStates +{ + // Move and details only active when an object is selected. + BOOL hasSelectedObject = self.selectedView != nil; + self.explorerToolbar.moveItem.enabled = hasSelectedObject; + self.explorerToolbar.selectItem.selected = self.currentMode == FLEXExplorerModeSelect; + self.explorerToolbar.moveItem.selected = self.currentMode == FLEXExplorerModeMove; +} + + +#pragma mark - Toolbar Dragging + +- (void)setupToolbarGestures +{ + // Pan gesture for dragging. + UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleToolbarPanGesture:)]; + [self.explorerToolbar.dragHandle addGestureRecognizer:panGR]; + + // Tap gesture for hinting. + UITapGestureRecognizer *hintTapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleToolbarHintTapGesture:)]; + [self.explorerToolbar.dragHandle addGestureRecognizer:hintTapGR]; + + // Tap gesture for showing additional details + self.detailsTapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleToolbarDetailsTapGesture:)]; + [self.explorerToolbar.selectedViewDescriptionContainer addGestureRecognizer:self.detailsTapGR]; +} + +- (void)handleToolbarPanGesture:(UIPanGestureRecognizer *)panGR +{ + switch (panGR.state) { + case UIGestureRecognizerStateBegan: + self.toolbarFrameBeforeDragging = self.explorerToolbar.frame; + [self updateToolbarPostionWithDragGesture:panGR]; + break; + + case UIGestureRecognizerStateChanged: + case UIGestureRecognizerStateEnded: + [self updateToolbarPostionWithDragGesture:panGR]; + break; + + default: + break; + } +} + +- (void)updateToolbarPostionWithDragGesture:(UIPanGestureRecognizer *)panGR +{ + CGPoint translation = [panGR translationInView:self.view]; + CGRect newToolbarFrame = self.toolbarFrameBeforeDragging; + newToolbarFrame.origin.y += translation.y; + + CGFloat maxY = CGRectGetMaxY(self.view.bounds) - newToolbarFrame.size.height; + if (newToolbarFrame.origin.y < 0.0) { + newToolbarFrame.origin.y = 0.0; + } else if (newToolbarFrame.origin.y > maxY) { + newToolbarFrame.origin.y = maxY; + } + + self.explorerToolbar.frame = newToolbarFrame; +} + +- (void)handleToolbarHintTapGesture:(UITapGestureRecognizer *)tapGR +{ + // Bounce the toolbar to indicate that it is draggable. + // TODO: make it bouncier. + if (tapGR.state == UIGestureRecognizerStateRecognized) { + CGRect originalToolbarFrame = self.explorerToolbar.frame; + const NSTimeInterval kHalfwayDuration = 0.2; + const CGFloat kVerticalOffset = 30.0; + [UIView animateWithDuration:kHalfwayDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ + CGRect newToolbarFrame = self.explorerToolbar.frame; + newToolbarFrame.origin.y += kVerticalOffset; + self.explorerToolbar.frame = newToolbarFrame; + } completion:^(BOOL finished) { + [UIView animateWithDuration:kHalfwayDuration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ + self.explorerToolbar.frame = originalToolbarFrame; + } completion:nil]; + }]; + } +} + +- (void)handleToolbarDetailsTapGesture:(UITapGestureRecognizer *)tapGR +{ + if (tapGR.state == UIGestureRecognizerStateRecognized && self.selectedView) { + FLEXObjectExplorerViewController *selectedViewExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:self.selectedView]; + selectedViewExplorer.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(selectedViewExplorerFinished:)]; + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:selectedViewExplorer]; + [self makeKeyAndPresentViewController:navigationController animated:YES completion:nil]; + } +} + + +#pragma mark - View Selection + +- (void)handleSelectionTap:(UITapGestureRecognizer *)tapGR +{ + // Only if we're in selection mode + if (self.currentMode == FLEXExplorerModeSelect && tapGR.state == UIGestureRecognizerStateRecognized) { + // Note that [tapGR locationInView:nil] is broken in iOS 8, so we have to do a two step conversion to window coordinates. + // Thanks to @lascorbe for finding this: https://github.com/Flipboard/FLEX/pull/31 + CGPoint tapPointInView = [tapGR locationInView:self.view]; + CGPoint tapPointInWindow = [self.view convertPoint:tapPointInView toView:nil]; + [self updateOutlineViewsForSelectionPoint:tapPointInWindow]; + } +} + +- (void)updateOutlineViewsForSelectionPoint:(CGPoint)selectionPointInWindow +{ + [self removeAndClearOutlineViews]; + + // Include hidden views in the "viewsAtTapPoint" array so we can show them in the hierarchy list. + self.viewsAtTapPoint = [self viewsAtPoint:selectionPointInWindow skipHiddenViews:NO]; + + // For outlined views and the selected view, only use visible views. + // Outlining hidden views adds clutter and makes the selection behavior confusing. + NSArray *visibleViewsAtTapPoint = [self viewsAtPoint:selectionPointInWindow skipHiddenViews:YES]; + NSMutableDictionary *newOutlineViewsForVisibleViews = [NSMutableDictionary dictionary]; + for (UIView *view in visibleViewsAtTapPoint) { + UIView *outlineView = [self outlineViewForView:view]; + [self.view addSubview:outlineView]; + NSValue *key = [NSValue valueWithNonretainedObject:view]; + [newOutlineViewsForVisibleViews setObject:outlineView forKey:key]; + } + self.outlineViewsForVisibleViews = newOutlineViewsForVisibleViews; + self.selectedView = [self viewForSelectionAtPoint:selectionPointInWindow]; + + // Make sure the explorer toolbar doesn't end up behind the newly added outline views. + [self.view bringSubviewToFront:self.explorerToolbar]; + + [self updateButtonStates]; +} + +- (UIView *)outlineViewForView:(UIView *)view +{ + CGRect outlineFrame = [self frameInLocalCoordinatesForView:view]; + UIView *outlineView = [[UIView alloc] initWithFrame:outlineFrame]; + outlineView.backgroundColor = [UIColor clearColor]; + outlineView.layer.borderColor = [[FLEXUtility consistentRandomColorForObject:view] CGColor]; + outlineView.layer.borderWidth = 1.0; + return outlineView; +} + +- (void)removeAndClearOutlineViews +{ + for (id key in self.outlineViewsForVisibleViews) { + UIView *outlineView = self.outlineViewsForVisibleViews[key]; + [outlineView removeFromSuperview]; + } + self.outlineViewsForVisibleViews = nil; +} + +- (NSArray *)viewsAtPoint:(CGPoint)tapPointInWindow skipHiddenViews:(BOOL)skipHidden +{ + NSMutableArray *views = [NSMutableArray array]; + for (UIWindow *window in [FLEXUtility allWindows]) { + // Don't include the explorer's own window or subviews. + if (window != self.view.window && [window pointInside:tapPointInWindow withEvent:nil]) { + [views addObject:window]; + [views addObjectsFromArray:[self recursiveSubviewsAtPoint:tapPointInWindow inView:window skipHiddenViews:skipHidden]]; + } + } + return views; +} + +- (UIView *)viewForSelectionAtPoint:(CGPoint)tapPointInWindow +{ + // Select in the window that would handle the touch, but don't just use the result of hitTest:withEvent: so we can still select views with interaction disabled. + // Default to the the application's key window if none of the windows want the touch. + UIWindow *windowForSelection = [[UIApplication sharedApplication] keyWindow]; + for (UIWindow *window in [[FLEXUtility allWindows] reverseObjectEnumerator]) { + // Ignore the explorer's own window. + if (window != self.view.window) { + if ([window hitTest:tapPointInWindow withEvent:nil]) { + windowForSelection = window; + break; + } + } + } + + // Select the deepest visible view at the tap point. This generally corresponds to what the user wants to select. + return [[self recursiveSubviewsAtPoint:tapPointInWindow inView:windowForSelection skipHiddenViews:YES] lastObject]; +} + +- (NSArray *)recursiveSubviewsAtPoint:(CGPoint)pointInView inView:(UIView *)view skipHiddenViews:(BOOL)skipHidden +{ + NSMutableArray *subviewsAtPoint = [NSMutableArray array]; + for (UIView *subview in view.subviews) { + BOOL isHidden = subview.hidden || subview.alpha < 0.01; + if (skipHidden && isHidden) { + continue; + } + + BOOL subviewContainsPoint = CGRectContainsPoint(subview.frame, pointInView); + if (subviewContainsPoint) { + [subviewsAtPoint addObject:subview]; + } + + // If this view doesn't clip to its bounds, we need to check its subviews even if it doesn't contain the selection point. + // They may be visible and contain the selection point. + if (subviewContainsPoint || !subview.clipsToBounds) { + CGPoint pointInSubview = [view convertPoint:pointInView toView:subview]; + [subviewsAtPoint addObjectsFromArray:[self recursiveSubviewsAtPoint:pointInSubview inView:subview skipHiddenViews:skipHidden]]; + } + } + return subviewsAtPoint; +} + +- (NSArray *)allRecursiveSubviewsInView:(UIView *)view +{ + NSMutableArray *subviews = [NSMutableArray array]; + for (UIView *subview in view.subviews) { + [subviews addObject:subview]; + [subviews addObjectsFromArray:[self allRecursiveSubviewsInView:subview]]; + } + return subviews; +} + +- (NSDictionary *)hierarchyDepthsForViews:(NSArray *)views +{ + NSMutableDictionary *hierarchyDepths = [NSMutableDictionary dictionary]; + for (UIView *view in views) { + NSInteger depth = 0; + UIView *tryView = view; + while (tryView.superview) { + tryView = tryView.superview; + depth++; + } + [hierarchyDepths setObject:@(depth) forKey:[NSValue valueWithNonretainedObject:view]]; + } + return hierarchyDepths; +} + + +#pragma mark - Selected View Moving + +- (void)handleMovePan:(UIPanGestureRecognizer *)movePanGR +{ + switch (movePanGR.state) { + case UIGestureRecognizerStateBegan: + self.selectedViewFrameBeforeDragging = self.selectedView.frame; + [self updateSelectedViewPositionWithDragGesture:movePanGR]; + break; + + case UIGestureRecognizerStateChanged: + case UIGestureRecognizerStateEnded: + [self updateSelectedViewPositionWithDragGesture:movePanGR]; + break; + + default: + break; + } +} + +- (void)updateSelectedViewPositionWithDragGesture:(UIPanGestureRecognizer *)movePanGR +{ + CGPoint translation = [movePanGR translationInView:self.selectedView.superview]; + CGRect newSelectedViewFrame = self.selectedViewFrameBeforeDragging; + newSelectedViewFrame.origin.x = FLEXFloor(newSelectedViewFrame.origin.x + translation.x); + newSelectedViewFrame.origin.y = FLEXFloor(newSelectedViewFrame.origin.y + translation.y); + self.selectedView.frame = newSelectedViewFrame; +} + + +#pragma mark - Touch Handling + +- (BOOL)shouldReceiveTouchAtWindowPoint:(CGPoint)pointInWindowCoordinates +{ + BOOL shouldReceiveTouch = NO; + + CGPoint pointInLocalCoordinates = [self.view convertPoint:pointInWindowCoordinates fromView:nil]; + + // Always if it's on the toolbar + if (CGRectContainsPoint(self.explorerToolbar.frame, pointInLocalCoordinates)) { + shouldReceiveTouch = YES; + } + + // Always if we're in selection mode + if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeSelect) { + shouldReceiveTouch = YES; + } + + // Always in move mode too + if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeMove) { + shouldReceiveTouch = YES; + } + + // Always if we have a modal presented + if (!shouldReceiveTouch && self.presentedViewController) { + shouldReceiveTouch = YES; + } + + return shouldReceiveTouch; +} + + +#pragma mark - FLEXHierarchyTableViewControllerDelegate + +- (void)hierarchyViewController:(FLEXHierarchyTableViewController *)hierarchyViewController didFinishWithSelectedView:(UIView *)selectedView +{ + // Note that we need to wait until the view controller is dismissed to calculated the frame of the outline view. + // Otherwise the coordinate conversion doesn't give the correct result. + [self resignKeyAndDismissViewControllerAnimated:YES completion:^{ + // If the selected view is outside of the tap point array (selected from "Full Hierarchy"), + // then clear out the tap point array and remove all the outline views. + if (![self.viewsAtTapPoint containsObject:selectedView]) { + self.viewsAtTapPoint = nil; + [self removeAndClearOutlineViews]; + } + + // If we now have a selected view and we didn't have one previously, go to "select" mode. + if (self.currentMode == FLEXExplorerModeDefault && selectedView) { + self.currentMode = FLEXExplorerModeSelect; + } + + // The selected view setter will also update the selected view overlay appropriately. + self.selectedView = selectedView; + }]; +} + + +#pragma mark - FLEXGlobalsViewControllerDelegate + +- (void)globalsViewControllerDidFinish:(FLEXGlobalsTableViewController *)globalsViewController +{ + [self resignKeyAndDismissViewControllerAnimated:YES completion:nil]; +} + + +#pragma mark - FLEXObjectExplorerViewController Done Action + +- (void)selectedViewExplorerFinished:(id)sender +{ + [self resignKeyAndDismissViewControllerAnimated:YES completion:nil]; +} + + +#pragma mark - Modal Presentation and Window Management + +- (void)makeKeyAndPresentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^)(void))completion +{ + // Save the current key window so we can restore it following dismissal. + self.previousKeyWindow = [[UIApplication sharedApplication] keyWindow]; + + // Make our window key to correctly handle input. + [self.view.window makeKeyWindow]; + + // Move the status bar on top of FLEX so we can get scroll to top behavior for taps. + [[self statusWindow] setWindowLevel:self.view.window.windowLevel + 1.0]; + + // If this app doesn't use view controller based status bar management and we're on iOS 7+, + // make sure the status bar style is UIStatusBarStyleDefault. We don't actully have to check + // for view controller based management because the global methods no-op if that is turned on. + self.previousStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle]; + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; + + // Show the view controller. + [self presentViewController:viewController animated:animated completion:completion]; +} + +- (void)resignKeyAndDismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion +{ + UIWindow *previousKeyWindow = self.previousKeyWindow; + self.previousKeyWindow = nil; + [previousKeyWindow makeKeyWindow]; + [[previousKeyWindow rootViewController] setNeedsStatusBarAppearanceUpdate]; + + // Restore the status bar window's normal window level. + // We want it above FLEX while a modal is presented for scroll to top, but below FLEX otherwise for exploration. + [[self statusWindow] setWindowLevel:UIWindowLevelStatusBar]; + + // Restore the stauts bar style if the app is using global status bar management. + [[UIApplication sharedApplication] setStatusBarStyle:self.previousStatusBarStyle]; + + [self dismissViewControllerAnimated:animated completion:completion]; +} + +- (BOOL)wantsWindowToBecomeKey +{ + return self.previousKeyWindow != nil; +} + +#pragma mark - Keyboard Shortcut Helpers + +- (void)toggleSelectTool +{ + if (self.currentMode == FLEXExplorerModeSelect) { + self.currentMode = FLEXExplorerModeDefault; + } else { + self.currentMode = FLEXExplorerModeSelect; + } +} + +- (void)toggleMoveTool +{ + if (self.currentMode == FLEXExplorerModeMove) { + self.currentMode = FLEXExplorerModeDefault; + } else { + self.currentMode = FLEXExplorerModeMove; + } +} + +- (void)toggleViewsTool +{ + BOOL viewsModalShown = [[self presentedViewController] isKindOfClass:[UINavigationController class]]; + viewsModalShown = viewsModalShown && [[[(UINavigationController *)[self presentedViewController] viewControllers] firstObject] isKindOfClass:[FLEXHierarchyTableViewController class]]; + if (viewsModalShown) { + [self resignKeyAndDismissViewControllerAnimated:YES completion:nil]; + } else { + void (^presentBlock)() = ^{ + NSArray *allViews = [self allViewsInHierarchy]; + NSDictionary *depthsForViews = [self hierarchyDepthsForViews:allViews]; + FLEXHierarchyTableViewController *hierarchyTVC = [[FLEXHierarchyTableViewController alloc] initWithViews:allViews viewsAtTap:self.viewsAtTapPoint selectedView:self.selectedView depths:depthsForViews]; + hierarchyTVC.delegate = self; + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:hierarchyTVC]; + [self makeKeyAndPresentViewController:navigationController animated:YES completion:nil]; + }; + + if (self.presentedViewController) { + [self resignKeyAndDismissViewControllerAnimated:NO completion:presentBlock]; + } else { + presentBlock(); + } + } +} + +- (void)toggleMenuTool +{ + BOOL menuModalShown = [[self presentedViewController] isKindOfClass:[UINavigationController class]]; + menuModalShown = menuModalShown && [[[(UINavigationController *)[self presentedViewController] viewControllers] firstObject] isKindOfClass:[FLEXGlobalsTableViewController class]]; + if (menuModalShown) { + [self resignKeyAndDismissViewControllerAnimated:YES completion:nil]; + } else { + void (^presentBlock)() = ^{ + FLEXGlobalsTableViewController *globalsViewController = [[FLEXGlobalsTableViewController alloc] init]; + globalsViewController.delegate = self; + [FLEXGlobalsTableViewController setApplicationWindow:[[UIApplication sharedApplication] keyWindow]]; + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:globalsViewController]; + [self makeKeyAndPresentViewController:navigationController animated:YES completion:nil]; + }; + + if (self.presentedViewController) { + [self resignKeyAndDismissViewControllerAnimated:NO completion:presentBlock]; + } else { + presentBlock(); + } + } +} + +- (void)handleDownArrowKeyPressed +{ + if (self.currentMode == FLEXExplorerModeMove) { + CGRect frame = self.selectedView.frame; + frame.origin.y += 1.0 / [[UIScreen mainScreen] scale]; + self.selectedView.frame = frame; + } else if (self.currentMode == FLEXExplorerModeSelect && [self.viewsAtTapPoint count] > 0) { + NSInteger selectedViewIndex = [self.viewsAtTapPoint indexOfObject:self.selectedView]; + if (selectedViewIndex > 0) { + self.selectedView = [self.viewsAtTapPoint objectAtIndex:selectedViewIndex - 1]; + } + } +} + +- (void)handleUpArrowKeyPressed +{ + if (self.currentMode == FLEXExplorerModeMove) { + CGRect frame = self.selectedView.frame; + frame.origin.y -= 1.0 / [[UIScreen mainScreen] scale]; + self.selectedView.frame = frame; + } else if (self.currentMode == FLEXExplorerModeSelect && [self.viewsAtTapPoint count] > 0) { + NSInteger selectedViewIndex = [self.viewsAtTapPoint indexOfObject:self.selectedView]; + if (selectedViewIndex < [self.viewsAtTapPoint count] - 1) { + self.selectedView = [self.viewsAtTapPoint objectAtIndex:selectedViewIndex + 1]; + } + } +} + +- (void)handleRightArrowKeyPressed +{ + if (self.currentMode == FLEXExplorerModeMove) { + CGRect frame = self.selectedView.frame; + frame.origin.x += 1.0 / [[UIScreen mainScreen] scale]; + self.selectedView.frame = frame; + } +} + +- (void)handleLeftArrowKeyPressed +{ + if (self.currentMode == FLEXExplorerModeMove) { + CGRect frame = self.selectedView.frame; + frame.origin.x -= 1.0 / [[UIScreen mainScreen] scale]; + self.selectedView.frame = frame; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.h new file mode 100755 index 0000000..8643c63 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.h @@ -0,0 +1,24 @@ +// +// FLEXWindow.h +// Flipboard +// +// Created by Ryan Olson on 4/13/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@protocol FLEXWindowEventDelegate; + +@interface FLEXWindow : UIWindow + +@property (nonatomic, weak) id eventDelegate; + +@end + +@protocol FLEXWindowEventDelegate + +- (BOOL)shouldHandleTouchAtPoint:(CGPoint)pointInWindow; +- (BOOL)canBecomeKeyWindow; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.m new file mode 100755 index 0000000..1923a5c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ExplorerInterface/FLEXWindow.m @@ -0,0 +1,67 @@ +// +// FLEXWindow.m +// Flipboard +// +// Created by Ryan Olson on 4/13/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXWindow.h" +#import + +@implementation FLEXWindow + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor clearColor]; + // Some apps have windows at UIWindowLevelStatusBar + n. + // If we make the window level too high, we block out UIAlertViews. + // There's a balance between staying above the app's windows and staying below alerts. + // UIWindowLevelStatusBar + 100 seems to hit that balance. + self.windowLevel = UIWindowLevelStatusBar + 100.0; + } + return self; +} + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + BOOL pointInside = NO; + if ([self.eventDelegate shouldHandleTouchAtPoint:point]) { + pointInside = [super pointInside:point withEvent:event]; + } + return pointInside; +} + +- (BOOL)shouldAffectStatusBarAppearance +{ + return [self isKeyWindow]; +} + +- (BOOL)canBecomeKeyWindow +{ + return [self.eventDelegate canBecomeKeyWindow]; +} + ++ (void)initialize +{ + // This adds a method (superclass override) at runtime which gives us the status bar behavior we want. + // The FLEX window is intended to be an overlay that generally doesn't affect the app underneath. + // Most of the time, we want the app's main window(s) to be in control of status bar behavior. + // Done at runtime with an obfuscated selector because it is private API. But you shoudn't ship this to the App Store anyways... + NSString *canAffectSelectorString = [@[@"_can", @"Affect", @"Status", @"Bar", @"Appearance"] componentsJoinedByString:@""]; + SEL canAffectSelector = NSSelectorFromString(canAffectSelectorString); + Method shouldAffectMethod = class_getInstanceMethod(self, @selector(shouldAffectStatusBarAppearance)); + IMP canAffectImplementation = method_getImplementation(shouldAffectMethod); + class_addMethod(self, canAffectSelector, canAffectImplementation, method_getTypeEncoding(shouldAffectMethod)); + + // One more... + NSString *canBecomeKeySelectorString = [NSString stringWithFormat:@"_%@", NSStringFromSelector(@selector(canBecomeKeyWindow))]; + SEL canBecomeKeySelector = NSSelectorFromString(canBecomeKeySelectorString); + Method canBecomeKeyMethod = class_getInstanceMethod(self, @selector(canBecomeKeyWindow)); + IMP canBecomeKeyImplementation = method_getImplementation(canBecomeKeyMethod); + class_addMethod(self, canBecomeKeySelector, canBecomeKeyImplementation, method_getTypeEncoding(canBecomeKeyMethod)); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEX.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEX.h new file mode 100755 index 0000000..bb6cd2f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEX.h @@ -0,0 +1,9 @@ +// +// FLEX.h +// FLEX +// +// Created by Eric Horacek on 7/18/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEXManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEXManager.h new file mode 100755 index 0000000..3310f1b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/FLEXManager.h @@ -0,0 +1,70 @@ +// +// FLEXManager.h +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import +#import + +@interface FLEXManager : NSObject + ++ (instancetype)sharedManager; + +@property (nonatomic, readonly) BOOL isHidden; + +- (void)showExplorer; +- (void)hideExplorer; +- (void)toggleExplorer; + +#pragma mark - Network Debugging + +/// If this property is set to YES, FLEX will swizzle NSURLConnection*Delegate and NSURLSession*Delegate methods +/// on classes that conform to the protocols. This allows you to view network activity history from the main FLEX menu. +/// Full responses are kept temporarily in a size limited cache and may be pruged under memory pressure. +@property (nonatomic, assign, getter=isNetworkDebuggingEnabled) BOOL networkDebuggingEnabled; + +/// Defaults to 25 MB if never set. Values set here are presisted across launches of the app. +/// The response cache uses an NSCache, so it may purge prior to hitting the limit when the app is under memory pressure. +@property (nonatomic, assign) NSUInteger networkResponseCacheByteLimit; + +#pragma mark - Keyboard Shortcuts + +/// Simulator keyboard shortcuts are enabled by default. +/// The shortcuts will not fire when there is an active text field, text view, or other responder accepting key input. +/// You can disable keyboard shortcuts if you have existing keyboard shortcuts that conflict with FLEX, or if you like doing things the hard way ;) +/// Keyboard shortcuts are always disabled (and support is compiled out) in non-simulator builds +@property (nonatomic, assign) BOOL simulatorShortcutsEnabled; + +/// Adds an action to run when the specified key & modifier combination is pressed +/// @param key A single character string matching a key on the keyboard +/// @param modifiers Modifier keys such as shift, command, or alt/option +/// @param action The block to run on the main thread when the key & modifier combination is recognized. +/// @param description Shown the the keyboard shortcut help menu, which is accessed via the '?' key. +/// @note The action block will be retained for the duration of the application. You may want to use weak references. +/// @note FLEX registers several default keyboard shortcuts. Use the '?' key to see a list of shortcuts. +- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description; + +#pragma mark - Extensions + +/// Adds an entry at the bottom of the list of Global State items. Call this method before this view controller is displayed. +/// @param entryName The string to be displayed in the cell. +/// @param objectFutureBlock When you tap on the row, information about the object returned by this block will be displayed. +/// Passing a block that returns an object allows you to display information about an object whose actual pointer may change at runtime (e.g. +currentUser) +/// @note This method must be called from the main thread. +/// The objectFutureBlock will be invoked from the main thread and may return nil. +/// @note The passed block will be copied and retain for the duration of the application, you may want to use __weak references. +- (void)registerGlobalEntryWithName:(NSString *)entryName objectFutureBlock:(id (^)(void))objectFutureBlock; + +/// Adds an entry at the bottom of the list of Global State items. Call this method before this view controller is displayed. +/// @param entryName The string to be displayed in the cell. +/// @param viewControllerFutureBlock When you tap on the row, view controller returned by this block will be pushed on the navigation controller stack. +/// @note This method must be called from the main thread. +/// The viewControllerFutureBlock will be invoked from the main thread and may not return nil. +/// @note The passed block will be copied and retain for the duration of the application, you may want to use __weak references. +- (void)registerGlobalEntryWithName:(NSString *)entryName + viewControllerFutureBlock:(UIViewController * (^)(void))viewControllerFutureBlock; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h new file mode 100755 index 0000000..20de90e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h @@ -0,0 +1,26 @@ +// +// PTDatabaseManager.h +// Derived from: +// +// FMDatabase.h +// FMDB( https://github.com/ccgus/fmdb ) +// +// Created by Peng Tao on 15/11/23. +// +// Licensed to Flying Meat Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Flying Meat Inc. licenses this file to you. + +#import + +@protocol FLEXDatabaseManager + +@required +- (instancetype)initWithPath:(NSString*)path; + +- (BOOL)open; +- (NSArray *)queryAllTables; +- (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName; +- (NSArray *)queryAllDataWithTableName:(NSString *)tableName; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h new file mode 100755 index 0000000..fca6cc8 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h @@ -0,0 +1,48 @@ +// +// PTMultiColumnTableView.h +// PTMultiColumnTableViewDemo +// +// Created by Peng Tao on 15/11/16. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import +#import "FLEXTableColumnHeader.h" + +@class FLEXMultiColumnTableView; + +@protocol FLEXMultiColumnTableViewDelegate + +@required +- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapLabelWithText:(NSString *)text; +- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapHeaderWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)sortType; + +@end + +@protocol FLEXMultiColumnTableViewDataSource + +@required + +- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView; +- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView; +- (NSString *)columnNameInColumn:(NSInteger)column; +- (NSString *)rowNameInRow:(NSInteger)row; +- (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row; +- (NSArray *)contentAtRow:(NSInteger)row; + +- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView widthForContentCellInColumn:(NSInteger)column; +- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView heightForContentCellInRow:(NSInteger)row; +- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView; +- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView; + +@end + + +@interface FLEXMultiColumnTableView : UIView + +@property (nonatomic, weak) iddataSource; +@property (nonatomic, weak) iddelegate; + +- (void)reloadData; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m new file mode 100755 index 0000000..9167914 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m @@ -0,0 +1,341 @@ +// +// PTMultiColumnTableView.m +// PTMultiColumnTableViewDemo +// +// Created by Peng Tao on 15/11/16. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import "FLEXMultiColumnTableView.h" +#import "FLEXTableContentCell.h" +#import "FLEXTableLeftCell.h" + +@interface FLEXMultiColumnTableView () + + +@property (nonatomic, strong) UIScrollView *contentScrollView; +@property (nonatomic, strong) UIScrollView *headerScrollView; +@property (nonatomic, strong) UITableView *leftTableView; +@property (nonatomic, strong) UITableView *contentTableView; +@property (nonatomic, strong) UIView *leftHeader; + +@property (nonatomic, strong) NSDictionary *sortStatusDict; +@property (nonatomic, strong) NSArray *rowData; +@end + +static const CGFloat kColumnMargin = 1; + +@implementation FLEXMultiColumnTableView + + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self loadUI]; + } + return self; +} + +- (void)didMoveToSuperview +{ + [super didMoveToSuperview]; + [self reloadData]; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat width = self.frame.size.width; + CGFloat height = self.frame.size.height; + CGFloat topheaderHeight = [self topHeaderHeight]; + CGFloat leftHeaderWidth = [self leftHeaderWidth]; + + CGFloat contentWidth = 0.0; + NSInteger rowsCount = [self numberOfColumns]; + for (int i = 0; i < rowsCount; i++) { + contentWidth += [self contentWidthForColumn:i]; + } + + self.leftTableView.frame = CGRectMake(0, topheaderHeight, leftHeaderWidth, height - topheaderHeight); + self.headerScrollView.frame = CGRectMake(leftHeaderWidth, 0, width - leftHeaderWidth, topheaderHeight); + self.headerScrollView.contentSize = CGSizeMake( self.contentTableView.frame.size.width, self.headerScrollView.frame.size.height); + self.contentTableView.frame = CGRectMake(0, 0, contentWidth + [self numberOfColumns] * [self columnMargin] , height - topheaderHeight); + self.contentScrollView.frame = CGRectMake(leftHeaderWidth, topheaderHeight, width - leftHeaderWidth, height - topheaderHeight); + self.contentScrollView.contentSize = self.contentTableView.frame.size; + self.leftHeader.frame = CGRectMake(0, 0, [self leftHeaderWidth], [self topHeaderHeight]); +} + + +- (void)loadUI +{ + [self loadHeaderScrollView]; + [self loadContentScrollView]; + [self loadLeftView]; +} + +- (void)reloadData +{ + [self loadLeftViewData]; + [self loadContentData]; + [self loadHeaderData]; +} + +#pragma mark - UI + +- (void)loadHeaderScrollView +{ + UIScrollView *headerScrollView = [[UIScrollView alloc] init]; + headerScrollView.delegate = self; + self.headerScrollView = headerScrollView; + self.headerScrollView.backgroundColor = [UIColor colorWithWhite:0.803 alpha:0.850]; + + [self addSubview:headerScrollView]; +} + +- (void)loadContentScrollView +{ + + UIScrollView *scrollView = [[UIScrollView alloc] init]; + scrollView.bounces = NO; + scrollView.delegate = self; + + UITableView *tableView = [[UITableView alloc] init]; + tableView.delegate = self; + tableView.dataSource = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + + [self addSubview:scrollView]; + [scrollView addSubview:tableView]; + + self.contentScrollView = scrollView; + self.contentTableView = tableView; + +} + +- (void)loadLeftView +{ + UITableView *leftTableView = [[UITableView alloc] init]; + leftTableView.delegate = self; + leftTableView.dataSource = self; + leftTableView.separatorStyle = UITableViewCellSeparatorStyleNone; + self.leftTableView = leftTableView; + [self addSubview:leftTableView]; + + UIView *leftHeader = [[UIView alloc] init]; + leftHeader.backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.668]; + self.leftHeader = leftHeader; + [self addSubview:leftHeader]; + +} + + +#pragma mark - Data + +- (void)loadHeaderData +{ + NSArray *subviews = self.headerScrollView.subviews; + + for (UIView *subview in subviews) { + [subview removeFromSuperview]; + } + CGFloat x = 0.0; + CGFloat w = 0.0; + for (int i = 0; i < [self numberOfColumns] ; i++) { + w = [self contentWidthForColumn:i] + [self columnMargin]; + + FLEXTableColumnHeader *cell = [[FLEXTableColumnHeader alloc] initWithFrame:CGRectMake(x, 0, w, [self topHeaderHeight] - 1)]; + cell.label.text = [self columnTitleForColumn:i]; + [self.headerScrollView addSubview:cell]; + + FLEXTableColumnHeaderSortType type = [self.sortStatusDict[[self columnTitleForColumn:i]] integerValue]; + [cell changeSortStatusWithType:type]; + + UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(contentHeaderTap:)]; + [cell addGestureRecognizer:gesture]; + cell.userInteractionEnabled = YES; + + x = x + w; + } +} + +- (void)contentHeaderTap:(UIGestureRecognizer *)gesture +{ + FLEXTableColumnHeader *header = (FLEXTableColumnHeader *)gesture.view; + NSString *string = header.label.text; + FLEXTableColumnHeaderSortType currentType = [self.sortStatusDict[string] integerValue]; + FLEXTableColumnHeaderSortType newType ; + + switch (currentType) { + case FLEXTableColumnHeaderSortTypeNone: + newType = FLEXTableColumnHeaderSortTypeAsc; + break; + case FLEXTableColumnHeaderSortTypeAsc: + newType = FLEXTableColumnHeaderSortTypeDesc; + break; + case FLEXTableColumnHeaderSortTypeDesc: + newType = FLEXTableColumnHeaderSortTypeAsc; + break; + } + + self.sortStatusDict = @{header.label.text : @(newType)}; + [header changeSortStatusWithType:newType]; + [self.delegate multiColumnTableView:self didTapHeaderWithText:string sortType:newType]; + +} + +- (void)loadContentData +{ + [self.contentTableView reloadData]; +} + +- (void)loadLeftViewData +{ + [self.leftTableView reloadData]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UIColor *backgroundColor = [UIColor whiteColor]; + if (indexPath.row % 2 != 0) { + backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.750]; + } + + if (tableView != self.leftTableView) { + self.rowData = [self.dataSource contentAtRow:indexPath.row]; + FLEXTableContentCell *cell = [FLEXTableContentCell cellWithTableView:tableView + columnNumber:[self numberOfColumns]]; + cell.contentView.backgroundColor = backgroundColor; + cell.delegate = self; + + for (int i = 0 ; i < cell.labels.count; i++) { + + UILabel *label = cell.labels[i]; + label.textColor = [UIColor blackColor]; + + NSString *content = [NSString stringWithFormat:@"%@",self.rowData[i]]; + if ([content isEqualToString:@""]) { + label.textColor = [UIColor lightGrayColor]; + content = @"NULL"; + } + label.text = content; + label.backgroundColor = backgroundColor; + } + return cell; + } + else { + FLEXTableLeftCell *cell = [FLEXTableLeftCell cellWithTableView:tableView]; + cell.contentView.backgroundColor = backgroundColor; + cell.titlelabel.text = [self rowTitleForRow:indexPath.row]; + return cell; + } +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.dataSource numberOfRowsInTableView:self]; +} + + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return [self.dataSource multiColumnTableView:self heightForContentCellInRow:indexPath.row]; +} + + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + if (scrollView == self.contentScrollView) { + self.headerScrollView.contentOffset = scrollView.contentOffset; + } + else if (scrollView == self.headerScrollView) { + self.contentScrollView.contentOffset = scrollView.contentOffset; + } + else if (scrollView == self.leftTableView) { + self.contentTableView.contentOffset = scrollView.contentOffset; + } + else if (scrollView == self.contentTableView) { + self.leftTableView.contentOffset = scrollView.contentOffset; + } +} + +#pragma mark - +#pragma mark UITableView Delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (tableView == self.leftTableView) { + [self.contentTableView selectRowAtIndexPath:indexPath + animated:NO + scrollPosition:UITableViewScrollPositionNone]; + } + else if (tableView == self.contentTableView) { + [self.leftTableView selectRowAtIndexPath:indexPath + animated:NO + scrollPosition:UITableViewScrollPositionNone]; + } +} + +#pragma mark - +#pragma mark DataSource Accessor + +- (NSInteger)numberOfrows +{ + return [self.dataSource numberOfRowsInTableView:self]; +} + +- (NSInteger)numberOfColumns +{ + return [self.dataSource numberOfColumnsInTableView:self]; +} + +- (NSString *)columnTitleForColumn:(NSInteger)column +{ + return [self.dataSource columnNameInColumn:column]; +} + +- (NSString *)rowTitleForRow:(NSInteger)row +{ + return [self.dataSource rowNameInRow:row]; +} + +- (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row; +{ + return [self.dataSource contentAtColumn:column row:row]; +} + +- (CGFloat)contentWidthForColumn:(NSInteger)column +{ + return [self.dataSource multiColumnTableView:self widthForContentCellInColumn:column]; +} + +- (CGFloat)contentHeightForRow:(NSInteger)row +{ + return [self.dataSource multiColumnTableView:self heightForContentCellInRow:row]; +} + +- (CGFloat)topHeaderHeight +{ + return [self.dataSource heightForTopHeaderInTableView:self]; +} + +- (CGFloat)leftHeaderWidth +{ + return [self.dataSource widthForLeftHeaderInTableView:self]; +} + +- (CGFloat)columnMargin +{ + return kColumnMargin; +} + + +- (void)tableContentCell:(FLEXTableContentCell *)tableView labelDidTapWithText:(NSString *)text +{ + [self.delegate multiColumnTableView:self didTapLabelWithText:text]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h new file mode 100755 index 0000000..44c78fb --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h @@ -0,0 +1,14 @@ +// +// FLEXRealmDatabaseManager.h +// FLEX +// +// Created by Tim Oliver on 28/01/2016. +// Copyright © 2016 Realm. All rights reserved. +// + +#import +#import "FLEXDatabaseManager.h" + +@interface FLEXRealmDatabaseManager : NSObject + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m new file mode 100755 index 0000000..f239a41 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m @@ -0,0 +1,114 @@ +// +// FLEXRealmDatabaseManager.m +// FLEX +// +// Created by Tim Oliver on 28/01/2016. +// Copyright © 2016 Realm. All rights reserved. +// + +#import "FLEXRealmDatabaseManager.h" + +#if __has_include() +#import +#import +#else +#import "FLEXRealmDefines.h" +#endif + +@interface FLEXRealmDatabaseManager () + +@property (nonatomic, copy) NSString *path; +@property (nonatomic, strong) id realm; + +@end + +//#endif + +@implementation FLEXRealmDatabaseManager + +- (instancetype)initWithPath:(NSString*)aPath +{ + Class realmClass = NSClassFromString(@"RLMRealm"); + if (realmClass == nil) { + return nil; + } + + self = [super init]; + + if (self) { + _path = aPath; + } + return self; +} + +- (BOOL)open +{ + Class realmClass = NSClassFromString(@"RLMRealm"); + Class configurationClass = NSClassFromString(@"RLMRealmConfiguration"); + + if (realmClass == nil || configurationClass == nil) { + return NO; + } + + NSError *error = nil; + id configuration = [[configurationClass alloc] init]; + [(RLMRealmConfiguration *)configuration setFileURL:[NSURL fileURLWithPath:self.path]]; + self.realm = [realmClass realmWithConfiguration:configuration error:&error]; + return (error == nil); +} + +- (NSArray *)queryAllTables +{ + NSMutableArray *allTables = [NSMutableArray array]; + RLMSchema *schema = [self.realm schema]; + + for (RLMObjectSchema *objectSchema in schema.objectSchema) { + if (objectSchema.className == nil) { + continue; + } + + NSDictionary *dictionary = @{@"name":objectSchema.className}; + [allTables addObject:dictionary]; + } + + return allTables; +} + +- (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName +{ + RLMObjectSchema *objectSchema = [[self.realm schema] schemaForClassName:tableName]; + if (objectSchema == nil) { + return nil; + } + + NSMutableArray *columnNames = [NSMutableArray array]; + for (RLMProperty *property in objectSchema.properties) { + [columnNames addObject:property.name]; + } + + return columnNames; +} + +- (NSArray *)queryAllDataWithTableName:(NSString *)tableName +{ + RLMObjectSchema *objectSchema = [[self.realm schema] schemaForClassName:tableName]; + RLMResults *results = [self.realm allObjects:tableName]; + if (results.count == 0 || objectSchema == nil) { + return nil; + } + + NSMutableArray *allDataEntries = [NSMutableArray array]; + for (RLMObject *result in results) { + NSMutableDictionary *entry = [NSMutableDictionary dictionary]; + for (RLMProperty *property in objectSchema.properties) { + id value = [result valueForKey:property.name]; + entry[property.name] = (value) ? (value) : [NSNull null]; + } + + [allDataEntries addObject:entry]; + } + + return allDataEntries; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h new file mode 100755 index 0000000..2afbaab --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h @@ -0,0 +1,46 @@ +// +// Realm.h +// FLEX +// +// Created by Tim Oliver on 16/02/2016. +// Copyright © 2016 Realm. All rights reserved. +// + +#if __has_include() +#else + +@class RLMObject, RLMResults, RLMRealm, RLMRealmConfiguration, RLMSchema, RLMObjectSchema, RLMProperty; + +@interface RLMRealmConfiguration : NSObject +@property (nonatomic, copy) NSURL *fileURL; +@end + +@interface RLMRealm : NSObject +@property (nonatomic, readonly) RLMSchema *schema; ++ (RLMRealm *)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error; +- (RLMResults *)allObjects:(NSString *)className; +@end + +@interface RLMSchema : NSObject +@property (nonatomic, readonly) NSArray *objectSchema; +- (RLMObjectSchema *)schemaForClassName:(NSString *)className; +@end + +@interface RLMObjectSchema : NSObject +@property (nonatomic, readonly) NSString *className; +@property (nonatomic, readonly) NSArray *properties; +@end + +@interface RLMProperty : NSString +@property (nonatomic, readonly) NSString *name; +@end + +@interface RLMResults : NSObject +@property (nonatomic, readonly) NSInteger count; +@end + +@interface RLMObject : NSObject + +@end + +#endif \ No newline at end of file diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h new file mode 100755 index 0000000..9ab461b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h @@ -0,0 +1,19 @@ +// +// PTDatabaseManager.h +// Derived from: +// +// FMDatabase.h +// FMDB( https://github.com/ccgus/fmdb ) +// +// Created by Peng Tao on 15/11/23. +// +// Licensed to Flying Meat Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Flying Meat Inc. licenses this file to you. + +#import +#import "FLEXDatabaseManager.h" + +@interface FLEXSQLiteDatabaseManager : NSObject + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m new file mode 100755 index 0000000..2ddbce1 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m @@ -0,0 +1,190 @@ +// +// PTDatabaseManager.m +// PTDatabaseReader +// +// Created by Peng Tao on 15/11/23. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import "FLEXSQLiteDatabaseManager.h" +#import + + +static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"; + +@implementation FLEXSQLiteDatabaseManager +{ + sqlite3* _db; + NSString* _databasePath; +} + +- (instancetype)initWithPath:(NSString*)aPath +{ + self = [super init]; + + if (self) { + _databasePath = [aPath copy]; + } + return self; +} + +- (BOOL)open { + if (_db) { + return YES; + } + int err = sqlite3_open([_databasePath UTF8String], &_db); + if(err != SQLITE_OK) { + NSLog(@"error opening!: %d", err); + return NO; + } + return YES; +} + +- (BOOL)close { + if (!_db) { + return YES; + } + + int rc; + BOOL retry; + BOOL triedFinalizingOpenStatements = NO; + + do { + retry = NO; + rc = sqlite3_close(_db); + if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { + if (!triedFinalizingOpenStatements) { + triedFinalizingOpenStatements = YES; + sqlite3_stmt *pStmt; + while ((pStmt = sqlite3_next_stmt(_db, nil)) !=0) { + NSLog(@"Closing leaked statement"); + sqlite3_finalize(pStmt); + retry = YES; + } + } + } + else if (SQLITE_OK != rc) { + NSLog(@"error closing!: %d", rc); + } + } + while (retry); + + _db = nil; + return YES; +} + + +- (NSArray *)queryAllTables +{ + return [self executeQuery:QUERY_TABLENAMES_SQL]; +} + +- (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName +{ + NSString *sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')",tableName]; + NSArray *resultArray = [self executeQuery:sql]; + NSMutableArray *array = [NSMutableArray array]; + for (NSDictionary *dict in resultArray) { + [array addObject:dict[@"name"]]; + } + return array; +} + +- (NSArray *)queryAllDataWithTableName:(NSString *)tableName +{ + NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@",tableName]; + return [self executeQuery:sql]; +} + +#pragma mark - +#pragma mark - Private + +- (NSArray *)executeQuery:(NSString *)sql +{ + [self open]; + NSMutableArray *resultArray = [NSMutableArray array]; + sqlite3_stmt *pstmt; + if (sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pstmt, 0) == SQLITE_OK) { + while (sqlite3_step(pstmt) == SQLITE_ROW) { + NSUInteger num_cols = (NSUInteger)sqlite3_data_count(pstmt); + if (num_cols > 0) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols]; + + int columnCount = sqlite3_column_count(pstmt); + + int columnIdx = 0; + for (columnIdx = 0; columnIdx < columnCount; columnIdx++) { + + NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name(pstmt, columnIdx)]; + id objectValue = [self objectForColumnIndex:columnIdx stmt:pstmt]; + [dict setObject:objectValue forKey:columnName]; + } + [resultArray addObject:dict]; + } + } + } + [self close]; + return resultArray; +} + + +- (id)objectForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt*)stmt { + int columnType = sqlite3_column_type(stmt, columnIdx); + + id returnValue = nil; + + if (columnType == SQLITE_INTEGER) { + returnValue = [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, columnIdx)]; + } + else if (columnType == SQLITE_FLOAT) { + returnValue = [NSNumber numberWithDouble:sqlite3_column_double(stmt, columnIdx)]; + } + else if (columnType == SQLITE_BLOB) { + returnValue = [self dataForColumnIndex:columnIdx stmt:stmt]; + } + else { + //default to a string for everything else + returnValue = [self stringForColumnIndex:columnIdx stmt:stmt]; + } + + if (returnValue == nil) { + returnValue = [NSNull null]; + } + + return returnValue; +} + +- (NSString *)stringForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt { + + if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) { + return nil; + } + + const char *c = (const char *)sqlite3_column_text(stmt, columnIdx); + + if (!c) { + // null row. + return nil; + } + + return [NSString stringWithUTF8String:c]; +} + +- (NSData *)dataForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt{ + + if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) { + return nil; + } + + const char *dataBuffer = sqlite3_column_blob(stmt, columnIdx); + int dataSize = sqlite3_column_bytes(stmt, columnIdx); + + if (dataBuffer == NULL) { + return nil; + } + + return [NSData dataWithBytes:(const void *)dataBuffer length:(NSUInteger)dataSize]; +} + + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h new file mode 100755 index 0000000..bded1e2 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h @@ -0,0 +1,24 @@ +// +// FLEXTableContentHeaderCell.h +// UICatalog +// +// Created by Peng Tao on 15/11/26. +// Copyright © 2015年 f. All rights reserved. +// + +#import + +typedef NS_ENUM(NSUInteger, FLEXTableColumnHeaderSortType) { + FLEXTableColumnHeaderSortTypeNone = 0, + FLEXTableColumnHeaderSortTypeAsc, + FLEXTableColumnHeaderSortTypeDesc, +}; + +@interface FLEXTableColumnHeader : UIView + +@property (nonatomic, strong) UILabel *label; + +- (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type; + +@end + diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m new file mode 100755 index 0000000..591cdd9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m @@ -0,0 +1,60 @@ +// +// FLEXTableContentHeaderCell.m +// UICatalog +// +// Created by Peng Tao on 15/11/26. +// Copyright © 2015年 f. All rights reserved. +// + +#import "FLEXTableColumnHeader.h" + +@implementation FLEXTableColumnHeader +{ + UILabel *_arrowLabel; +} + + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor whiteColor]; + + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, frame.size.width - 25, frame.size.height)]; + label.font = [UIFont systemFontOfSize:13.0]; + [self addSubview:label]; + self.label = label; + + + _arrowLabel = [[UILabel alloc] initWithFrame:CGRectMake(frame.size.width - 20, 0, 20, frame.size.height)]; + _arrowLabel.font = [UIFont systemFontOfSize:13.0]; + [self addSubview:_arrowLabel]; + + UIView *line = [[UIView alloc] initWithFrame:CGRectMake(frame.size.width - 1, 2, 1, frame.size.height - 4)]; + line.backgroundColor = [UIColor colorWithWhite:0.803 alpha:0.850]; + [self addSubview:line]; + + } + return self; +} + +- (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type +{ + switch (type) { + case FLEXTableColumnHeaderSortTypeNone: + _arrowLabel.text = @""; + break; + case FLEXTableColumnHeaderSortTypeAsc: + _arrowLabel.text = @"⬆️"; + break; + case FLEXTableColumnHeaderSortTypeDesc: + _arrowLabel.text = @"⬇️"; + break; + } +} + + + + + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.h new file mode 100755 index 0000000..b95a28c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.h @@ -0,0 +1,27 @@ +// +// FLEXTableContentCell.h +// UICatalog +// +// Created by Peng Tao on 15/11/24. +// Copyright © 2015年 f. All rights reserved. +// + +#import + +@class FLEXTableContentCell; +@protocol FLEXTableContentCellDelegate + +@optional +- (void)tableContentCell:(FLEXTableContentCell *)tableView labelDidTapWithText:(NSString *)text; + +@end + +@interface FLEXTableContentCell : UITableViewCell + +@property (nonatomic, strong)NSArray *labels; + +@property (nonatomic, weak) iddelegate; + ++ (instancetype)cellWithTableView:(UITableView *)tableView columnNumber:(NSInteger)number; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m new file mode 100755 index 0000000..b3aaaaf --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m @@ -0,0 +1,66 @@ +// +// FLEXTableContentCell.m +// UICatalog +// +// Created by Peng Tao on 15/11/24. +// Copyright © 2015年 f. All rights reserved. +// + +#import "FLEXTableContentCell.h" +#import "FLEXMultiColumnTableView.h" + +@interface FLEXTableContentCell () + +@end + +@implementation FLEXTableContentCell + ++ (instancetype)cellWithTableView:(UITableView *)tableView columnNumber:(NSInteger)number; +{ + static NSString *identifier = @"FLEXTableContentCell"; + FLEXTableContentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; + if (!cell) { + cell = [[FLEXTableContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + NSMutableArray *labels = [NSMutableArray array]; + for (int i = 0; i < number ; i++) { + UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; + label.backgroundColor = [UIColor whiteColor]; + label.font = [UIFont systemFontOfSize:13.0]; + label.textAlignment = NSTextAlignmentLeft; + label.backgroundColor = [UIColor greenColor]; + [labels addObject:label]; + + UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:cell + action:@selector(labelDidTap:)]; + [label addGestureRecognizer:gesture]; + label.userInteractionEnabled = YES; + + [cell.contentView addSubview:label]; + cell.contentView.backgroundColor = [UIColor whiteColor]; + } + cell.labels = labels; + } + return cell; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + CGFloat labelWidth = self.contentView.frame.size.width / self.labels.count; + CGFloat labelHeight = self.contentView.frame.size.height; + for (int i = 0; i < self.labels.count; i++) { + UILabel *label = self.labels[i]; + label.frame = CGRectMake(labelWidth * i + 5, 0, (labelWidth - 10), labelHeight); + } +} + + +- (void)labelDidTap:(UIGestureRecognizer *)gesture +{ + UILabel *label = (UILabel *)gesture.view; + if ([self.delegate respondsToSelector:@selector(tableContentCell:labelDidTapWithText:)]) { + [self.delegate tableContentCell:self labelDidTapWithText:label.text]; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h new file mode 100755 index 0000000..9bb481c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h @@ -0,0 +1,16 @@ +// +// PTTableContentViewController.h +// PTDatabaseReader +// +// Created by Peng Tao on 15/11/23. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import + +@interface FLEXTableContentViewController : UIViewController + +@property (nonatomic, strong) NSArray *columnsArray; +@property (nonatomic, strong) NSArray *contentsArray; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m new file mode 100755 index 0000000..5651a0a --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m @@ -0,0 +1,184 @@ +// +// PTTableContentViewController.m +// PTDatabaseReader +// +// Created by Peng Tao on 15/11/23. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import "FLEXTableContentViewController.h" +#import "FLEXMultiColumnTableView.h" +#import "FLEXWebViewController.h" + + +@interface FLEXTableContentViewController () + +@property (nonatomic, strong)FLEXMultiColumnTableView *multiColumView; + +@end + +@implementation FLEXTableContentViewController + +- (instancetype)init +{ + self = [super init]; + if (self) { + + CGRect rectStatus = [UIApplication sharedApplication].statusBarFrame; + CGFloat y = 64; + if (rectStatus.size.height == 0) { + y = 32; + } + _multiColumView = [[FLEXMultiColumnTableView alloc] initWithFrame: + CGRectMake(0, y, self.view.frame.size.width, self.view.frame.size.height - y)]; + + _multiColumView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _multiColumView.backgroundColor = [UIColor whiteColor]; + _multiColumView.dataSource = self; + _multiColumView.delegate = self; + self.automaticallyAdjustsScrollViewInsets = NO; + + + [self.view addSubview:_multiColumView]; + } + return self; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self.multiColumView reloadData]; + +} + +#pragma mark - +#pragma mark MultiColumnTableView DataSource + +- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView +{ + return self.columnsArray.count; +} +- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView +{ + return self.contentsArray.count; +} + + +- (NSString *)columnNameInColumn:(NSInteger)column +{ + return self.columnsArray[column]; +} + + +- (NSString *)rowNameInRow:(NSInteger)row +{ + return [NSString stringWithFormat:@"%ld",(long)row]; +} + +- (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row +{ + if (self.contentsArray.count > row) { + NSDictionary *dic = self.contentsArray[row]; + if (self.contentsArray.count > column) { + return [NSString stringWithFormat:@"%@",[dic objectForKey:self.columnsArray[column]]]; + } + } + return @""; +} + +- (NSArray *)contentAtRow:(NSInteger)row +{ + NSMutableArray *result = [NSMutableArray array]; + if (self.contentsArray.count > row) { + NSDictionary *dic = self.contentsArray[row]; + for (int i = 0; i < self.columnsArray.count; i ++) { + [result addObject:dic[self.columnsArray[i]]]; + } + return result; + } + return nil; +} + +- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView + heightForContentCellInRow:(NSInteger)row +{ + return 40; +} + +- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView + widthForContentCellInColumn:(NSInteger)column +{ + return 120; +} + +- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView +{ + return 40; +} + +- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView +{ + NSString *str = [NSString stringWithFormat:@"%lu",(unsigned long)self.contentsArray.count]; + NSDictionary *attrs = @{@"NSFontAttributeName":[UIFont systemFontOfSize:17.0]}; + CGSize size = [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 14) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:attrs context:nil].size; + return size.width + 20; +} + +#pragma mark - +#pragma mark MultiColumnTableView Delegate + + +- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapLabelWithText:(NSString *)text +{ + FLEXWebViewController * detailViewController = [[FLEXWebViewController alloc] initWithText:text]; + [self.navigationController pushViewController:detailViewController animated:YES]; +} + +- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapHeaderWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)sortType +{ + + NSArray *sortContentData = [self.contentsArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { + + if ([obj1 objectForKey:text] == [NSNull null]) { + return NSOrderedAscending; + } + if ([obj2 objectForKey:text] == [NSNull null]) { + return NSOrderedDescending; + } + NSComparisonResult result = [[obj1 objectForKey:text] compare:[obj2 objectForKey:text]]; + + return result; + }]; + if (sortType == FLEXTableColumnHeaderSortTypeDesc) { + NSEnumerator *contentReverseEvumerator = [sortContentData reverseObjectEnumerator]; + sortContentData = [NSArray arrayWithArray:[contentReverseEvumerator allObjects]]; + } + + self.contentsArray = sortContentData; + [self.multiColumView reloadData]; +} + +#pragma mark - +#pragma mark About Transition + +- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection + withTransitionCoordinator:(id )coordinator +{ + [super willTransitionToTraitCollection:newCollection + withTransitionCoordinator:coordinator]; + [coordinator animateAlongsideTransition:^(id context) { + if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) { + + _multiColumView.frame = CGRectMake(0, 32, self.view.frame.size.width, self.view.frame.size.height - 32); + } + else { + _multiColumView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64); + } + [self.view setNeedsLayout]; + } completion:nil]; +} + + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h new file mode 100755 index 0000000..3ec4a01 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h @@ -0,0 +1,17 @@ +// +// FLEXTableLeftCell.h +// UICatalog +// +// Created by Peng Tao on 15/11/24. +// Copyright © 2015年 f. All rights reserved. +// + +#import + +@interface FLEXTableLeftCell : UITableViewCell + +@property (nonatomic, strong) UILabel *titlelabel; + ++ (instancetype)cellWithTableView:(UITableView *)tableView; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m new file mode 100755 index 0000000..a1a73e5 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m @@ -0,0 +1,35 @@ +// +// FLEXTableLeftCell.m +// UICatalog +// +// Created by Peng Tao on 15/11/24. +// Copyright © 2015年 f. All rights reserved. +// + +#import "FLEXTableLeftCell.h" + +@implementation FLEXTableLeftCell + ++ (instancetype)cellWithTableView:(UITableView *)tableView +{ + static NSString *identifier = @"FLEXTableLeftCell"; + FLEXTableLeftCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; + + if (!cell) { + cell = [[FLEXTableLeftCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + textLabel.textAlignment = NSTextAlignmentCenter; + textLabel.font = [UIFont systemFontOfSize:13.0]; + textLabel.backgroundColor = [UIColor clearColor]; + [cell.contentView addSubview:textLabel]; + cell.titlelabel = textLabel; + } + return cell; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + self.titlelabel.frame = self.contentView.frame; +} +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h new file mode 100755 index 0000000..0a63316 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h @@ -0,0 +1,16 @@ +// +// PTTableListViewController.h +// PTDatabaseReader +// +// Created by Peng Tao on 15/11/23. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import + +@interface FLEXTableListViewController : UITableViewController + ++ (BOOL)supportsExtension:(NSString *)extension; +- (instancetype)initWithPath:(NSString *)path; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m new file mode 100755 index 0000000..5b64446 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m @@ -0,0 +1,136 @@ +// +// PTTableListViewController.m +// PTDatabaseReader +// +// Created by Peng Tao on 15/11/23. +// Copyright © 2015年 Peng Tao. All rights reserved. +// + +#import "FLEXTableListViewController.h" + +#import "FLEXDatabaseManager.h" +#import "FLEXSQLiteDatabaseManager.h" +#import "FLEXRealmDatabaseManager.h" + +#import "FLEXTableContentViewController.h" + +@interface FLEXTableListViewController () +{ + id _dbm; + NSString *_databasePath; +} + +@property (nonatomic, strong) NSArray *tables; + ++ (NSArray *)supportedSQLiteExtensions; ++ (NSArray *)supportedRealmExtensions; + +@end + +@implementation FLEXTableListViewController + +- (instancetype)initWithPath:(NSString *)path +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self) { + _databasePath = [path copy]; + _dbm = [self databaseManagerForFileAtPath:_databasePath]; + [_dbm open]; + [self getAllTables]; + } + return self; +} + +- (id)databaseManagerForFileAtPath:(NSString *)path +{ + NSString *pathExtension = path.pathExtension.lowercaseString; + + NSArray *sqliteExtensions = [FLEXTableListViewController supportedSQLiteExtensions]; + if ([sqliteExtensions indexOfObject:pathExtension] != NSNotFound) { + return [[FLEXSQLiteDatabaseManager alloc] initWithPath:path]; + } + + NSArray *realmExtensions = [FLEXTableListViewController supportedRealmExtensions]; + if (realmExtensions != nil && [realmExtensions indexOfObject:pathExtension] != NSNotFound) { + return [[FLEXRealmDatabaseManager alloc] initWithPath:path]; + } + + return nil; +} + +- (void)getAllTables +{ + NSArray *resultArray = [_dbm queryAllTables]; + NSMutableArray *array = [NSMutableArray array]; + for (NSDictionary *dict in resultArray) { + [array addObject:dict[@"name"]]; + } + self.tables = array; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.tables.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FLEXTableListViewControllerCell"]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:@"FLEXTableListViewControllerCell"]; + } + cell.textLabel.text = self.tables[indexPath.row]; + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXTableContentViewController *contentViewController = [[FLEXTableContentViewController alloc] init]; + + contentViewController.contentsArray = [_dbm queryAllDataWithTableName:self.tables[indexPath.row]]; + contentViewController.columnsArray = [_dbm queryAllColumnsWithTableName:self.tables[indexPath.row]]; + + contentViewController.title = self.tables[indexPath.row]; + [self.navigationController pushViewController:contentViewController animated:YES]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [NSString stringWithFormat:@"%lu tables", (unsigned long)self.tables.count]; +} + ++ (BOOL)supportsExtension:(NSString *)extension +{ + extension = extension.lowercaseString; + + NSArray *sqliteExtensions = [FLEXTableListViewController supportedSQLiteExtensions]; + if (sqliteExtensions.count > 0 && [sqliteExtensions indexOfObject:extension] != NSNotFound) { + return YES; + } + + NSArray *realmExtensions = [FLEXTableListViewController supportedRealmExtensions]; + if (realmExtensions.count > 0 && [realmExtensions indexOfObject:extension] != NSNotFound) { + return YES; + } + + return NO; +} + ++ (NSArray *)supportedSQLiteExtensions +{ + return @[@"db", @"sqlite", @"sqlite3"]; +} + ++ (NSArray *)supportedRealmExtensions +{ + if (NSClassFromString(@"RLMRealm") == nil) { + return nil; + } + + return @[@"realm"]; +} + +@end diff --git a/Pods/JSPatch/LICENSE b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/LICENSE old mode 100644 new mode 100755 similarity index 87% rename from Pods/JSPatch/LICENSE rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/LICENSE index fce58e4..fad3577 --- a/Pods/JSPatch/LICENSE +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/DatabaseBrowser/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) -Copyright (c) 2015 bang +FMDB +Copyright (c) 2008-2014 Flying Meat Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,14 +9,13 @@ 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 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. - +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/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.h new file mode 100755 index 0000000..0c00cc2 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.h @@ -0,0 +1,15 @@ +// +// FLEXClassesTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXClassesTableViewController : UITableViewController + +@property (nonatomic, copy) NSString *binaryImageName; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.m new file mode 100755 index 0000000..80e3fa4 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXClassesTableViewController.m @@ -0,0 +1,140 @@ +// +// FLEXClassesTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXClassesTableViewController.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXUtility.h" +#import + +@interface FLEXClassesTableViewController () + +@property (nonatomic, strong) NSArray *classNames; +@property (nonatomic, strong) NSArray *filteredClassNames; +@property (nonatomic, strong) UISearchBar *searchBar; + +@end + +@implementation FLEXClassesTableViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.searchBar = [[UISearchBar alloc] init]; + self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText]; + self.searchBar.delegate = self; + [self.searchBar sizeToFit]; + self.tableView.tableHeaderView = self.searchBar; +} + +- (void)setBinaryImageName:(NSString *)binaryImageName +{ + if (![_binaryImageName isEqual:binaryImageName]) { + _binaryImageName = binaryImageName; + [self loadClassNames]; + [self updateTitle]; + } +} + +- (void)setClassNames:(NSArray *)classNames +{ + _classNames = classNames; + self.filteredClassNames = classNames; +} + +- (void)loadClassNames +{ + unsigned int classNamesCount = 0; + const char **classNames = objc_copyClassNamesForImage([self.binaryImageName UTF8String], &classNamesCount); + if (classNames) { + NSMutableArray *classNameStrings = [NSMutableArray array]; + for (unsigned int i = 0; i < classNamesCount; i++) { + const char *className = classNames[i]; + NSString *classNameString = [NSString stringWithUTF8String:className]; + [classNameStrings addObject:classNameString]; + } + + self.classNames = [classNameStrings sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + + free(classNames); + } +} + +- (void)updateTitle +{ + NSString *shortImageName = self.binaryImageName.lastPathComponent; + self.title = [NSString stringWithFormat:@"%@ Classes (%lu)", shortImageName, (unsigned long)[self.filteredClassNames count]]; +} + + +#pragma mark - Search + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText +{ + if ([searchText length] > 0) { + NSPredicate *searchPreidcate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchText]; + self.filteredClassNames = [self.classNames filteredArrayUsingPredicate:searchPreidcate]; + } else { + self.filteredClassNames = self.classNames; + } + [self updateTitle]; + [self.tableView reloadData]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + // Dismiss the keyboard when interacting with filtered results. + [self.searchBar endEditing:YES]; +} + + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.filteredClassNames count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + } + + cell.textLabel.text = self.filteredClassNames[indexPath.row]; + + return cell; +} + + +#pragma mark - Table View Delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString *className = self.filteredClassNames[indexPath.row]; + Class selectedClass = objc_getClass([className UTF8String]); + FLEXObjectExplorerViewController *objectExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:selectedClass]; + [self.navigationController pushViewController:objectExplorer animated:YES]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.h new file mode 100755 index 0000000..09c5865 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXCookiesTableViewController.h +// FLEX +// +// Created by Rich Robinson on 19/10/2015. +// Copyright © 2015 Flipboard. All rights reserved. +// + +#import + +@interface FLEXCookiesTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.m new file mode 100755 index 0000000..d7e87ce --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXCookiesTableViewController.m @@ -0,0 +1,71 @@ +// +// FLEXCookiesTableViewController.m +// FLEX +// +// Created by Rich Robinson on 19/10/2015. +// Copyright © 2015 Flipboard. All rights reserved. +// + +#import "FLEXCookiesTableViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXUtility.h" + +@interface FLEXCookiesTableViewController () + +@property (nonatomic, strong) NSArray *cookies; + +@end + +@implementation FLEXCookiesTableViewController + +- (id)initWithStyle:(UITableViewStyle)style { + self = [super initWithStyle:style]; + + if (self) { + self.title = @"Cookies"; + + NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)]; + _cookies =[[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies sortedArrayUsingDescriptors:@[nameSortDescriptor]]; + } + + return self; +} + +- (NSHTTPCookie *)cookieForRowAtIndexPath:(NSIndexPath *)indexPath { + return self.cookies[indexPath.row]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.cookies.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + cell.detailTextLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + cell.detailTextLabel.textColor = [UIColor grayColor]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + + NSHTTPCookie *cookie = [self cookieForRowAtIndexPath:indexPath]; + cell.textLabel.text = [NSString stringWithFormat:@"%@ (%@)", cookie.name, cookie.value]; + cell.detailTextLabel.text = cookie.domain; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSHTTPCookie *cookie = [self cookieForRowAtIndexPath:indexPath]; + UIViewController *cookieViewController = (UIViewController *)[FLEXObjectExplorerFactory explorerViewControllerForObject:cookie]; + + [self.navigationController pushViewController:cookieViewController animated:YES]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.h new file mode 100755 index 0000000..79ff114 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.h @@ -0,0 +1,33 @@ +// +// FLEXFileBrowserFileOperationController.h +// Flipboard +// +// Created by Daniel Rodriguez Troitino on 2/13/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import + +@protocol FLEXFileBrowserFileOperationController; + +@protocol FLEXFileBrowserFileOperationControllerDelegate + +- (void)fileOperationControllerDidDismiss:(id)controller; + +@end + +@protocol FLEXFileBrowserFileOperationController + +@property (nonatomic, weak) id delegate; + +- (instancetype)initWithPath:(NSString *)path; + +- (void)show; + +@end + +@interface FLEXFileBrowserFileDeleteOperationController : NSObject +@end + +@interface FLEXFileBrowserFileRenameOperationController : NSObject +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.m new file mode 100755 index 0000000..4ed48f9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserFileOperationController.m @@ -0,0 +1,142 @@ +// +// FLEXFileBrowserFileOperationController.m +// Flipboard +// +// Created by Daniel Rodriguez Troitino on 2/13/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXFileBrowserFileOperationController.h" +#import + +@interface FLEXFileBrowserFileDeleteOperationController () + +@property (nonatomic, copy, readonly) NSString *path; + +- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FLEXFileBrowserFileDeleteOperationController + +@synthesize delegate = _delegate; + +- (instancetype)init +{ + return [self initWithPath:nil]; +} + +- (instancetype)initWithPath:(NSString *)path +{ + self = [super init]; + if (self) { + _path = path; + } + + return self; +} + +- (void)show +{ + BOOL isDirectory = NO; + BOOL stillExists = [[NSFileManager defaultManager] fileExistsAtPath:self.path isDirectory:&isDirectory]; + + if (stillExists) { + UIAlertView *deleteWarning = [[UIAlertView alloc] + initWithTitle:[NSString stringWithFormat:@"Delete %@?", self.path.lastPathComponent] + message:[NSString stringWithFormat:@"The %@ will be deleted. This operation cannot be undone", isDirectory ? @"directory" : @"file"] + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:@"Delete", nil]; + [deleteWarning show]; + } else { + [[[UIAlertView alloc] initWithTitle:@"File Removed" message:@"The file at the specified path no longer exists." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } +} + +#pragma mark - UIAlertViewDelegate + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == alertView.cancelButtonIndex) { + // Nothing, just cancel + } else if (buttonIndex == alertView.firstOtherButtonIndex) { + [[NSFileManager defaultManager] removeItemAtPath:self.path error:NULL]; + } +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [self.delegate fileOperationControllerDidDismiss:self]; +} + +@end + +@interface FLEXFileBrowserFileRenameOperationController () + +@property (nonatomic, copy, readonly) NSString *path; + +- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FLEXFileBrowserFileRenameOperationController + +@synthesize delegate = _delegate; + +- (instancetype)init +{ + return [self initWithPath:nil]; +} + +- (instancetype)initWithPath:(NSString *)path +{ + self = [super init]; + if (self) { + _path = path; + } + + return self; +} + +- (void)show +{ + BOOL isDirectory = NO; + BOOL stillExists = [[NSFileManager defaultManager] fileExistsAtPath:self.path isDirectory:&isDirectory]; + + if (stillExists) { + UIAlertView *renameDialog = [[UIAlertView alloc] + initWithTitle:[NSString stringWithFormat:@"Rename %@?", self.path.lastPathComponent] + message:nil + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:@"Rename", nil]; + renameDialog.alertViewStyle = UIAlertViewStylePlainTextInput; + UITextField *textField = [renameDialog textFieldAtIndex:0]; + textField.placeholder = @"New file name"; + textField.text = self.path.lastPathComponent; + [renameDialog show]; + } else { + [[[UIAlertView alloc] initWithTitle:@"File Removed" message:@"The file at the specified path no longer exists." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } +} + +#pragma mark - UIAlertViewDelegate + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == alertView.cancelButtonIndex) { + // Nothing, just cancel + } else if (buttonIndex == alertView.firstOtherButtonIndex) { + NSString *newFileName = [alertView textFieldAtIndex:0].text; + NSString *newPath = [[self.path stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFileName]; + [[NSFileManager defaultManager] moveItemAtPath:self.path toPath:newPath error:NULL]; + } +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [self.delegate fileOperationControllerDidDismiss:self]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.h new file mode 100755 index 0000000..24b7fa9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.h @@ -0,0 +1,25 @@ +// +// FLEXFileBrowserSearchOperation.h +// UICatalog +// +// Created by 啟倫 陳 on 2014/8/4. +// Copyright (c) 2014年 f. All rights reserved. +// + +#import + +@protocol FLEXFileBrowserSearchOperationDelegate; + +@interface FLEXFileBrowserSearchOperation : NSOperation + +@property (nonatomic, weak) id delegate; + +- (id)initWithPath:(NSString *)currentPath searchString:(NSString *)searchString; + +@end + +@protocol FLEXFileBrowserSearchOperationDelegate + +- (void)fileBrowserSearchOperationResult:(NSArray *)searchResult size:(uint64_t)size; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.m new file mode 100755 index 0000000..1b99f43 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserSearchOperation.m @@ -0,0 +1,123 @@ +// +// FLEXFileBrowserSearchOperation.m +// UICatalog +// +// Created by 啟倫 陳 on 2014/8/4. +// Copyright (c) 2014年 f. All rights reserved. +// + +#import "FLEXFileBrowserSearchOperation.h" + +@implementation NSMutableArray (FLEXStack) + +- (void)flex_push:(id)anObject +{ + [self addObject:anObject]; +} + +- (id)flex_pop +{ + id anObject = [self lastObject]; + [self removeLastObject]; + return anObject; +} + +@end + +@interface FLEXFileBrowserSearchOperation () + +@property (nonatomic, strong) NSString *path; +@property (nonatomic, strong) NSString *searchString; + +@end + +@implementation FLEXFileBrowserSearchOperation + +#pragma mark - private + +- (uint64_t)totalSizeAtPath:(NSString *)path +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:NULL]; + uint64_t totalSize = [attributes fileSize]; + + for (NSString *fileName in [fileManager enumeratorAtPath:path]) { + attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL]; + totalSize += [attributes fileSize]; + } + return totalSize; +} + +#pragma mark - instance method + +- (id)initWithPath:(NSString *)currentPath searchString:(NSString *)searchString +{ + self = [super init]; + if (self) { + self.path = currentPath; + self.searchString = searchString; + } + return self; +} + +#pragma mark - methods to override + +- (void)main +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSMutableArray *searchPaths = [NSMutableArray array]; + NSMutableDictionary *sizeMapping = [NSMutableDictionary dictionary]; + uint64_t totalSize = 0; + NSMutableArray *stack = [NSMutableArray array]; + [stack flex_push:self.path]; + + //recursive found all match searchString paths, and precomputing there size + while ([stack count]) { + NSString *currentPath = [stack flex_pop]; + NSArray *directoryPath = [fileManager contentsOfDirectoryAtPath:currentPath error:nil]; + + for (NSString *subPath in directoryPath) { + NSString *fullPath = [currentPath stringByAppendingPathComponent:subPath]; + + if ([[subPath lowercaseString] rangeOfString:[self.searchString lowercaseString]].location != NSNotFound) { + [searchPaths addObject:fullPath]; + if (!sizeMapping[fullPath]) { + uint64_t fullPathSize = [self totalSizeAtPath:fullPath]; + totalSize += fullPathSize; + [sizeMapping setObject:@(fullPathSize) forKey:fullPath]; + } + } + BOOL isDirectory; + if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDirectory] && isDirectory) { + [stack flex_push:fullPath]; + } + + if ([self isCancelled]) { + return; + } + } + } + + //sort + NSArray *sortedArray = [searchPaths sortedArrayUsingComparator:^NSComparisonResult(NSString *path1, NSString *path2) { + uint64_t pathSize1 = [sizeMapping[path1] unsignedLongLongValue]; + uint64_t pathSize2 = [sizeMapping[path2] unsignedLongLongValue]; + if (pathSize1 < pathSize2) { + return NSOrderedAscending; + } else if (pathSize1 > pathSize2) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } + }]; + + if ([self isCancelled]) { + return; + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [self.delegate fileBrowserSearchOperationResult:sortedArray size:totalSize]; + }); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.h new file mode 100755 index 0000000..7454e9d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.h @@ -0,0 +1,17 @@ +// +// FLEXFileBrowserTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/9/14. +// Based on previous work by Evan Doll +// + +#import + +#import "FLEXFileBrowserSearchOperation.h" + +@interface FLEXFileBrowserTableViewController : UITableViewController + +- (id)initWithPath:(NSString *)path; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.m new file mode 100755 index 0000000..6508bde --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXFileBrowserTableViewController.m @@ -0,0 +1,351 @@ +// +// FLEXFileBrowserTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/9/14. +// +// + +#import "FLEXFileBrowserTableViewController.h" +#import "FLEXFileBrowserFileOperationController.h" +#import "FLEXUtility.h" +#import "FLEXWebViewController.h" +#import "FLEXImagePreviewViewController.h" +#import "FLEXTableListViewController.h" + +@interface FLEXFileBrowserTableViewCell : UITableViewCell +@end + +@interface FLEXFileBrowserTableViewController () + +@property (nonatomic, copy) NSString *path; +@property (nonatomic, copy) NSArray *childPaths; +@property (nonatomic, strong) NSArray *searchPaths; +@property (nonatomic, strong) NSNumber *recursiveSize; +@property (nonatomic, strong) NSNumber *searchPathsSize; +@property (nonatomic, strong) UISearchController *searchController; +@property (nonatomic) NSOperationQueue *operationQueue; +@property (nonatomic, strong) UIDocumentInteractionController *documentController; +@property (nonatomic, strong) id fileOperationController; + +@end + +@implementation FLEXFileBrowserTableViewController + +- (id)initWithStyle:(UITableViewStyle)style +{ + return [self initWithPath:NSHomeDirectory()]; +} + +- (id)initWithPath:(NSString *)path +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self) { + self.path = path; + self.title = [path lastPathComponent]; + self.operationQueue = [NSOperationQueue new]; + + self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; + self.searchController.searchResultsUpdater = self; + self.searchController.delegate = self; + self.searchController.dimsBackgroundDuringPresentation = NO; + self.tableView.tableHeaderView = self.searchController.searchBar; + + //computing path size + FLEXFileBrowserTableViewController *__weak weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:NULL]; + uint64_t totalSize = [attributes fileSize]; + + for (NSString *fileName in [fileManager enumeratorAtPath:path]) { + attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL]; + totalSize += [attributes fileSize]; + + // Bail if the interested view controller has gone away. + if (!weakSelf) { + return; + } + } + + dispatch_async(dispatch_get_main_queue(), ^{ + FLEXFileBrowserTableViewController *__strong strongSelf = weakSelf; + strongSelf.recursiveSize = @(totalSize); + [strongSelf.tableView reloadData]; + }); + }); + + [self reloadChildPaths]; + } + return self; +} + +#pragma mark - UIViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + UIMenuItem *renameMenuItem = [[UIMenuItem alloc] initWithTitle:@"Rename" action:@selector(fileBrowserRename:)]; + UIMenuItem *deleteMenuItem = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(fileBrowserDelete:)]; + [UIMenuController sharedMenuController].menuItems = @[renameMenuItem, deleteMenuItem]; +} + +#pragma mark - FLEXFileBrowserSearchOperationDelegate + +- (void)fileBrowserSearchOperationResult:(NSArray *)searchResult size:(uint64_t)size +{ + self.searchPaths = searchResult; + self.searchPathsSize = @(size); + [self.tableView reloadData]; +} + +#pragma mark - UISearchResultsUpdating + +- (void)updateSearchResultsForSearchController:(UISearchController *)searchController +{ + [self reloadDisplayedPaths]; +} + +#pragma mark - UISearchControllerDelegate + +- (void)willDismissSearchController:(UISearchController *)searchController +{ + [self.operationQueue cancelAllOperations]; + [self reloadChildPaths]; + [self.tableView reloadData]; +} + + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.searchController.isActive ? [self.searchPaths count] : [self.childPaths count]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + BOOL isSearchActive = self.searchController.isActive; + NSNumber *currentSize = isSearchActive ? self.searchPathsSize : self.recursiveSize; + NSArray *currentPaths = isSearchActive ? self.searchPaths : self.childPaths; + + NSString *sizeString = nil; + if (!currentSize) { + sizeString = @"Computing size…"; + } else { + sizeString = [NSByteCountFormatter stringFromByteCount:[currentSize longLongValue] countStyle:NSByteCountFormatterCountStyleFile]; + } + + return [NSString stringWithFormat:@"%lu files (%@)", (unsigned long)[currentPaths count], sizeString]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString *fullPath = [self filePathAtIndexPath:indexPath]; + NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:NULL]; + BOOL isDirectory = [[attributes fileType] isEqual:NSFileTypeDirectory]; + NSString *subtitle = nil; + if (isDirectory) { + NSUInteger count = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:fullPath error:NULL] count]; + subtitle = [NSString stringWithFormat:@"%lu file%@", (unsigned long)count, (count == 1 ? @"" : @"s")]; + } else { + NSString *sizeString = [NSByteCountFormatter stringFromByteCount:[attributes fileSize] countStyle:NSByteCountFormatterCountStyleFile]; + subtitle = [NSString stringWithFormat:@"%@ - %@", sizeString, [attributes fileModificationDate]]; + } + + static NSString *textCellIdentifier = @"textCell"; + static NSString *imageCellIdentifier = @"imageCell"; + UITableViewCell *cell = nil; + + // Separate image and text only cells because otherwise the separator lines get out-of-whack on image cells reused with text only. + BOOL showImagePreview = [FLEXUtility isImagePathExtension:[fullPath pathExtension]]; + NSString *cellIdentifier = showImagePreview ? imageCellIdentifier : textCellIdentifier; + + if (!cell) { + cell = [[FLEXFileBrowserTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + cell.detailTextLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + cell.detailTextLabel.textColor = [UIColor grayColor]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + NSString *cellTitle = [fullPath lastPathComponent]; + cell.textLabel.text = cellTitle; + cell.detailTextLabel.text = subtitle; + + if (showImagePreview) { + cell.imageView.contentMode = UIViewContentModeScaleAspectFit; + cell.imageView.image = [UIImage imageWithContentsOfFile:fullPath]; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString *fullPath = [self filePathAtIndexPath:indexPath]; + NSString *subpath = [fullPath lastPathComponent]; + NSString *pathExtension = [subpath pathExtension]; + + BOOL isDirectory = NO; + BOOL stillExists = [[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory:&isDirectory]; + if (stillExists) { + UIViewController *drillInViewController = nil; + if (isDirectory) { + drillInViewController = [[[self class] alloc] initWithPath:fullPath]; + } else if ([FLEXUtility isImagePathExtension:pathExtension]) { + UIImage *image = [UIImage imageWithContentsOfFile:fullPath]; + drillInViewController = [[FLEXImagePreviewViewController alloc] initWithImage:image]; + } else { + // Special case keyed archives, json, and plists to get more readable data. + NSString *prettyString = nil; + if ([pathExtension isEqual:@"archive"] || [pathExtension isEqual:@"coded"]) { + prettyString = [[NSKeyedUnarchiver unarchiveObjectWithFile:fullPath] description]; + } else if ([pathExtension isEqualToString:@"json"]) { + prettyString = [FLEXUtility prettyJSONStringFromData:[NSData dataWithContentsOfFile:fullPath]]; + } else if ([pathExtension isEqualToString:@"plist"]) { + NSData *fileData = [NSData dataWithContentsOfFile:fullPath]; + prettyString = [[NSPropertyListSerialization propertyListWithData:fileData options:0 format:NULL error:NULL] description]; + } + + if ([prettyString length] > 0) { + drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString]; + } else if ([FLEXWebViewController supportsPathExtension:pathExtension]) { + drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]]; + } else if ([FLEXTableListViewController supportsExtension:subpath.pathExtension]) { + drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath]; + } + else { + NSString *fileString = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL]; + if ([fileString length] > 0) { + drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString]; + } + } + } + + if (drillInViewController) { + drillInViewController.title = [subpath lastPathComponent]; + [self.navigationController pushViewController:drillInViewController animated:YES]; + } else { + [self openFileController:fullPath]; + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + } + } else { + [[[UIAlertView alloc] initWithTitle:@"File Removed" message:@"The file at the specified path no longer exists." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + [self reloadDisplayedPaths]; + } +} + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return YES; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + return action == @selector(fileBrowserDelete:) || action == @selector(fileBrowserRename:); +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + // Empty, but has to exist for the menu to show + // The table view only calls this method for actions in the UIResponderStandardEditActions informal protocol. + // Since our actions are outside of that protocol, we need to manually handle the action forwarding from the cells. +} + +#pragma mark - FLEXFileBrowserFileOperationControllerDelegate + +- (void)fileOperationControllerDidDismiss:(id)controller +{ + [self reloadDisplayedPaths]; +} + +- (void)openFileController:(NSString *)fullPath +{ + UIDocumentInteractionController *controller = [UIDocumentInteractionController new]; + controller.URL = [[NSURL alloc] initFileURLWithPath:fullPath]; + + [controller presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES]; + self.documentController = controller; +} + +- (void)fileBrowserRename:(UITableViewCell *)sender +{ + NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; + NSString *fullPath = [self filePathAtIndexPath:indexPath]; + + self.fileOperationController = [[FLEXFileBrowserFileRenameOperationController alloc] initWithPath:fullPath]; + self.fileOperationController.delegate = self; + [self.fileOperationController show]; +} + +- (void)fileBrowserDelete:(UITableViewCell *)sender +{ + NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; + NSString *fullPath = [self filePathAtIndexPath:indexPath]; + + self.fileOperationController = [[FLEXFileBrowserFileDeleteOperationController alloc] initWithPath:fullPath]; + self.fileOperationController.delegate = self; + [self.fileOperationController show]; +} + +- (void)reloadDisplayedPaths +{ + if (self.searchController.isActive) { + [self reloadSearchPaths]; + } else { + [self reloadChildPaths]; + } + [self.tableView reloadData]; +} + +- (void)reloadChildPaths +{ + NSMutableArray *childPaths = [NSMutableArray array]; + NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.path error:NULL]; + for (NSString *subpath in subpaths) { + [childPaths addObject:[self.path stringByAppendingPathComponent:subpath]]; + } + self.childPaths = childPaths; +} + +- (void)reloadSearchPaths +{ + self.searchPaths = nil; + self.searchPathsSize = nil; + + //clear pre search request and start a new one + [self.operationQueue cancelAllOperations]; + FLEXFileBrowserSearchOperation *newOperation = [[FLEXFileBrowserSearchOperation alloc] initWithPath:self.path searchString:self.searchController.searchBar.text]; + newOperation.delegate = self; + [self.operationQueue addOperation:newOperation]; +} + +- (NSString *)filePathAtIndexPath:(NSIndexPath *)indexPath +{ + return self.searchController.isActive ? self.searchPaths[indexPath.row] : self.childPaths[indexPath.row]; +} + +@end + + +@implementation FLEXFileBrowserTableViewCell + +- (void)fileBrowserRename:(UIMenuController *)sender +{ + id target = [self.nextResponder targetForAction:_cmd withSender:sender]; + [[UIApplication sharedApplication] sendAction:_cmd to:target from:self forEvent:nil]; +} + +- (void)fileBrowserDelete:(UIMenuController *)sender +{ + id target = [self.nextResponder targetForAction:_cmd withSender:sender]; + [[UIApplication sharedApplication] sendAction:_cmd to:target from:self forEvent:nil]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.h new file mode 100755 index 0000000..a2fbe35 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.h @@ -0,0 +1,27 @@ +// +// FLEXGlobalsTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@protocol FLEXGlobalsTableViewControllerDelegate; + +@interface FLEXGlobalsTableViewController : UITableViewController + +@property (nonatomic, weak) id delegate; + +/// We pretend that one of the app's windows is still the key window, even though the explorer window may have become key. +/// We want to display debug state about the application, not about this tool. ++ (void)setApplicationWindow:(UIWindow *)applicationWindow; + +@end + +@protocol FLEXGlobalsTableViewControllerDelegate + +- (void)globalsViewControllerDidFinish:(FLEXGlobalsTableViewController *)globalsViewController; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.m new file mode 100755 index 0000000..2986643 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXGlobalsTableViewController.m @@ -0,0 +1,306 @@ +// +// FLEXGlobalsTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXGlobalsTableViewController.h" +#import "FLEXUtility.h" +#import "FLEXLibrariesTableViewController.h" +#import "FLEXClassesTableViewController.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXLiveObjectsTableViewController.h" +#import "FLEXFileBrowserTableViewController.h" +#import "FLEXCookiesTableViewController.h" +#import "FLEXGlobalsTableViewControllerEntry.h" +#import "FLEXManager+Private.h" +#import "FLEXSystemLogTableViewController.h" +#import "FLEXNetworkHistoryTableViewController.h" + +static __weak UIWindow *s_applicationWindow = nil; + +typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) { + FLEXGlobalsRowNetworkHistory, + FLEXGlobalsRowSystemLog, + FLEXGlobalsRowLiveObjects, + FLEXGlobalsRowFileBrowser, + FLEXGlobalsCookies, + FLEXGlobalsRowSystemLibraries, + FLEXGlobalsRowAppClasses, + FLEXGlobalsRowAppDelegate, + FLEXGlobalsRowRootViewController, + FLEXGlobalsRowUserDefaults, + FLEXGlobalsRowApplication, + FLEXGlobalsRowKeyWindow, + FLEXGlobalsRowMainScreen, + FLEXGlobalsRowCurrentDevice, + FLEXGlobalsRowCount +}; + +@interface FLEXGlobalsTableViewController () + +/// [FLEXGlobalsTableViewControllerEntry *] +@property (nonatomic, readonly, copy) NSArray *entries; + +@end + +@implementation FLEXGlobalsTableViewController + +/// [FLEXGlobalsTableViewControllerEntry *] ++ (NSArray *)defaultGlobalEntries +{ + NSMutableArray *defaultGlobalEntries = [NSMutableArray array]; + + for (FLEXGlobalsRow defaultRowIndex = 0; defaultRowIndex < FLEXGlobalsRowCount; defaultRowIndex++) { + FLEXGlobalsTableViewControllerEntryNameFuture titleFuture = nil; + FLEXGlobalsTableViewControllerViewControllerFuture viewControllerFuture = nil; + + switch (defaultRowIndex) { + case FLEXGlobalsRowAppClasses: + titleFuture = ^NSString *{ + return [NSString stringWithFormat:@"📕 %@ Classes", [FLEXUtility applicationName]]; + }; + viewControllerFuture = ^UIViewController *{ + FLEXClassesTableViewController *classesViewController = [[FLEXClassesTableViewController alloc] init]; + classesViewController.binaryImageName = [FLEXUtility applicationImageName]; + + return classesViewController; + }; + break; + + case FLEXGlobalsRowSystemLibraries: { + NSString *titleString = @"📚 System Libraries"; + titleFuture = ^NSString *{ + return titleString; + }; + viewControllerFuture = ^UIViewController *{ + FLEXLibrariesTableViewController *librariesViewController = [[FLEXLibrariesTableViewController alloc] init]; + librariesViewController.title = titleString; + + return librariesViewController; + }; + break; + } + + case FLEXGlobalsRowLiveObjects: + titleFuture = ^NSString *{ + return @"💩 Heap Objects"; + }; + viewControllerFuture = ^UIViewController *{ + return [[FLEXLiveObjectsTableViewController alloc] init]; + }; + + break; + + case FLEXGlobalsRowAppDelegate: + titleFuture = ^NSString *{ + return [NSString stringWithFormat:@"👉 %@", [[[UIApplication sharedApplication] delegate] class]]; + }; + viewControllerFuture = ^UIViewController *{ + id appDelegate = [[UIApplication sharedApplication] delegate]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:appDelegate]; + }; + break; + + case FLEXGlobalsRowRootViewController: + titleFuture = ^NSString *{ + return [NSString stringWithFormat:@"🌴 %@", [[s_applicationWindow rootViewController] class]]; + }; + viewControllerFuture = ^UIViewController *{ + UIViewController *rootViewController = [s_applicationWindow rootViewController]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:rootViewController]; + }; + break; + + case FLEXGlobalsRowUserDefaults: + titleFuture = ^NSString *{ + return @"🚶 +[NSUserDefaults standardUserDefaults]"; + }; + viewControllerFuture = ^UIViewController *{ + NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:standardUserDefaults]; + }; + break; + + case FLEXGlobalsRowApplication: + titleFuture = ^NSString *{ + return @"💾 +[UIApplication sharedApplication]"; + }; + viewControllerFuture = ^UIViewController *{ + UIApplication *sharedApplication = [UIApplication sharedApplication]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:sharedApplication]; + }; + break; + + case FLEXGlobalsRowKeyWindow: + titleFuture = ^NSString *{ + return @"🔑 -[UIApplication keyWindow]"; + }; + viewControllerFuture = ^UIViewController *{ + return [FLEXObjectExplorerFactory explorerViewControllerForObject:s_applicationWindow]; + }; + break; + + case FLEXGlobalsRowMainScreen: + titleFuture = ^NSString *{ + return @"💻 +[UIScreen mainScreen]"; + }; + viewControllerFuture = ^UIViewController *{ + UIScreen *mainScreen = [UIScreen mainScreen]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:mainScreen]; + }; + break; + + case FLEXGlobalsRowCurrentDevice: + titleFuture = ^NSString *{ + return @"📱 +[UIDevice currentDevice]"; + }; + viewControllerFuture = ^UIViewController *{ + UIDevice *currentDevice = [UIDevice currentDevice]; + return [FLEXObjectExplorerFactory explorerViewControllerForObject:currentDevice]; + }; + break; + + case FLEXGlobalsCookies: + titleFuture = ^NSString *{ + return @"🍪 Cookies"; + }; + viewControllerFuture = ^UIViewController *{ + return [[FLEXCookiesTableViewController alloc] init]; + }; + break; + + case FLEXGlobalsRowFileBrowser: + titleFuture = ^NSString *{ + return @"📁 File Browser"; + }; + viewControllerFuture = ^UIViewController *{ + return [[FLEXFileBrowserTableViewController alloc] init]; + }; + break; + + case FLEXGlobalsRowSystemLog: + titleFuture = ^{ + return @"⚠️ System Log"; + }; + viewControllerFuture = ^{ + return [[FLEXSystemLogTableViewController alloc] init]; + }; + break; + + case FLEXGlobalsRowNetworkHistory: + titleFuture = ^{ + return @"📡 Network History"; + }; + viewControllerFuture = ^{ + return [[FLEXNetworkHistoryTableViewController alloc] init]; + }; + break; + case FLEXGlobalsRowCount: + break; + } + + NSParameterAssert(titleFuture); + NSParameterAssert(viewControllerFuture); + + [defaultGlobalEntries addObject:[FLEXGlobalsTableViewControllerEntry entryWithNameFuture:titleFuture viewControllerFuture:viewControllerFuture]]; + } + + return defaultGlobalEntries; +} + +- (id)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:style]; + if (self) { + self.title = @"💪 FLEX"; + _entries = [[[self class] defaultGlobalEntries] arrayByAddingObjectsFromArray:[FLEXManager sharedManager].userGlobalEntries]; + } + return self; +} + +#pragma mark - Public + ++ (void)setApplicationWindow:(UIWindow *)applicationWindow +{ + s_applicationWindow = applicationWindow; +} + +#pragma mark - UIViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)]; +} + +#pragma mark - + +- (void)donePressed:(id)sender +{ + [self.delegate globalsViewControllerDidFinish:self]; +} + +#pragma mark - Table Data Helpers + +- (FLEXGlobalsTableViewControllerEntry *)globalEntryAtIndexPath:(NSIndexPath *)indexPath +{ + return self.entries[indexPath.row]; +} + +- (NSString *)titleForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXGlobalsTableViewControllerEntry *entry = [self globalEntryAtIndexPath:indexPath]; + + return entry.entryNameFuture(); +} + +- (UIViewController *)viewControllerToPushForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXGlobalsTableViewControllerEntry *entry = [self globalEntryAtIndexPath:indexPath]; + + return entry.viewControllerFuture(); +} + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.entries count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.textLabel.font = [FLEXUtility defaultFontOfSize:14.0]; + } + + cell.textLabel.text = [self titleForRowAtIndexPath:indexPath]; + + return cell; +} + + +#pragma mark - Table View Delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + UIViewController *viewControllerToPush = [self viewControllerToPushForRowAtIndexPath:indexPath]; + + [self.navigationController pushViewController:viewControllerToPush animated:YES]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.h new file mode 100755 index 0000000..b8e6d8f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.h @@ -0,0 +1,16 @@ +// +// FLEXInstancesTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXInstancesTableViewController : UITableViewController + ++ (instancetype)instancesTableViewControllerForClassName:(NSString *)className; ++ (instancetype)instancesTableViewControllerForInstancesReferencingObject:(id)object; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.m new file mode 100755 index 0000000..b802dce --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXInstancesTableViewController.m @@ -0,0 +1,130 @@ +// +// FLEXInstancesTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXInstancesTableViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXUtility.h" +#import "FLEXHeapEnumerator.h" +#import + + +@interface FLEXInstancesTableViewController () + +@property (nonatomic, strong) NSArray *instances; +@property (nonatomic, strong) NSArray *fieldNames; + +@end + +@implementation FLEXInstancesTableViewController + ++ (instancetype)instancesTableViewControllerForClassName:(NSString *)className +{ + const char *classNameCString = [className UTF8String]; + NSMutableArray *instances = [NSMutableArray array]; + [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id object, __unsafe_unretained Class actualClass) { + if (strcmp(classNameCString, class_getName(actualClass)) == 0) { + // Note: objects of certain classes crash when retain is called. It is up to the user to avoid tapping into instance lists for these classes. + // Ex. OS_dispatch_queue_specific_queue + // In the future, we could provide some kind of warning for classes that are known to be problematic. + if (malloc_size((__bridge const void *)(object)) > 0) { + [instances addObject:object]; + } + } + }]; + FLEXInstancesTableViewController *instancesViewController = [[self alloc] init]; + instancesViewController.instances = instances; + instancesViewController.title = [NSString stringWithFormat:@"%@ (%lu)", className, (unsigned long)[instances count]]; + return instancesViewController; +} + ++ (instancetype)instancesTableViewControllerForInstancesReferencingObject:(id)object +{ + NSMutableArray *instances = [NSMutableArray array]; + NSMutableArray *fieldNames = [NSMutableArray array]; + [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id tryObject, __unsafe_unretained Class actualClass) { + // Get all the ivars on the object. Start with the class and and travel up the inheritance chain. + // Once we find a match, record it and move on to the next object. There's no reason to find multiple matches within the same object. + Class tryClass = actualClass; + while (tryClass) { + unsigned int ivarCount = 0; + Ivar *ivars = class_copyIvarList(tryClass, &ivarCount); + for (unsigned int ivarIndex = 0; ivarIndex < ivarCount; ivarIndex++) { + Ivar ivar = ivars[ivarIndex]; + const char *typeEncoding = ivar_getTypeEncoding(ivar); + if (typeEncoding[0] == @encode(id)[0] || typeEncoding[0] == @encode(Class)[0]) { + ptrdiff_t offset = ivar_getOffset(ivar); + uintptr_t *fieldPointer = (__bridge void *)tryObject + offset; + if (*fieldPointer == (uintptr_t)(__bridge void *)object) { + [instances addObject:tryObject]; + [fieldNames addObject:@(ivar_getName(ivar))]; + return; + } + } + } + tryClass = class_getSuperclass(tryClass); + } + }]; + FLEXInstancesTableViewController *instancesViewController = [[self alloc] init]; + instancesViewController.instances = instances; + instancesViewController.fieldNames = fieldNames; + instancesViewController.title = [NSString stringWithFormat:@"Referencing %@ %p", NSStringFromClass(object_getClass(object)), object]; + return instancesViewController; +} + + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.instances count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + UIFont *cellFont = [FLEXUtility defaultTableViewCellLabelFont]; + cell.textLabel.font = cellFont; + cell.detailTextLabel.font = cellFont; + cell.detailTextLabel.textColor = [UIColor grayColor]; + } + + id instance = self.instances[indexPath.row]; + NSString *title = nil; + if ((NSInteger)[self.fieldNames count] > indexPath.row) { + title = [NSString stringWithFormat:@"%@ %@", NSStringFromClass(object_getClass(instance)), self.fieldNames[indexPath.row]]; + } else { + title = [NSString stringWithFormat:@"%@ %p", NSStringFromClass(object_getClass(instance)), instance]; + } + cell.textLabel.text = title; + cell.detailTextLabel.text = [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:instance]; + + return cell; +} + + +#pragma mark - Table View Delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + id instance = self.instances[indexPath.row]; + FLEXObjectExplorerViewController *drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:instance]; + [self.navigationController pushViewController:drillInViewController animated:YES]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.h new file mode 100755 index 0000000..a67783c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXLibrariesTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-02. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXLibrariesTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.m new file mode 100755 index 0000000..849238e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLibrariesTableViewController.m @@ -0,0 +1,177 @@ +// +// FLEXLibrariesTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-02. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXLibrariesTableViewController.h" +#import "FLEXUtility.h" +#import "FLEXClassesTableViewController.h" +#import "FLEXClassExplorerViewController.h" +#import + +@interface FLEXLibrariesTableViewController () + +@property (nonatomic, strong) NSArray *imageNames; +@property (nonatomic, strong) NSArray *filteredImageNames; + +@property (nonatomic, strong) UISearchBar *searchBar; +@property (nonatomic, strong) Class foundClass; + +@end + +@implementation FLEXLibrariesTableViewController + +- (id)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:style]; + if (self) { + [self loadImageNames]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.searchBar = [[UISearchBar alloc] init]; + self.searchBar.delegate = self; + self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText]; + [self.searchBar sizeToFit]; + self.tableView.tableHeaderView = self.searchBar; +} + + +#pragma mark - Binary Images + +- (void)loadImageNames +{ + unsigned int imageNamesCount = 0; + const char **imageNames = objc_copyImageNames(&imageNamesCount); + if (imageNames) { + NSMutableArray *imageNameStrings = [NSMutableArray array]; + NSString *appImageName = [FLEXUtility applicationImageName]; + for (unsigned int i = 0; i < imageNamesCount; i++) { + const char *imageName = imageNames[i]; + NSString *imageNameString = [NSString stringWithUTF8String:imageName]; + // Skip the app's image. We're just showing system libraries and frameworks. + if (![imageNameString isEqual:appImageName]) { + [imageNameStrings addObject:imageNameString]; + } + } + + // Sort alphabetically + self.imageNames = [imageNameStrings sortedArrayWithOptions:0 usingComparator:^NSComparisonResult(NSString *name1, NSString *name2) { + NSString *shortName1 = [self shortNameForImageName:name1]; + NSString *shortName2 = [self shortNameForImageName:name2]; + return [shortName1 caseInsensitiveCompare:shortName2]; + }]; + + free(imageNames); + } +} + +- (NSString *)shortNameForImageName:(NSString *)imageName +{ + NSArray *components = [imageName componentsSeparatedByString:@"/"]; + if (components.count >= 2) { + return [NSString stringWithFormat:@"%@/%@", components[components.count - 2], components[components.count - 1]]; + } + return imageName.lastPathComponent; +} + +- (void)setImageNames:(NSArray *)imageNames +{ + if (![_imageNames isEqual:imageNames]) { + _imageNames = imageNames; + self.filteredImageNames = imageNames; + } +} + + +#pragma mark - Filtering + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText +{ + if ([searchText length] > 0) { + NSPredicate *searchPreidcate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { + BOOL matches = NO; + NSString *shortName = [self shortNameForImageName:evaluatedObject]; + if ([shortName rangeOfString:searchText options:NSCaseInsensitiveSearch].length > 0) { + matches = YES; + } + return matches; + }]; + self.filteredImageNames = [self.imageNames filteredArrayUsingPredicate:searchPreidcate]; + } else { + self.filteredImageNames = self.imageNames; + } + + self.foundClass = NSClassFromString(searchText); + [self.tableView reloadData]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; +} + + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.filteredImageNames.count + (self.foundClass ? 1 : 0); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *cellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + } + + NSString *executablePath; + if (self.foundClass) { + if (indexPath.row == 0) { + cell.textLabel.text = [NSString stringWithFormat:@"Class \"%@\"", self.searchBar.text]; + return cell; + } else { + executablePath = self.filteredImageNames[indexPath.row-1]; + } + } else { + executablePath = self.filteredImageNames[indexPath.row]; + } + + cell.textLabel.text = [self shortNameForImageName:executablePath]; + return cell; +} + + +#pragma mark - Table View Delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row == 0 && self.foundClass) { + FLEXClassExplorerViewController *objectExplorer = [FLEXClassExplorerViewController new]; + objectExplorer.object = self.foundClass; + [self.navigationController pushViewController:objectExplorer animated:YES]; + } else { + FLEXClassesTableViewController *classesViewController = [[FLEXClassesTableViewController alloc] init]; + classesViewController.binaryImageName = self.filteredImageNames[self.foundClass ? indexPath.row-1 : indexPath.row]; + [self.navigationController pushViewController:classesViewController animated:YES]; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.h new file mode 100755 index 0000000..bf7a8d7 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXLiveObjectsTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXLiveObjectsTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.m new file mode 100755 index 0000000..e414b9c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXLiveObjectsTableViewController.m @@ -0,0 +1,208 @@ +// +// FLEXLiveObjectsTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXLiveObjectsTableViewController.h" +#import "FLEXHeapEnumerator.h" +#import "FLEXInstancesTableViewController.h" +#import "FLEXUtility.h" +#import + +static const NSInteger kFLEXLiveObjectsSortAlphabeticallyIndex = 0; +static const NSInteger kFLEXLiveObjectsSortByCountIndex = 1; + +@interface FLEXLiveObjectsTableViewController () + +@property (nonatomic, strong) NSDictionary *instanceCountsForClassNames; +@property (nonatomic, readonly) NSArray *allClassNames; +@property (nonatomic, strong) NSArray *filteredClassNames; +@property (nonatomic, strong) UISearchBar *searchBar; + +@end + +@implementation FLEXLiveObjectsTableViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.searchBar = [[UISearchBar alloc] init]; + self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText]; + self.searchBar.delegate = self; + self.searchBar.showsScopeBar = YES; + self.searchBar.scopeButtonTitles = @[@"Sort Alphabetically", @"Sort by Count"]; + [self.searchBar sizeToFit]; + self.tableView.tableHeaderView = self.searchBar; + + self.refreshControl = [[UIRefreshControl alloc] init]; + [self.refreshControl addTarget:self action:@selector(refreshControlDidRefresh:) forControlEvents:UIControlEventValueChanged]; + + [self reloadTableData]; +} + +- (NSArray *)allClassNames +{ + return [self.instanceCountsForClassNames allKeys]; +} + +- (void)reloadTableData +{ + // Set up a CFMutableDictionary with class pointer keys and NSUInteger values. + // We abuse CFMutableDictionary a little to have primitive keys through judicious casting, but it gets the job done. + // The dictionary is intialized with a 0 count for each class so that it doesn't have to expand during enumeration. + // While it might be a little cleaner to populate an NSMutableDictionary with class name string keys to NSNumber counts, + // we choose the CF/primitives approach because it lets us enumerate the objects in the heap without allocating any memory during enumeration. + // The alternative of creating one NSString/NSNumber per object on the heap ends up polluting the count of live objects quite a bit. + unsigned int classCount = 0; + Class *classes = objc_copyClassList(&classCount); + CFMutableDictionaryRef mutableCountsForClasses = CFDictionaryCreateMutable(NULL, classCount, NULL, NULL); + for (unsigned int i = 0; i < classCount; i++) { + CFDictionarySetValue(mutableCountsForClasses, (__bridge const void *)classes[i], (const void *)0); + } + + // Enumerate all objects on the heap to build the counts of instances for each class. + [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id object, __unsafe_unretained Class actualClass) { + NSUInteger instanceCount = (NSUInteger)CFDictionaryGetValue(mutableCountsForClasses, (__bridge const void *)actualClass); + instanceCount++; + CFDictionarySetValue(mutableCountsForClasses, (__bridge const void *)actualClass, (const void *)instanceCount); + }]; + + // Convert our CF primitive dictionary into a nicer mapping of class name strings to counts that we will use as the table's model. + NSMutableDictionary *mutableCountsForClassNames = [NSMutableDictionary dictionary]; + for (unsigned int i = 0; i < classCount; i++) { + Class class = classes[i]; + NSUInteger instanceCount = (NSUInteger)CFDictionaryGetValue(mutableCountsForClasses, (__bridge const void *)(class)); + if (instanceCount > 0) { + NSString *className = @(class_getName(class)); + [mutableCountsForClassNames setObject:@(instanceCount) forKey:className]; + } + } + free(classes); + + self.instanceCountsForClassNames = mutableCountsForClassNames; + + [self updateTableDataForSearchFilter]; +} + +- (void)refreshControlDidRefresh:(id)sender +{ + [self reloadTableData]; + [self.refreshControl endRefreshing]; +} + +- (void)updateTitle +{ + NSString *title = @"Live Objects"; + + NSUInteger totalCount = 0; + for (NSString *className in self.allClassNames) { + totalCount += [self.instanceCountsForClassNames[className] unsignedIntegerValue]; + } + NSUInteger filteredCount = 0; + for (NSString *className in self.filteredClassNames) { + filteredCount += [self.instanceCountsForClassNames[className] unsignedIntegerValue]; + } + + if (filteredCount == totalCount) { + // Unfiltered + title = [title stringByAppendingFormat:@" (%lu)", (unsigned long)totalCount]; + } else { + title = [title stringByAppendingFormat:@" (filtered, %lu)", (unsigned long)filteredCount]; + } + + self.title = title; +} + + +#pragma mark - Search + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText +{ + [self updateTableDataForSearchFilter]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; +} + +- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope +{ + [self updateTableDataForSearchFilter]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + // Dismiss the keyboard when interacting with filtered results. + [self.searchBar endEditing:YES]; +} + +- (void)updateTableDataForSearchFilter +{ + if ([self.searchBar.text length] > 0) { + NSPredicate *searchPreidcate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", self.searchBar.text]; + self.filteredClassNames = [self.allClassNames filteredArrayUsingPredicate:searchPreidcate]; + } else { + self.filteredClassNames = self.allClassNames; + } + + if (self.searchBar.selectedScopeButtonIndex == kFLEXLiveObjectsSortAlphabeticallyIndex) { + self.filteredClassNames = [self.filteredClassNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + } else if (self.searchBar.selectedScopeButtonIndex == kFLEXLiveObjectsSortByCountIndex) { + self.filteredClassNames = [self.filteredClassNames sortedArrayUsingComparator:^NSComparisonResult(NSString *className1, NSString *className2) { + NSNumber *count1 = self.instanceCountsForClassNames[className1]; + NSNumber *count2 = self.instanceCountsForClassNames[className2]; + // Reversed for descending counts. + return [count2 compare:count1]; + }]; + } + + [self updateTitle]; + [self.tableView reloadData]; +} + + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.filteredClassNames count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + } + + NSString *className = self.filteredClassNames[indexPath.row]; + NSNumber *count = self.instanceCountsForClassNames[className]; + cell.textLabel.text = [NSString stringWithFormat:@"%@ (%ld)", className, (long)[count integerValue]]; + + return cell; +} + + +#pragma mark - Table view delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString *className = self.filteredClassNames[indexPath.row]; + FLEXInstancesTableViewController *instancesViewController = [FLEXInstancesTableViewController instancesTableViewControllerForClassName:className]; + [self.navigationController pushViewController:instancesViewController animated:YES]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.h new file mode 100755 index 0000000..86c73dc --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.h @@ -0,0 +1,18 @@ +// +// FLEXWebViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/10/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXWebViewController : UIViewController + +- (id)initWithURL:(NSURL *)url; +- (id)initWithText:(NSString *)text; + ++ (BOOL)supportsPathExtension:(NSString *)extension; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.m new file mode 100755 index 0000000..51fdc7f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/FLEXWebViewController.m @@ -0,0 +1,127 @@ +// +// FLEXWebViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/10/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXWebViewController.h" +#import "FLEXUtility.h" + +@interface FLEXWebViewController () + +@property (nonatomic, strong) UIWebView *webView; +@property (nonatomic, strong) NSString *originalText; + +@end + +@implementation FLEXWebViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.webView = [[UIWebView alloc] init]; + self.webView.delegate = self; + self.webView.dataDetectorTypes = UIDataDetectorTypeLink; + self.webView.scalesPageToFit = YES; + } + return self; +} + +- (id)initWithText:(NSString *)text +{ + self = [self initWithNibName:nil bundle:nil]; + if (self) { + self.originalText = text; + NSString *htmlString = [NSString stringWithFormat:@"
%@
", [FLEXUtility stringByEscapingHTMLEntitiesInString:text]]; + [self.webView loadHTMLString:htmlString baseURL:nil]; + } + return self; +} + +- (id)initWithURL:(NSURL *)url +{ + self = [self initWithNibName:nil bundle:nil]; + if (self) { + NSURLRequest *request = [NSURLRequest requestWithURL:url]; + [self.webView loadRequest:request]; + } + return self; +} + +- (void)dealloc +{ + // UIWebView's delegate is assign so we need to clear it manually. + if (_webView.delegate == self) { + _webView.delegate = nil; + } +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.view addSubview:self.webView]; + self.webView.frame = self.view.bounds; + self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + if ([self.originalText length] > 0) { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Copy" style:UIBarButtonItemStylePlain target:self action:@selector(copyButtonTapped:)]; + } +} + +- (void)copyButtonTapped:(id)sender +{ + [[UIPasteboard generalPasteboard] setString:self.originalText]; +} + + +#pragma mark - UIWebView Delegate + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + BOOL shouldStart = NO; + if (navigationType == UIWebViewNavigationTypeOther) { + // Allow the initial load + shouldStart = YES; + } else { + // For clicked links, push another web view controller onto the navigation stack so that hitting the back button works as expected. + // Don't allow the current web view do handle the navigation. + FLEXWebViewController *webVC = [[[self class] alloc] initWithURL:[request URL]]; + webVC.title = [[request URL] absoluteString]; + [self.navigationController pushViewController:webVC animated:YES]; + } + return shouldStart; +} + + +#pragma mark - Class Helpers + ++ (BOOL)supportsPathExtension:(NSString *)extension +{ + BOOL supported = NO; + NSSet *supportedExtensions = [self webViewSupportedPathExtensions]; + if ([supportedExtensions containsObject:[extension lowercaseString]]) { + supported = YES; + } + return supported; +} + ++ (NSSet *)webViewSupportedPathExtensions +{ + static NSSet *pathExtenstions = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Note that this is not exhaustive, but all these extensions should work well in the web view. + // See https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW7 + pathExtenstions = [NSSet setWithArray:@[@"jpg", @"jpeg", @"png", @"gif", @"pdf", @"svg", @"tiff", @"3gp", @"3gpp", @"3g2", + @"3gp2", @"aiff", @"aif", @"aifc", @"cdda", @"amr", @"mp3", @"swa", @"mp4", @"mpeg", + @"mpg", @"mp3", @"wav", @"bwf", @"m4a", @"m4b", @"m4p", @"mov", @"qt", @"mqv", @"m4v"]]; + + }); + return pathExtenstions; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h new file mode 100755 index 0000000..32d0419 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h @@ -0,0 +1,21 @@ +// +// FLEXSystemLogMessage.h +// UICatalog +// +// Created by Ryan Olson on 1/25/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import +#import + +@interface FLEXSystemLogMessage : NSObject + ++ (instancetype)logMessageFromASLMessage:(aslmsg)aslMessage; + +@property (nonatomic, strong) NSDate *date; +@property (nonatomic, copy) NSString *sender; +@property (nonatomic, copy) NSString *messageText; +@property (nonatomic, assign) long long messageID; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m new file mode 100755 index 0000000..785b619 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m @@ -0,0 +1,55 @@ +// +// FLEXSystemLogMessage.m +// UICatalog +// +// Created by Ryan Olson on 1/25/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import "FLEXSystemLogMessage.h" + +@implementation FLEXSystemLogMessage + ++(instancetype)logMessageFromASLMessage:(aslmsg)aslMessage +{ + FLEXSystemLogMessage *logMessage = [[FLEXSystemLogMessage alloc] init]; + + const char *timestamp = asl_get(aslMessage, ASL_KEY_TIME); + if (timestamp) { + NSTimeInterval timeInterval = [@(timestamp) integerValue]; + const char *nanoseconds = asl_get(aslMessage, ASL_KEY_TIME_NSEC); + if (nanoseconds) { + timeInterval += [@(nanoseconds) doubleValue] / NSEC_PER_SEC; + } + logMessage.date = [NSDate dateWithTimeIntervalSince1970:timeInterval]; + } + + const char *sender = asl_get(aslMessage, ASL_KEY_SENDER); + if (sender) { + logMessage.sender = @(sender); + } + + const char *messageText = asl_get(aslMessage, ASL_KEY_MSG); + if (messageText) { + logMessage.messageText = @(messageText); + } + + const char *messageID = asl_get(aslMessage, ASL_KEY_MSG_ID); + if (messageID) { + logMessage.messageID = [@(messageID) longLongValue]; + } + + return logMessage; +} + +- (BOOL)isEqual:(id)object +{ + return [object isKindOfClass:[FLEXSystemLogMessage class]] && self.messageID == [object messageID]; +} + +- (NSUInteger)hash +{ + return (NSUInteger)self.messageID; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.h new file mode 100755 index 0000000..eff562a --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.h @@ -0,0 +1,23 @@ +// +// FLEXSystemLogTableViewCell.h +// UICatalog +// +// Created by Ryan Olson on 1/25/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import + +@class FLEXSystemLogMessage; + +extern NSString *const kFLEXSystemLogTableViewCellIdentifier; + +@interface FLEXSystemLogTableViewCell : UITableViewCell + +@property (nonatomic, strong) FLEXSystemLogMessage *logMessage; +@property (nonatomic, copy) NSString *highlightedText; + ++ (NSString *)displayedTextForLogMessage:(FLEXSystemLogMessage *)logMessage; ++ (CGFloat)preferredHeightForLogMessage:(FLEXSystemLogMessage *)logMessage inWidth:(CGFloat)width; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.m new file mode 100755 index 0000000..dbeb62f --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewCell.m @@ -0,0 +1,128 @@ +// +// FLEXSystemLogTableViewCell.m +// UICatalog +// +// Created by Ryan Olson on 1/25/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import "FLEXSystemLogTableViewCell.h" +#import "FLEXSystemLogMessage.h" + +NSString *const kFLEXSystemLogTableViewCellIdentifier = @"FLEXSystemLogTableViewCellIdentifier"; + +@interface FLEXSystemLogTableViewCell () + +@property (nonatomic, strong) UILabel *logMessageLabel; +@property (nonatomic, strong) NSAttributedString *logMessageAttributedText; + +@end + +@implementation FLEXSystemLogTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.logMessageLabel = [[UILabel alloc] init]; + self.logMessageLabel.numberOfLines = 0; + self.separatorInset = UIEdgeInsetsZero; + self.selectionStyle = UITableViewCellSelectionStyleNone; + [self.contentView addSubview:self.logMessageLabel]; + } + return self; +} + +- (void)setLogMessage:(FLEXSystemLogMessage *)logMessage +{ + if (![_logMessage isEqual:logMessage]) { + _logMessage = logMessage; + self.logMessageAttributedText = nil; + [self setNeedsLayout]; + } +} + +- (void)setHighlightedText:(NSString *)highlightedText +{ + if (![_highlightedText isEqual:highlightedText]) { + _highlightedText = highlightedText; + self.logMessageAttributedText = nil; + [self setNeedsLayout]; + } +} + +- (NSAttributedString *)logMessageAttributedText +{ + if (!_logMessageAttributedText) { + _logMessageAttributedText = [[self class] attributedTextForLogMessage:self.logMessage highlightedText:self.highlightedText]; + } + return _logMessageAttributedText; +} + +static const UIEdgeInsets kFLEXLogMessageCellInsets = {10.0, 10.0, 10.0, 10.0}; + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.logMessageLabel.attributedText = self.logMessageAttributedText; + self.logMessageLabel.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, kFLEXLogMessageCellInsets); +} + +#pragma mark - Stateless helpers + ++ (NSAttributedString *)attributedTextForLogMessage:(FLEXSystemLogMessage *)logMessage highlightedText:(NSString *)highlightedText +{ + NSString *text = [self displayedTextForLogMessage:logMessage]; + NSDictionary *attributes = @{ NSFontAttributeName : [UIFont fontWithName:@"CourierNewPSMT" size:12.0] }; + NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:attributes]; + + if ([highlightedText length] > 0) { + NSMutableAttributedString *mutableAttributedText = [attributedText mutableCopy]; + NSMutableDictionary *highlightAttributes = [@{ NSBackgroundColorAttributeName : [UIColor yellowColor] } mutableCopy]; + [highlightAttributes addEntriesFromDictionary:attributes]; + + NSRange remainingSearchRange = NSMakeRange(0, text.length); + while (remainingSearchRange.location < text.length) { + remainingSearchRange.length = text.length - remainingSearchRange.location; + NSRange foundRange = [text rangeOfString:highlightedText options:NSCaseInsensitiveSearch range:remainingSearchRange]; + if (foundRange.location != NSNotFound) { + remainingSearchRange.location = foundRange.location + foundRange.length; + [mutableAttributedText setAttributes:highlightAttributes range:foundRange]; + } else { + break; + } + } + attributedText = mutableAttributedText; + } + + return attributedText; +} + ++ (NSString *)displayedTextForLogMessage:(FLEXSystemLogMessage *)logMessage +{ + return [NSString stringWithFormat:@"%@: %@", [self logTimeStringFromDate:logMessage.date], logMessage.messageText]; +} + ++ (CGFloat)preferredHeightForLogMessage:(FLEXSystemLogMessage *)logMessage inWidth:(CGFloat)width +{ + UIEdgeInsets insets = kFLEXLogMessageCellInsets; + CGFloat availableWidth = width - insets.left - insets.right; + NSAttributedString *attributedLogText = [self attributedTextForLogMessage:logMessage highlightedText:nil]; + CGSize labelSize = [attributedLogText boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil].size; + return labelSize.height + insets.top + insets.bottom; +} + ++ (NSString *)logTimeStringFromDate:(NSDate *)date +{ + static NSDateFormatter *formatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + formatter = [[NSDateFormatter alloc] init]; + formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; + }); + + return [formatter stringFromDate:date]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.h new file mode 100755 index 0000000..ca9f521 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXSystemLogTableViewController.h +// UICatalog +// +// Created by Ryan Olson on 1/19/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import + +@interface FLEXSystemLogTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.m new file mode 100755 index 0000000..b1e5b65 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/GlobalStateExplorers/SystemLog/FLEXSystemLogTableViewController.m @@ -0,0 +1,192 @@ +// +// FLEXSystemLogTableViewController.m +// UICatalog +// +// Created by Ryan Olson on 1/19/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import "FLEXSystemLogTableViewController.h" +#import "FLEXUtility.h" +#import "FLEXSystemLogMessage.h" +#import "FLEXSystemLogTableViewCell.h" +#import + +@interface FLEXSystemLogTableViewController () + +@property (nonatomic, strong) UISearchController *searchController; +@property (nonatomic, copy) NSArray *logMessages; +@property (nonatomic, copy) NSArray *filteredLogMessages; +@property (nonatomic, strong) NSTimer *logUpdateTimer; + +@end + +@implementation FLEXSystemLogTableViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.tableView registerClass:[FLEXSystemLogTableViewCell class] forCellReuseIdentifier:kFLEXSystemLogTableViewCellIdentifier]; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + self.title = @"Loading..."; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@" ⬇︎ " style:UIBarButtonItemStylePlain target:self action:@selector(scrollToLastRow)]; + + self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; + self.searchController.delegate = self; + self.searchController.searchResultsUpdater = self; + self.searchController.dimsBackgroundDuringPresentation = NO; + self.tableView.tableHeaderView = self.searchController.searchBar; + + [self updateLogMessages]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + NSTimeInterval updateInterval = 1.0; + +#if TARGET_IPHONE_SIMULATOR + // Querrying the ASL is much slower in the simulator. We need a longer polling interval to keep things repsonsive. + updateInterval = 5.0; +#endif + + self.logUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:updateInterval target:self selector:@selector(updateLogMessages) userInfo:nil repeats:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + + [self.logUpdateTimer invalidate]; +} + +- (void)updateLogMessages +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSArray *logMessages = [[self class] allLogMessagesForCurrentProcess]; + dispatch_async(dispatch_get_main_queue(), ^{ + self.title = @"System Log"; + self.logMessages = logMessages; + + // "Follow" the log as new messages stream in if we were previously near the bottom. + BOOL wasNearBottom = self.tableView.contentOffset.y >= self.tableView.contentSize.height - self.tableView.frame.size.height - 100.0; + [self.tableView reloadData]; + if (wasNearBottom) { + [self scrollToLastRow]; + } + }); + }); +} + +- (void)scrollToLastRow +{ + NSInteger numberOfRows = [self.tableView numberOfRowsInSection:0]; + if (numberOfRows > 0) { + NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:numberOfRows - 1 inSection:0]; + [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; + } +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.searchController.isActive ? [self.filteredLogMessages count] : [self.logMessages count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXSystemLogTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXSystemLogTableViewCellIdentifier forIndexPath:indexPath]; + cell.logMessage = [self logMessageAtIndexPath:indexPath]; + cell.highlightedText = self.searchController.searchBar.text; + + if (indexPath.row % 2 == 0) { + cell.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; + } else { + cell.backgroundColor = [UIColor whiteColor]; + } + + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXSystemLogMessage *logMessage = [self logMessageAtIndexPath:indexPath]; + return [FLEXSystemLogTableViewCell preferredHeightForLogMessage:logMessage inWidth:self.tableView.bounds.size.width]; +} + +#pragma mark - Copy on long press + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return YES; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + return action == @selector(copy:); +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + if (action == @selector(copy:)) { + FLEXSystemLogMessage *logMessage = [self logMessageAtIndexPath:indexPath]; + NSString *stringToCopy = [FLEXSystemLogTableViewCell displayedTextForLogMessage:logMessage] ?: @""; + [[UIPasteboard generalPasteboard] setString:stringToCopy]; + } +} + +- (FLEXSystemLogMessage *)logMessageAtIndexPath:(NSIndexPath *)indexPath +{ + return self.searchController.isActive ? self.filteredLogMessages[indexPath.row] : self.logMessages[indexPath.row]; +} + +#pragma mark - UISearchResultsUpdating + +- (void)updateSearchResultsForSearchController:(UISearchController *)searchController +{ + NSString *searchString = searchController.searchBar.text; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSArray *filteredLogMessages = [self.logMessages filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FLEXSystemLogMessage *logMessage, NSDictionary *bindings) { + NSString *displayedText = [FLEXSystemLogTableViewCell displayedTextForLogMessage:logMessage]; + return [displayedText rangeOfString:searchString options:NSCaseInsensitiveSearch].length > 0; + }]]; + dispatch_async(dispatch_get_main_queue(), ^{ + if ([searchController.searchBar.text isEqual:searchString]) { + self.filteredLogMessages = filteredLogMessages; + [self.tableView reloadData]; + } + }); + }); +} + +#pragma mark - Log Message Fetching + ++ (NSArray *)allLogMessagesForCurrentProcess +{ + asl_object_t query = asl_new(ASL_TYPE_QUERY); + + // Filter for messages from the current process. Note that this appears to happen by default on device, but is required in the simulator. + NSString *pidString = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]]; + asl_set_query(query, ASL_KEY_PID, [pidString UTF8String], ASL_QUERY_OP_EQUAL); + + aslresponse response = asl_search(NULL, query); + aslmsg aslMessage = NULL; + + NSMutableArray *logMessages = [NSMutableArray array]; + while ((aslMessage = asl_next(response))) { + [logMessages addObject:[FLEXSystemLogMessage logMessageFromASLMessage:aslMessage]]; + } + asl_release(response); + + return logMessages; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager+Private.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager+Private.h new file mode 100755 index 0000000..e5a25bc --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager+Private.h @@ -0,0 +1,16 @@ +// +// FLEXManager+Private.h +// PebbleApp +// +// Created by Javier Soto on 7/26/14. +// Copyright (c) 2014 Pebble Technology. All rights reserved. +// + +#import "FLEXManager.h" + +@interface FLEXManager () + +/// An array of FLEXGlobalsTableViewControllerEntry objects that have been registered by the user. +@property (nonatomic, readonly, strong) NSArray *userGlobalEntries; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager.m new file mode 100755 index 0000000..e8d66fe --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Manager/FLEXManager.m @@ -0,0 +1,360 @@ +// +// FLEXManager.m +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXManager.h" +#import "FLEXExplorerViewController.h" +#import "FLEXWindow.h" +#import "FLEXGlobalsTableViewControllerEntry.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXNetworkObserver.h" +#import "FLEXNetworkRecorder.h" +#import "FLEXKeyboardShortcutManager.h" +#import "FLEXFileBrowserTableViewController.h" +#import "FLEXNetworkHistoryTableViewController.h" +#import "FLEXKeyboardHelpViewController.h" + +@interface FLEXManager () + +@property (nonatomic, strong) FLEXWindow *explorerWindow; +@property (nonatomic, strong) FLEXExplorerViewController *explorerViewController; + +@property (nonatomic, readonly, strong) NSMutableArray *userGlobalEntries; + +@end + +@implementation FLEXManager + ++ (instancetype)sharedManager +{ + static FLEXManager *sharedManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedManager = [[[self class] alloc] init]; + }); + return sharedManager; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + _userGlobalEntries = [[NSMutableArray alloc] init]; + } + return self; +} + +- (FLEXWindow *)explorerWindow +{ + NSAssert([NSThread isMainThread], @"You must use %@ from the main thread only.", NSStringFromClass([self class])); + + if (!_explorerWindow) { + _explorerWindow = [[FLEXWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + _explorerWindow.eventDelegate = self; + _explorerWindow.rootViewController = self.explorerViewController; + } + + return _explorerWindow; +} + +- (FLEXExplorerViewController *)explorerViewController +{ + if (!_explorerViewController) { + _explorerViewController = [[FLEXExplorerViewController alloc] init]; + _explorerViewController.delegate = self; + } + + return _explorerViewController; +} + +- (void)showExplorer +{ + self.explorerWindow.hidden = NO; +} + +- (void)hideExplorer +{ + self.explorerWindow.hidden = YES; +} + +- (void)toggleExplorer { + if (self.explorerWindow.isHidden) { + [self showExplorer]; + } else { + [self hideExplorer]; + } +} + +- (BOOL)isHidden +{ + return self.explorerWindow.isHidden; +} + +- (BOOL)isNetworkDebuggingEnabled +{ + return [FLEXNetworkObserver isEnabled]; +} + +- (void)setNetworkDebuggingEnabled:(BOOL)networkDebuggingEnabled +{ + [FLEXNetworkObserver setEnabled:networkDebuggingEnabled]; +} + +- (NSUInteger)networkResponseCacheByteLimit +{ + return [[FLEXNetworkRecorder defaultRecorder] responseCacheByteLimit]; +} + +- (void)setNetworkResponseCacheByteLimit:(NSUInteger)networkResponseCacheByteLimit +{ + [[FLEXNetworkRecorder defaultRecorder] setResponseCacheByteLimit:networkResponseCacheByteLimit]; +} + +#pragma mark - FLEXWindowEventDelegate + +- (BOOL)shouldHandleTouchAtPoint:(CGPoint)pointInWindow +{ + // Ask the explorer view controller + return [self.explorerViewController shouldReceiveTouchAtWindowPoint:pointInWindow]; +} + +- (BOOL)canBecomeKeyWindow +{ + // Only when the explorer view controller wants it because it needs to accept key input & affect the status bar. + return [self.explorerViewController wantsWindowToBecomeKey]; +} + + +#pragma mark - FLEXExplorerViewControllerDelegate + +- (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerViewController +{ + [self hideExplorer]; +} + +#pragma mark - Simulator Shortcuts + +- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description +{ +# if TARGET_OS_SIMULATOR + [[FLEXKeyboardShortcutManager sharedManager] registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description]; +#endif +} + +- (void)setSimulatorShortcutsEnabled:(BOOL)simulatorShortcutsEnabled +{ +# if TARGET_OS_SIMULATOR + [[FLEXKeyboardShortcutManager sharedManager] setEnabled:simulatorShortcutsEnabled]; +#endif +} + +- (BOOL)simulatorShortcutsEnabled +{ +# if TARGET_OS_SIMULATOR + return [[FLEXKeyboardShortcutManager sharedManager] isEnabled]; +#else + return NO; +#endif +} + +- (void)registerDefaultSimulatorShortcuts +{ + [self registerSimulatorShortcutWithKey:@"f" modifiers:0 action:^{ + [self toggleExplorer]; + } description:@"Toggle FLEX toolbar"]; + + [self registerSimulatorShortcutWithKey:@"g" modifiers:0 action:^{ + [self showExplorerIfNeeded]; + [self.explorerViewController toggleMenuTool]; + } description:@"Toggle FLEX globals menu"]; + + [self registerSimulatorShortcutWithKey:@"v" modifiers:0 action:^{ + [self showExplorerIfNeeded]; + [self.explorerViewController toggleViewsTool]; + } description:@"Toggle view hierarchy menu"]; + + [self registerSimulatorShortcutWithKey:@"s" modifiers:0 action:^{ + [self showExplorerIfNeeded]; + [self.explorerViewController toggleSelectTool]; + } description:@"Toggle select tool"]; + + [self registerSimulatorShortcutWithKey:@"m" modifiers:0 action:^{ + [self showExplorerIfNeeded]; + [self.explorerViewController toggleMoveTool]; + } description:@"Toggle move tool"]; + + [self registerSimulatorShortcutWithKey:@"n" modifiers:0 action:^{ + [self toggleTopViewControllerOfClass:[FLEXNetworkHistoryTableViewController class]]; + } description:@"Toggle network history view"]; + + [self registerSimulatorShortcutWithKey:UIKeyInputDownArrow modifiers:0 action:^{ + if ([self isHidden]) { + [self tryScrollDown]; + } else { + [self.explorerViewController handleDownArrowKeyPressed]; + } + } description:@"Cycle view selection\n\t\tMove view down\n\t\tScroll down"]; + + [self registerSimulatorShortcutWithKey:UIKeyInputUpArrow modifiers:0 action:^{ + if ([self isHidden]) { + [self tryScrollUp]; + } else { + [self.explorerViewController handleUpArrowKeyPressed]; + } + } description:@"Cycle view selection\n\t\tMove view up\n\t\tScroll up"]; + + [self registerSimulatorShortcutWithKey:UIKeyInputRightArrow modifiers:0 action:^{ + if (![self isHidden]) { + [self.explorerViewController handleRightArrowKeyPressed]; + } + } description:@"Move selected view right"]; + + [self registerSimulatorShortcutWithKey:UIKeyInputLeftArrow modifiers:0 action:^{ + if ([self isHidden]) { + [self tryGoBack]; + } else { + [self.explorerViewController handleLeftArrowKeyPressed]; + } + } description:@"Move selected view left"]; + + [self registerSimulatorShortcutWithKey:@"?" modifiers:0 action:^{ + [self toggleTopViewControllerOfClass:[FLEXKeyboardHelpViewController class]]; + } description:@"Toggle (this) help menu"]; + + [self registerSimulatorShortcutWithKey:UIKeyInputEscape modifiers:0 action:^{ + [[[self topViewController] presentingViewController] dismissViewControllerAnimated:YES completion:nil]; + } description:@"End editing text\n\t\tDismiss top view controller"]; + + [self registerSimulatorShortcutWithKey:@"o" modifiers:UIKeyModifierCommand|UIKeyModifierShift action:^{ + [self toggleTopViewControllerOfClass:[FLEXFileBrowserTableViewController class]]; + } description:@"Toggle file browser menu"]; +} + ++ (void)load +{ + dispatch_async(dispatch_get_main_queue(), ^{ + [[[self class] sharedManager] registerDefaultSimulatorShortcuts]; + }); +} + +#pragma mark - Extensions + +- (void)registerGlobalEntryWithName:(NSString *)entryName objectFutureBlock:(id (^)(void))objectFutureBlock +{ + NSParameterAssert(entryName); + NSParameterAssert(objectFutureBlock); + NSAssert([NSThread isMainThread], @"This method must be called from the main thread."); + + entryName = entryName.copy; + FLEXGlobalsTableViewControllerEntry *entry = [FLEXGlobalsTableViewControllerEntry entryWithNameFuture:^NSString *{ + return entryName; + } viewControllerFuture:^UIViewController *{ + return [FLEXObjectExplorerFactory explorerViewControllerForObject:objectFutureBlock()]; + }]; + + [self.userGlobalEntries addObject:entry]; +} + +- (void)registerGlobalEntryWithName:(NSString *)entryName viewControllerFutureBlock:(UIViewController * (^)(void))viewControllerFutureBlock +{ + NSParameterAssert(entryName); + NSParameterAssert(viewControllerFutureBlock); + NSAssert([NSThread isMainThread], @"This method must be called from the main thread."); + + entryName = entryName.copy; + FLEXGlobalsTableViewControllerEntry *entry = [FLEXGlobalsTableViewControllerEntry entryWithNameFuture:^NSString *{ + return entryName; + } viewControllerFuture:^UIViewController *{ + UIViewController *viewController = viewControllerFutureBlock(); + NSCAssert(viewController, @"'%@' entry returned nil viewController. viewControllerFutureBlock should never return nil.", entryName); + return viewController; + }]; + + [self.userGlobalEntries addObject:entry]; +} + +- (void)tryScrollDown +{ + UIScrollView *firstScrollView = [self firstScrollView]; + CGPoint contentOffset = [firstScrollView contentOffset]; + CGFloat distance = floor(firstScrollView.frame.size.height / 2.0); + CGFloat maxContentOffsetY = firstScrollView.contentSize.height + firstScrollView.contentInset.bottom - firstScrollView.frame.size.height; + distance = MIN(maxContentOffsetY - firstScrollView.contentOffset.y, distance); + contentOffset.y += distance; + [firstScrollView setContentOffset:contentOffset animated:YES]; +} + +- (void)tryScrollUp +{ + UIScrollView *firstScrollView = [self firstScrollView]; + CGPoint contentOffset = [firstScrollView contentOffset]; + CGFloat distance = floor(firstScrollView.frame.size.height / 2.0); + CGFloat minContentOffsetY = -firstScrollView.contentInset.top; + distance = MIN(firstScrollView.contentOffset.y - minContentOffsetY, distance); + contentOffset.y -= distance; + [firstScrollView setContentOffset:contentOffset animated:YES]; +} + +- (UIScrollView *)firstScrollView +{ + NSMutableArray *views = [[[[UIApplication sharedApplication] keyWindow] subviews] mutableCopy]; + UIScrollView *scrollView = nil; + while ([views count] > 0) { + UIView *view = [views firstObject]; + [views removeObjectAtIndex:0]; + if ([view isKindOfClass:[UIScrollView class]]) { + scrollView = (UIScrollView *)view; + break; + } else { + [views addObjectsFromArray:[view subviews]]; + } + } + return scrollView; +} + +- (void)tryGoBack +{ + UINavigationController *navigationController = nil; + UIViewController *topViewController = [self topViewController]; + if ([topViewController isKindOfClass:[UINavigationController class]]) { + navigationController = (UINavigationController *)topViewController; + } else { + navigationController = topViewController.navigationController; + } + [navigationController popViewControllerAnimated:YES]; +} + +- (UIViewController *)topViewController +{ + UIViewController *topViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController]; + while ([topViewController presentedViewController]) { + topViewController = [topViewController presentedViewController]; + } + return topViewController; +} + +- (void)toggleTopViewControllerOfClass:(Class)class +{ + UIViewController *topViewController = [self topViewController]; + if ([topViewController isKindOfClass:[UINavigationController class]] && [[[(UINavigationController *)topViewController viewControllers] firstObject] isKindOfClass:[class class]]) { + [[topViewController presentingViewController] dismissViewControllerAnimated:YES completion:nil]; + } else { + id viewController = [[class alloc] init]; + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; + [topViewController presentViewController:navigationController animated:YES completion:nil]; + } +} + +- (void)showExplorerIfNeeded +{ + if ([self isHidden]) { + [self showExplorer]; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.h new file mode 100755 index 0000000..6fb7eb6 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.h @@ -0,0 +1,19 @@ +// +// FLEXCurlLogger.h +// +// +// Created by Ji Pei on 07/27/16 +// + +#import + +@interface FLEXNetworkCurlLogger : NSObject + +/** + * Generates a cURL command equivalent to the given request. + * + * @param request The request to be translated + */ ++ (NSString *)curlCommandString:(NSURLRequest *)request; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.m new file mode 100755 index 0000000..742d3a5 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkCurlLogger.m @@ -0,0 +1,42 @@ +// +// FLEXCurlLogger.m +// +// +// Created by Ji Pei on 07/27/16 +// + +#import "FLEXNetworkCurlLogger.h" + +@implementation FLEXNetworkCurlLogger + ++ (NSString *)curlCommandString:(NSURLRequest *)request { + __block NSMutableString *curlCommandString = [NSMutableString stringWithFormat:@"curl -v -X %@ ", request.HTTPMethod]; + + [curlCommandString appendFormat:@"\'%@\' ", request.URL.absoluteString]; + + [request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *val, BOOL *stop) { + [curlCommandString appendFormat:@"-H \'%@: %@\' ", key, val]; + }]; + + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL]; + if (cookies) { + [curlCommandString appendFormat:@"-H \'Cookie:"]; + for (NSHTTPCookie *cookie in cookies) { + [curlCommandString appendFormat:@" %@=%@;", cookie.name, cookie.value]; + } + [curlCommandString appendFormat:@"\' "]; + } + + if (request.HTTPBody) { + if ([request.allHTTPHeaderFields[@"Content-Length"] intValue] < 1024) { + [curlCommandString appendFormat:@"-d \'%@\'", + [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]]; + } else { + [curlCommandString appendFormat:@"[TOO MUCH DATA TO INCLUDE]"]; + } + } + + return curlCommandString; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.h new file mode 100755 index 0000000..b114515 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXNetworkHistoryTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import + +@interface FLEXNetworkHistoryTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.m new file mode 100755 index 0000000..040fa44 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkHistoryTableViewController.m @@ -0,0 +1,360 @@ +// +// FLEXNetworkHistoryTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXNetworkHistoryTableViewController.h" +#import "FLEXNetworkTransaction.h" +#import "FLEXNetworkTransactionTableViewCell.h" +#import "FLEXNetworkRecorder.h" +#import "FLEXNetworkTransactionDetailTableViewController.h" +#import "FLEXNetworkObserver.h" +#import "FLEXNetworkSettingsTableViewController.h" + +@interface FLEXNetworkHistoryTableViewController () + +/// Backing model +@property (nonatomic, copy) NSArray *networkTransactions; +@property (nonatomic, assign) long long bytesReceived; +@property (nonatomic, copy) NSArray *filteredNetworkTransactions; +@property (nonatomic, assign) long long filteredBytesReceived; + +@property (nonatomic, assign) BOOL rowInsertInProgress; +@property (nonatomic, assign) BOOL isPresentingSearch; + +@property (nonatomic, strong) UISearchController *searchController; + +@end + +@implementation FLEXNetworkHistoryTableViewController + +- (instancetype)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:style]; + if (self) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNewTransactionRecordedNotification:) name:kFLEXNetworkRecorderNewTransactionNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTransactionUpdatedNotification:) name:kFLEXNetworkRecorderTransactionUpdatedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTransactionsClearedNotification:) name:kFLEXNetworkRecorderTransactionsClearedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNetworkObserverEnabledStateChangedNotification:) name:kFLEXNetworkObserverEnabledStateChangedNotification object:nil]; + self.title = @"📡 Network"; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStylePlain target:self action:@selector(settingsButtonTapped:)]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.tableView registerClass:[FLEXNetworkTransactionTableViewCell class] forCellReuseIdentifier:kFLEXNetworkTransactionCellIdentifier]; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + self.tableView.rowHeight = [FLEXNetworkTransactionTableViewCell preferredCellHeight]; + + self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; + self.searchController.delegate = self; + self.searchController.searchResultsUpdater = self; + self.searchController.dimsBackgroundDuringPresentation = NO; + self.tableView.tableHeaderView = self.searchController.searchBar; + + [self updateTransactions]; +} + +- (void)settingsButtonTapped:(id)sender +{ + FLEXNetworkSettingsTableViewController *settingsViewController = [[FLEXNetworkSettingsTableViewController alloc] init]; + settingsViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(settingsViewControllerDoneTapped:)]; + settingsViewController.title = @"Network Debugging Settings"; + UINavigationController *wrapperNavigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController]; + [self presentViewController:wrapperNavigationController animated:YES completion:nil]; +} + +- (void)settingsViewControllerDoneTapped:(id)sender +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)updateTransactions +{ + self.networkTransactions = [[FLEXNetworkRecorder defaultRecorder] networkTransactions]; +} + +- (void)setNetworkTransactions:(NSArray *)networkTransactions +{ + if (![_networkTransactions isEqual:networkTransactions]) { + _networkTransactions = networkTransactions; + [self updateBytesReceived]; + [self updateFilteredBytesReceived]; + } +} + +- (void)updateBytesReceived +{ + long long bytesReceived = 0; + for (FLEXNetworkTransaction *transaction in self.networkTransactions) { + bytesReceived += transaction.receivedDataLength; + } + self.bytesReceived = bytesReceived; + [self updateFirstSectionHeader]; +} + +- (void)setFilteredNetworkTransactions:(NSArray *)filteredNetworkTransactions +{ + if (![_filteredNetworkTransactions isEqual:filteredNetworkTransactions]) { + _filteredNetworkTransactions = filteredNetworkTransactions; + [self updateFilteredBytesReceived]; + } +} + +- (void)updateFilteredBytesReceived +{ + long long filteredBytesReceived = 0; + for (FLEXNetworkTransaction *transaction in self.filteredNetworkTransactions) { + filteredBytesReceived += transaction.receivedDataLength; + } + self.filteredBytesReceived = filteredBytesReceived; + [self updateFirstSectionHeader]; +} + +- (void)updateFirstSectionHeader +{ + UIView *view = [self.tableView headerViewForSection:0]; + if ([view isKindOfClass:[UITableViewHeaderFooterView class]]) { + UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view; + headerView.textLabel.text = [self headerText]; + [headerView setNeedsLayout]; + } +} + +- (NSString *)headerText +{ + NSString *headerText = nil; + if ([FLEXNetworkObserver isEnabled]) { + long long bytesReceived = 0; + NSInteger totalRequests = 0; + if (self.searchController.isActive) { + bytesReceived = self.filteredBytesReceived; + totalRequests = [self.filteredNetworkTransactions count]; + } else { + bytesReceived = self.bytesReceived; + totalRequests = [self.networkTransactions count]; + } + NSString *byteCountText = [NSByteCountFormatter stringFromByteCount:bytesReceived countStyle:NSByteCountFormatterCountStyleBinary]; + NSString *requestsText = totalRequests == 1 ? @"Request" : @"Requests"; + headerText = [NSString stringWithFormat:@"%ld %@ (%@ received)", (long)totalRequests, requestsText, byteCountText]; + } else { + headerText = @"⚠️ Debugging Disabled (Enable in Settings)"; + } + return headerText; +} + +#pragma mark - Notification Handlers + +- (void)handleNewTransactionRecordedNotification:(NSNotification *)notification +{ + [self tryUpdateTransactions]; +} + +- (void)tryUpdateTransactions +{ + // Let the previous row insert animation finish before starting a new one to avoid stomping. + // We'll try calling the method again when the insertion completes, and we properly no-op if there haven't been changes. + if (self.rowInsertInProgress) { + return; + } + + if (self.searchController.isActive) { + [self updateTransactions]; + [self updateSearchResults]; + return; + } + + NSInteger existingRowCount = [self.networkTransactions count]; + [self updateTransactions]; + NSInteger newRowCount = [self.networkTransactions count]; + NSInteger addedRowCount = newRowCount - existingRowCount; + + if (addedRowCount != 0 && !self.isPresentingSearch) { + // Insert animation if we're at the top. + if (self.tableView.contentOffset.y <= 0.0 && addedRowCount > 0) { + [CATransaction begin]; + + self.rowInsertInProgress = YES; + [CATransaction setCompletionBlock:^{ + self.rowInsertInProgress = NO; + [self tryUpdateTransactions]; + }]; + + NSMutableArray *indexPathsToReload = [NSMutableArray array]; + for (NSInteger row = 0; row < addedRowCount; row++) { + [indexPathsToReload addObject:[NSIndexPath indexPathForRow:row inSection:0]]; + } + [self.tableView insertRowsAtIndexPaths:indexPathsToReload withRowAnimation:UITableViewRowAnimationAutomatic]; + + [CATransaction commit]; + } else { + // Maintain the user's position if they've scrolled down. + CGSize existingContentSize = self.tableView.contentSize; + [self.tableView reloadData]; + CGFloat contentHeightChange = self.tableView.contentSize.height - existingContentSize.height; + self.tableView.contentOffset = CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y + contentHeightChange); + } + } +} + +- (void)handleTransactionUpdatedNotification:(NSNotification *)notification +{ + [self updateBytesReceived]; + [self updateFilteredBytesReceived]; + + FLEXNetworkTransaction *transaction = notification.userInfo[kFLEXNetworkRecorderUserInfoTransactionKey]; + + // Update both the main table view and search table view if needed. + for (FLEXNetworkTransactionTableViewCell *cell in [self.tableView visibleCells]) { + if ([cell.transaction isEqual:transaction]) { + // Using -[UITableView reloadRowsAtIndexPaths:withRowAnimation:] is overkill here and kicks off a lot of + // work that can make the table view somewhat unresponseive when lots of updates are streaming in. + // We just need to tell the cell that it needs to re-layout. + [cell setNeedsLayout]; + break; + } + } + [self updateFirstSectionHeader]; +} + +- (void)handleTransactionsClearedNotification:(NSNotification *)notification +{ + [self updateTransactions]; + [self.tableView reloadData]; +} + +- (void)handleNetworkObserverEnabledStateChangedNotification:(NSNotification *)notification +{ + // Update the header, which displays a warning when network debugging is disabled + [self updateFirstSectionHeader]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.searchController.isActive ? [self.filteredNetworkTransactions count] : [self.networkTransactions count]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [self headerText]; +} + +- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section +{ + if ([view isKindOfClass:[UITableViewHeaderFooterView class]]) { + UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view; + headerView.textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0]; + headerView.textLabel.textColor = [UIColor whiteColor]; + headerView.contentView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.0]; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXNetworkTransactionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXNetworkTransactionCellIdentifier forIndexPath:indexPath]; + cell.transaction = [self transactionAtIndexPath:indexPath inTableView:tableView]; + + // Since we insert from the top, assign background colors bottom up to keep them consistent for each transaction. + NSInteger totalRows = [tableView numberOfRowsInSection:indexPath.section]; + if ((totalRows - indexPath.row) % 2 == 0) { + cell.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; + } else { + cell.backgroundColor = [UIColor whiteColor]; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXNetworkTransactionDetailTableViewController *detailViewController = [[FLEXNetworkTransactionDetailTableViewController alloc] init]; + detailViewController.transaction = [self transactionAtIndexPath:indexPath inTableView:tableView]; + [self.navigationController pushViewController:detailViewController animated:YES]; +} + +#pragma mark - Menu Actions + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return YES; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + return action == @selector(copy:); +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + if (action == @selector(copy:)) { + FLEXNetworkTransaction *transaction = [self transactionAtIndexPath:indexPath inTableView:tableView]; + NSString *requestURLString = transaction.request.URL.absoluteString ?: @""; + [[UIPasteboard generalPasteboard] setString:requestURLString]; + } +} + +- (FLEXNetworkTransaction *)transactionAtIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView +{ + return self.searchController.isActive ? self.filteredNetworkTransactions[indexPath.row] : self.networkTransactions[indexPath.row]; +} + +#pragma mark - UISearchResultsUpdating + +- (void)updateSearchResultsForSearchController:(UISearchController *)searchController +{ + [self updateSearchResults]; +} + +- (void)updateSearchResults +{ + NSString *searchString = self.searchController.searchBar.text; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSArray *filteredNetworkTransactions = [self.networkTransactions filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FLEXNetworkTransaction *transaction, NSDictionary *bindings) { + return [[transaction.request.URL absoluteString] rangeOfString:searchString options:NSCaseInsensitiveSearch].length > 0; + }]]; + dispatch_async(dispatch_get_main_queue(), ^{ + if ([self.searchController.searchBar.text isEqual:searchString]) { + self.filteredNetworkTransactions = filteredNetworkTransactions; + [self.tableView reloadData]; + } + }); + }); +} + +#pragma mark - UISearchControllerDelegate + +- (void)willPresentSearchController:(UISearchController *)searchController +{ + self.isPresentingSearch = YES; +} + +- (void)didPresentSearchController:(UISearchController *)searchController +{ + self.isPresentingSearch = NO; +} + +- (void)willDismissSearchController:(UISearchController *)searchController +{ + [self.tableView reloadData]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.h new file mode 100755 index 0000000..1f075bf --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.h @@ -0,0 +1,63 @@ +// +// FLEXNetworkRecorder.h +// Flipboard +// +// Created by Ryan Olson on 2/4/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import + +// Notifications posted when the record is updated +extern NSString *const kFLEXNetworkRecorderNewTransactionNotification; +extern NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification; +extern NSString *const kFLEXNetworkRecorderUserInfoTransactionKey; +extern NSString *const kFLEXNetworkRecorderTransactionsClearedNotification; + +@class FLEXNetworkTransaction; + +@interface FLEXNetworkRecorder : NSObject + +/// In general, it only makes sense to have one recorder for the entire application. ++ (instancetype)defaultRecorder; + +/// Defaults to 25 MB if never set. Values set here are presisted across launches of the app. +@property (nonatomic, assign) NSUInteger responseCacheByteLimit; + +/// If NO, the recorder not cache will not cache response for content types with an "image", "video", or "audio" prefix. +@property (nonatomic, assign) BOOL shouldCacheMediaResponses; + +// Accessing recorded network activity + +/// Array of FLEXNetworkTransaction objects ordered by start time with the newest first. +- (NSArray *)networkTransactions; + +/// The full response data IFF it hasn't been purged due to memory pressure. +- (NSData *)cachedResponseBodyForTransaction:(FLEXNetworkTransaction *)transaction; + +/// Dumps all network transactions and cached response bodies. +- (void)clearRecordedActivity; + + +// Recording network activity + +/// Call when app is about to send HTTP request. +- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID request:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse; + +/// Call when HTTP response is available. +- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response; + +/// Call when data chunk is received over the network. +- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength; + +/// Call when HTTP request has finished loading. +- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody; + +/// Call when HTTP request has failed to load. +- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error; + +/// Call to set the request mechanism anytime after recordRequestWillBeSent... has been called. +/// This string can be set to anything useful about the API used to make the request. +- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.m new file mode 100755 index 0000000..a36bf32 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkRecorder.m @@ -0,0 +1,262 @@ +// +// FLEXNetworkRecorder.m +// Flipboard +// +// Created by Ryan Olson on 2/4/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXNetworkRecorder.h" +#import "FLEXNetworkCurlLogger.h" +#import "FLEXNetworkTransaction.h" +#import "FLEXUtility.h" +#import "FLEXResources.h" + +NSString *const kFLEXNetworkRecorderNewTransactionNotification = @"kFLEXNetworkRecorderNewTransactionNotification"; +NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification = @"kFLEXNetworkRecorderTransactionUpdatedNotification"; +NSString *const kFLEXNetworkRecorderUserInfoTransactionKey = @"transaction"; +NSString *const kFLEXNetworkRecorderTransactionsClearedNotification = @"kFLEXNetworkRecorderTransactionsClearedNotification"; + +NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.responseCacheLimit"; + +@interface FLEXNetworkRecorder () + +@property (nonatomic, strong) NSCache *responseCache; +@property (nonatomic, strong) NSMutableArray *orderedTransactions; +@property (nonatomic, strong) NSMutableDictionary *networkTransactionsForRequestIdentifiers; +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + +@implementation FLEXNetworkRecorder + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.responseCache = [[NSCache alloc] init]; + NSUInteger responseCacheLimit = [[[NSUserDefaults standardUserDefaults] objectForKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey] unsignedIntegerValue]; + if (responseCacheLimit) { + [self.responseCache setTotalCostLimit:responseCacheLimit]; + } else { + // Default to 25 MB max. The cache will purge earlier if there is memory pressure. + [self.responseCache setTotalCostLimit:25 * 1024 * 1024]; + } + self.orderedTransactions = [NSMutableArray array]; + self.networkTransactionsForRequestIdentifiers = [NSMutableDictionary dictionary]; + + // Serial queue used because we use mutable objects that are not thread safe + self.queue = dispatch_queue_create("com.flex.FLEXNetworkRecorder", DISPATCH_QUEUE_SERIAL); + } + return self; +} + ++ (instancetype)defaultRecorder +{ + static FLEXNetworkRecorder *defaultRecorder = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + defaultRecorder = [[[self class] alloc] init]; + }); + return defaultRecorder; +} + +#pragma mark - Public Data Access + +- (NSUInteger)responseCacheByteLimit +{ + return [self.responseCache totalCostLimit]; +} + +- (void)setResponseCacheByteLimit:(NSUInteger)responseCacheByteLimit +{ + [self.responseCache setTotalCostLimit:responseCacheByteLimit]; + [[NSUserDefaults standardUserDefaults] setObject:@(responseCacheByteLimit) forKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey]; +} + +- (NSArray *)networkTransactions +{ + __block NSArray *transactions = nil; + dispatch_sync(self.queue, ^{ + transactions = [self.orderedTransactions copy]; + }); + return transactions; +} + +- (NSData *)cachedResponseBodyForTransaction:(FLEXNetworkTransaction *)transaction +{ + return [self.responseCache objectForKey:transaction.requestID]; +} + +- (void)clearRecordedActivity +{ + dispatch_async(self.queue, ^{ + [self.responseCache removeAllObjects]; + [self.orderedTransactions removeAllObjects]; + [self.networkTransactionsForRequestIdentifiers removeAllObjects]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:kFLEXNetworkRecorderTransactionsClearedNotification object:self]; + }); + }); +} + +#pragma mark - Network Events + +- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID request:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse +{ + NSDate *startDate = [NSDate date]; + + if (redirectResponse) { + [self recordResponseReceivedWithRequestID:requestID response:redirectResponse]; + [self recordLoadingFinishedWithRequestID:requestID responseBody:nil]; + } + + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = [[FLEXNetworkTransaction alloc] init]; + transaction.requestID = requestID; + transaction.request = request; + transaction.startTime = startDate; + + [self.orderedTransactions insertObject:transaction atIndex:0]; + [self.networkTransactionsForRequestIdentifiers setObject:transaction forKey:requestID]; + transaction.transactionState = FLEXNetworkTransactionStateAwaitingResponse; + + [self postNewTransactionNotificationWithTransaction:transaction]; + }); +} + +- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response +{ + NSDate *responseDate = [NSDate date]; + + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.response = response; + transaction.transactionState = FLEXNetworkTransactionStateReceivingData; + transaction.latency = -[transaction.startTime timeIntervalSinceDate:responseDate]; + + [self postUpdateNotificationForTransaction:transaction]; + }); +} + +- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.receivedDataLength += dataLength; + + [self postUpdateNotificationForTransaction:transaction]; + }); +} + +- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody +{ + NSDate *finishedDate = [NSDate date]; + + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.transactionState = FLEXNetworkTransactionStateFinished; + transaction.duration = -[transaction.startTime timeIntervalSinceDate:finishedDate]; + + BOOL shouldCache = [responseBody length] > 0; + if (!self.shouldCacheMediaResponses) { + NSArray *ignoredMIMETypePrefixes = @[ @"audio", @"image", @"video" ]; + for (NSString *ignoredPrefix in ignoredMIMETypePrefixes) { + shouldCache = shouldCache && ![transaction.response.MIMEType hasPrefix:ignoredPrefix]; + } + } + + if (shouldCache) { + [self.responseCache setObject:responseBody forKey:requestID cost:[responseBody length]]; + } + + NSString *mimeType = transaction.response.MIMEType; + if ([mimeType hasPrefix:@"image/"] && [responseBody length] > 0) { + // Thumbnail image previews on a separate background queue + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSInteger maxPixelDimension = [[UIScreen mainScreen] scale] * 32.0; + transaction.responseThumbnail = [FLEXUtility thumbnailedImageWithMaxPixelDimension:maxPixelDimension fromImageData:responseBody]; + [self postUpdateNotificationForTransaction:transaction]; + }); + } else if ([mimeType isEqual:@"application/json"]) { + transaction.responseThumbnail = [FLEXResources jsonIcon]; + } else if ([mimeType isEqual:@"text/plain"]){ + transaction.responseThumbnail = [FLEXResources textPlainIcon]; + } else if ([mimeType isEqual:@"text/html"]) { + transaction.responseThumbnail = [FLEXResources htmlIcon]; + } else if ([mimeType isEqual:@"application/x-plist"]) { + transaction.responseThumbnail = [FLEXResources plistIcon]; + } else if ([mimeType isEqual:@"application/octet-stream"] || [mimeType isEqual:@"application/binary"]) { + transaction.responseThumbnail = [FLEXResources binaryIcon]; + } else if ([mimeType rangeOfString:@"javascript"].length > 0) { + transaction.responseThumbnail = [FLEXResources jsIcon]; + } else if ([mimeType rangeOfString:@"xml"].length > 0) { + transaction.responseThumbnail = [FLEXResources xmlIcon]; + } else if ([mimeType hasPrefix:@"audio"]) { + transaction.responseThumbnail = [FLEXResources audioIcon]; + } else if ([mimeType hasPrefix:@"video"]) { + transaction.responseThumbnail = [FLEXResources videoIcon]; + } else if ([mimeType hasPrefix:@"text"]) { + transaction.responseThumbnail = [FLEXResources textIcon]; + } + + [self postUpdateNotificationForTransaction:transaction]; + }); +} + +- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.transactionState = FLEXNetworkTransactionStateFailed; + transaction.duration = -[transaction.startTime timeIntervalSinceNow]; + transaction.error = error; + + [self postUpdateNotificationForTransaction:transaction]; + }); +} + +- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.requestMechanism = mechanism; + + [self postUpdateNotificationForTransaction:transaction]; + }); +} + +#pragma mark Notification Posting + +- (void)postNewTransactionNotificationWithTransaction:(FLEXNetworkTransaction *)transaction +{ + dispatch_async(dispatch_get_main_queue(), ^{ + NSDictionary *userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction }; + [[NSNotificationCenter defaultCenter] postNotificationName:kFLEXNetworkRecorderNewTransactionNotification object:self userInfo:userInfo]; + }); +} + +- (void)postUpdateNotificationForTransaction:(FLEXNetworkTransaction *)transaction +{ + dispatch_async(dispatch_get_main_queue(), ^{ + NSDictionary *userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction }; + [[NSNotificationCenter defaultCenter] postNotificationName:kFLEXNetworkRecorderTransactionUpdatedNotification object:self userInfo:userInfo]; + }); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.h new file mode 100755 index 0000000..331a2d8 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.h @@ -0,0 +1,13 @@ +// +// FLEXNetworkSettingsTableViewController.h +// FLEXInjected +// +// Created by Ryan Olson on 2/20/15. +// +// + +#import + +@interface FLEXNetworkSettingsTableViewController : UITableViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.m new file mode 100755 index 0000000..3586c5d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkSettingsTableViewController.m @@ -0,0 +1,186 @@ +// +// FLEXNetworkSettingsTableViewController.m +// FLEXInjected +// +// Created by Ryan Olson on 2/20/15. +// +// + +#import "FLEXNetworkSettingsTableViewController.h" +#import "FLEXNetworkObserver.h" +#import "FLEXNetworkRecorder.h" +#import "FLEXUtility.h" + +@interface FLEXNetworkSettingsTableViewController () + +@property (nonatomic, copy) NSArray *cells; + +@property (nonatomic, strong) UITableViewCell *cacheLimitCell; + +@end + +@implementation FLEXNetworkSettingsTableViewController + +- (instancetype)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self) { + + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + NSMutableArray *mutableCells = [NSMutableArray array]; + + UITableViewCell *networkDebuggingCell = [self switchCellWithTitle:@"Network Debugging" toggleAction:@selector(networkDebuggingToggled:) isOn:[FLEXNetworkObserver isEnabled]]; + [mutableCells addObject:networkDebuggingCell]; + + UITableViewCell *cacheMediaResponsesCell = [self switchCellWithTitle:@"Cache Media Responses" toggleAction:@selector(cacheMediaResponsesToggled:) isOn:NO]; + [mutableCells addObject:cacheMediaResponsesCell]; + + NSUInteger currentCacheLimit = [[FLEXNetworkRecorder defaultRecorder] responseCacheByteLimit]; + const NSUInteger fiftyMega = 50 * 1024 * 1024; + NSString *cacheLimitTitle = [self titleForCacheLimitCellWithValue:currentCacheLimit]; + self.cacheLimitCell = [self sliderCellWithTitle:cacheLimitTitle changedAction:@selector(cacheLimitAdjusted:) minimum:0.0 maximum:fiftyMega initialValue:currentCacheLimit]; + [mutableCells addObject:self.cacheLimitCell]; + + UITableViewCell *clearRecordedRequestsCell = [self buttonCellWithTitle:@"❌ Clear Recorded Requests" touchUpAction:@selector(clearRequestsTapped:) isDestructive:YES]; + [mutableCells addObject:clearRecordedRequestsCell]; + + self.cells = mutableCells; +} + +#pragma mark - Settings Actions + +- (void)networkDebuggingToggled:(UISwitch *)sender +{ + [FLEXNetworkObserver setEnabled:sender.isOn]; +} + +- (void)cacheMediaResponsesToggled:(UISwitch *)sender +{ + [[FLEXNetworkRecorder defaultRecorder] setShouldCacheMediaResponses:sender.isOn]; +} + +- (void)cacheLimitAdjusted:(UISlider *)sender +{ + [[FLEXNetworkRecorder defaultRecorder] setResponseCacheByteLimit:sender.value]; + self.cacheLimitCell.textLabel.text = [self titleForCacheLimitCellWithValue:sender.value]; +} + +- (void)clearRequestsTapped:(UIButton *)sender +{ + UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Clear Recorded Requests" otherButtonTitles:nil]; + [actionSheet showInView:self.view]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.cells count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return self.cells[indexPath.row]; +} + +#pragma mark - UIActionSheetDelegate + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex != actionSheet.cancelButtonIndex) { + [[FLEXNetworkRecorder defaultRecorder] clearRecordedActivity]; + } +} + +#pragma mark - Helpers + +- (UITableViewCell *)switchCellWithTitle:(NSString *)title toggleAction:(SEL)toggleAction isOn:(BOOL)isOn +{ + UITableViewCell *cell = [[UITableViewCell alloc] init]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.text = title; + cell.textLabel.font = [[self class] cellTitleFont]; + + UISwitch *theSwitch = [[UISwitch alloc] init]; + theSwitch.on = isOn; + [theSwitch addTarget:self action:toggleAction forControlEvents:UIControlEventValueChanged]; + + CGFloat switchOriginY = round((cell.contentView.frame.size.height - theSwitch.frame.size.height) / 2.0); + CGFloat switchOriginX = CGRectGetMaxX(cell.contentView.frame) - theSwitch.frame.size.width - self.tableView.separatorInset.left; + theSwitch.frame = CGRectMake(switchOriginX, switchOriginY, theSwitch.frame.size.width, theSwitch.frame.size.height); + theSwitch.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + [cell.contentView addSubview:theSwitch]; + + return cell; +} + +- (UITableViewCell *)buttonCellWithTitle:(NSString *)title touchUpAction:(SEL)action isDestructive:(BOOL)isDestructive +{ + UITableViewCell *buttonCell = [[UITableViewCell alloc] init]; + buttonCell.selectionStyle = UITableViewCellSelectionStyleNone; + + UIButton *actionButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [actionButton setTitle:title forState:UIControlStateNormal]; + if (isDestructive) { + actionButton.tintColor = [UIColor redColor]; + } + actionButton.titleLabel.font = [[self class] cellTitleFont];; + [actionButton addTarget:self action:@selector(clearRequestsTapped:) forControlEvents:UIControlEventTouchUpInside]; + + [buttonCell.contentView addSubview:actionButton]; + actionButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + actionButton.frame = buttonCell.contentView.frame; + actionButton.contentEdgeInsets = UIEdgeInsetsMake(0.0, self.tableView.separatorInset.left, 0.0, self.tableView.separatorInset.left); + actionButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + + return buttonCell; +} + +- (NSString *)titleForCacheLimitCellWithValue:(long long)cacheLimit +{ + NSInteger limitInMB = round(cacheLimit / (1024 * 1024)); + return [NSString stringWithFormat:@"Cache Limit (%ld MB)", (long)limitInMB]; +} + +- (UITableViewCell *)sliderCellWithTitle:(NSString *)title changedAction:(SEL)changedAction minimum:(CGFloat)minimum maximum:(CGFloat)maximum initialValue:(CGFloat)initialValue +{ + UITableViewCell *sliderCell = [[UITableViewCell alloc] init]; + sliderCell.selectionStyle = UITableViewCellSelectionStyleNone; + sliderCell.textLabel.text = title; + sliderCell.textLabel.font = [[self class] cellTitleFont]; + + UISlider *slider = [[UISlider alloc] init]; + slider.minimumValue = minimum; + slider.maximumValue = maximum; + slider.value = initialValue; + [slider addTarget:self action:changedAction forControlEvents:UIControlEventValueChanged]; + [slider sizeToFit]; + + CGFloat sliderWidth = round(sliderCell.contentView.frame.size.width * 2.0 / 5.0); + CGFloat sliderOriginY = round((sliderCell.contentView.frame.size.height - slider.frame.size.height) / 2.0); + CGFloat sliderOriginX = CGRectGetMaxX(sliderCell.contentView.frame) - sliderWidth - self.tableView.separatorInset.left; + slider.frame = CGRectMake(sliderOriginX, sliderOriginY, sliderWidth, slider.frame.size.height); + slider.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + [sliderCell.contentView addSubview:slider]; + + return sliderCell; +} + ++ (UIFont *)cellTitleFont +{ + return [FLEXUtility defaultFontOfSize:14.0]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.h new file mode 100755 index 0000000..8c9d000 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.h @@ -0,0 +1,44 @@ +// +// FLEXNetworkTransaction.h +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import +#import "UIKit/UIKit.h" + +typedef NS_ENUM(NSInteger, FLEXNetworkTransactionState) { + FLEXNetworkTransactionStateUnstarted, + FLEXNetworkTransactionStateAwaitingResponse, + FLEXNetworkTransactionStateReceivingData, + FLEXNetworkTransactionStateFinished, + FLEXNetworkTransactionStateFailed +}; + +@interface FLEXNetworkTransaction : NSObject + +@property (nonatomic, copy) NSString *requestID; + +@property (nonatomic, strong) NSURLRequest *request; +@property (nonatomic, strong) NSURLResponse *response; +@property (nonatomic, copy) NSString *requestMechanism; +@property (nonatomic, assign) FLEXNetworkTransactionState transactionState; +@property (nonatomic, strong) NSError *error; + +@property (nonatomic, strong) NSDate *startTime; +@property (nonatomic, assign) NSTimeInterval latency; +@property (nonatomic, assign) NSTimeInterval duration; + +@property (nonatomic, assign) int64_t receivedDataLength; + +/// Only applicable for image downloads. A small thumbnail to preview the full response. +@property (nonatomic, strong) UIImage *responseThumbnail; + +/// Populated lazily. Handles both normal HTTPBody data and HTTPBodyStreams. +@property (nonatomic, strong, readonly) NSData *cachedRequestBody; + ++ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.m new file mode 100755 index 0000000..87a9892 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransaction.m @@ -0,0 +1,80 @@ +// +// FLEXNetworkTransaction.m +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXNetworkTransaction.h" + +@interface FLEXNetworkTransaction () + +@property (nonatomic, strong, readwrite) NSData *cachedRequestBody; + +@end + +@implementation FLEXNetworkTransaction + +- (NSString *)description +{ + NSString *description = [super description]; + + description = [description stringByAppendingFormat:@" id = %@;", self.requestID]; + description = [description stringByAppendingFormat:@" url = %@;", self.request.URL]; + description = [description stringByAppendingFormat:@" duration = %f;", self.duration]; + description = [description stringByAppendingFormat:@" receivedDataLength = %lld", self.receivedDataLength]; + + return description; +} + +- (NSData *)cachedRequestBody { + if (!_cachedRequestBody) { + if (self.request.HTTPBody != nil) { + _cachedRequestBody = self.request.HTTPBody; + } else if ([self.request.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { + NSInputStream *bodyStream = [self.request.HTTPBodyStream copy]; + const NSUInteger bufferSize = 1024; + uint8_t buffer[bufferSize]; + NSMutableData *data = [NSMutableData data]; + [bodyStream open]; + NSInteger readBytes = 0; + do { + readBytes = [bodyStream read:buffer maxLength:bufferSize]; + [data appendBytes:buffer length:readBytes]; + } while (readBytes > 0); + [bodyStream close]; + _cachedRequestBody = data; + } + } + return _cachedRequestBody; +} + ++ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state +{ + NSString *readableString = nil; + switch (state) { + case FLEXNetworkTransactionStateUnstarted: + readableString = @"Unstarted"; + break; + + case FLEXNetworkTransactionStateAwaitingResponse: + readableString = @"Awaiting Response"; + break; + + case FLEXNetworkTransactionStateReceivingData: + readableString = @"Receiving Data"; + break; + + case FLEXNetworkTransactionStateFinished: + readableString = @"Finished"; + break; + + case FLEXNetworkTransactionStateFailed: + readableString = @"Failed"; + break; + } + return readableString; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.h new file mode 100755 index 0000000..2e065fa --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.h @@ -0,0 +1,17 @@ +// +// FLEXNetworkTransactionDetailTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2/10/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import + +@class FLEXNetworkTransaction; + +@interface FLEXNetworkTransactionDetailTableViewController : UITableViewController + +@property (nonatomic, strong) FLEXNetworkTransaction *transaction; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.m new file mode 100755 index 0000000..57ee4e7 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionDetailTableViewController.m @@ -0,0 +1,465 @@ +// +// FLEXNetworkTransactionDetailTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2/10/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXNetworkTransactionDetailTableViewController.h" +#import "FLEXNetworkCurlLogger.h" +#import "FLEXNetworkRecorder.h" +#import "FLEXNetworkTransaction.h" +#import "FLEXWebViewController.h" +#import "FLEXImagePreviewViewController.h" +#import "FLEXMultilineTableViewCell.h" +#import "FLEXUtility.h" + +@interface FLEXNetworkDetailSection : NSObject + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSArray *rows; + +@end + +@implementation FLEXNetworkDetailSection + +@end + +typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void); + +@interface FLEXNetworkDetailRow : NSObject + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *detailText; +@property (nonatomic, copy) FLEXNetworkDetailRowSelectionFuture selectionFuture; + +@end + +@implementation FLEXNetworkDetailRow + +@end + +@interface FLEXNetworkTransactionDetailTableViewController () + +@property (nonatomic, copy) NSArray *sections; + +@end + +@implementation FLEXNetworkTransactionDetailTableViewController + +- (instancetype)initWithStyle:(UITableViewStyle)style +{ + // Force grouped style + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTransactionUpdatedNotification:) name:kFLEXNetworkRecorderTransactionUpdatedNotification object:nil]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Copy curl" style:UIBarButtonItemStylePlain target:self action:@selector(copyButtonPressed:)]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.tableView registerClass:[FLEXMultilineTableViewCell class] forCellReuseIdentifier:kFLEXMultilineTableViewCellIdentifier]; +} + +- (void)setTransaction:(FLEXNetworkTransaction *)transaction +{ + if (![_transaction isEqual:transaction]) { + _transaction = transaction; + self.title = [transaction.request.URL lastPathComponent]; + [self rebuildTableSections]; + } +} + +- (void)setSections:(NSArray *)sections +{ + if (![_sections isEqual:sections]) { + _sections = [sections copy]; + [self.tableView reloadData]; + } +} + +- (void)rebuildTableSections +{ + NSMutableArray *sections = [NSMutableArray array]; + + FLEXNetworkDetailSection *generalSection = [[self class] generalSectionForTransaction:self.transaction]; + if ([generalSection.rows count] > 0) { + [sections addObject:generalSection]; + } + FLEXNetworkDetailSection *requestHeadersSection = [[self class] requestHeadersSectionForTransaction:self.transaction]; + if ([requestHeadersSection.rows count] > 0) { + [sections addObject:requestHeadersSection]; + } + FLEXNetworkDetailSection *queryParametersSection = [[self class] queryParametersSectionForTransaction:self.transaction]; + if ([queryParametersSection.rows count] > 0) { + [sections addObject:queryParametersSection]; + } + FLEXNetworkDetailSection *postBodySection = [[self class] postBodySectionForTransaction:self.transaction]; + if ([postBodySection.rows count] > 0) { + [sections addObject:postBodySection]; + } + FLEXNetworkDetailSection *responseHeadersSection = [[self class] responseHeadersSectionForTransaction:self.transaction]; + if ([responseHeadersSection.rows count] > 0) { + [sections addObject:responseHeadersSection]; + } + + self.sections = sections; +} + +- (void)handleTransactionUpdatedNotification:(NSNotification *)notification +{ + FLEXNetworkTransaction *transaction = [[notification userInfo] objectForKey:kFLEXNetworkRecorderUserInfoTransactionKey]; + if (transaction == self.transaction) { + [self rebuildTableSections]; + } +} + +- (void)copyButtonPressed:(id)sender +{ + [[UIPasteboard generalPasteboard] setString:[FLEXNetworkCurlLogger curlCommandString:_transaction.request]]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [self.sections count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + FLEXNetworkDetailSection *sectionModel = self.sections[section]; + return [sectionModel.rows count]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + FLEXNetworkDetailSection *sectionModel = self.sections[section]; + return sectionModel.title; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXMultilineTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXMultilineTableViewCellIdentifier forIndexPath:indexPath]; + + FLEXNetworkDetailRow *rowModel = [self rowModelAtIndexPath:indexPath]; + + cell.textLabel.attributedText = [[self class] attributedTextForRow:rowModel]; + cell.accessoryType = rowModel.selectionFuture ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.selectionStyle = rowModel.selectionFuture ? UITableViewCellSelectionStyleDefault : UITableViewCellSelectionStyleNone; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXNetworkDetailRow *rowModel = [self rowModelAtIndexPath:indexPath]; + + UIViewController *viewControllerToPush = nil; + if (rowModel.selectionFuture) { + viewControllerToPush = rowModel.selectionFuture(); + } + + if (viewControllerToPush) { + [self.navigationController pushViewController:viewControllerToPush animated:YES]; + } + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXNetworkDetailRow *row = [self rowModelAtIndexPath:indexPath]; + NSAttributedString *attributedText = [[self class] attributedTextForRow:row]; + BOOL showsAccessory = row.selectionFuture != nil; + return [FLEXMultilineTableViewCell preferredHeightWithAttributedText:attributedText inTableViewWidth:self.tableView.bounds.size.width style:UITableViewStyleGrouped showsAccessory:showsAccessory]; +} + +- (FLEXNetworkDetailRow *)rowModelAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXNetworkDetailSection *sectionModel = self.sections[indexPath.section]; + return sectionModel.rows[indexPath.row]; +} + +#pragma mark - Cell Copying + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return YES; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + return action == @selector(copy:); +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + if (action == @selector(copy:)) { + FLEXNetworkDetailRow *row = [self rowModelAtIndexPath:indexPath]; + [[UIPasteboard generalPasteboard] setString:row.detailText]; + } +} + +#pragma mark - View Configuration + ++ (NSAttributedString *)attributedTextForRow:(FLEXNetworkDetailRow *)row +{ + NSDictionary *titleAttributes = @{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Medium" size:12.0], + NSForegroundColorAttributeName : [UIColor colorWithWhite:0.5 alpha:1.0] }; + NSDictionary *detailAttributes = @{ NSFontAttributeName : [FLEXUtility defaultTableViewCellLabelFont], + NSForegroundColorAttributeName : [UIColor blackColor] }; + + NSString *title = [NSString stringWithFormat:@"%@: ", row.title]; + NSString *detailText = row.detailText ?: @""; + NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init]; + [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:title attributes:titleAttributes]]; + [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:detailText attributes:detailAttributes]]; + + return attributedText; +} + +#pragma mark - Table Data Generation + ++ (FLEXNetworkDetailSection *)generalSectionForTransaction:(FLEXNetworkTransaction *)transaction +{ + NSMutableArray *rows = [NSMutableArray array]; + + FLEXNetworkDetailRow *requestURLRow = [[FLEXNetworkDetailRow alloc] init]; + requestURLRow.title = @"Request URL"; + NSURL *url = transaction.request.URL; + requestURLRow.detailText = url.absoluteString; + requestURLRow.selectionFuture = ^{ + UIViewController *urlWebViewController = [[FLEXWebViewController alloc] initWithURL:url]; + urlWebViewController.title = url.absoluteString; + return urlWebViewController; + }; + [rows addObject:requestURLRow]; + + FLEXNetworkDetailRow *requestMethodRow = [[FLEXNetworkDetailRow alloc] init]; + requestMethodRow.title = @"Request Method"; + requestMethodRow.detailText = transaction.request.HTTPMethod; + [rows addObject:requestMethodRow]; + + if ([transaction.cachedRequestBody length] > 0) { + FLEXNetworkDetailRow *postBodySizeRow = [[FLEXNetworkDetailRow alloc] init]; + postBodySizeRow.title = @"Request Body Size"; + postBodySizeRow.detailText = [NSByteCountFormatter stringFromByteCount:[transaction.cachedRequestBody length] countStyle:NSByteCountFormatterCountStyleBinary]; + [rows addObject:postBodySizeRow]; + + FLEXNetworkDetailRow *postBodyRow = [[FLEXNetworkDetailRow alloc] init]; + postBodyRow.title = @"Request Body"; + postBodyRow.detailText = @"tap to view"; + postBodyRow.selectionFuture = ^{ + NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"]; + UIViewController *detailViewController = [self detailViewControllerForMIMEType:contentType data:[self postBodyDataForTransaction:transaction]]; + if (detailViewController) { + detailViewController.title = @"Request Body"; + } else { + NSString *alertMessage = [NSString stringWithFormat:@"FLEX does not have a viewer for request body data with MIME type: %@", [transaction.request valueForHTTPHeaderField:@"Content-Type"]]; + [[[UIAlertView alloc] initWithTitle:@"Can't View Body Data" message:alertMessage delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } + return detailViewController; + }; + [rows addObject:postBodyRow]; + } + + NSString *statusCodeString = [FLEXUtility statusCodeStringFromURLResponse:transaction.response]; + if ([statusCodeString length] > 0) { + FLEXNetworkDetailRow *statusCodeRow = [[FLEXNetworkDetailRow alloc] init]; + statusCodeRow.title = @"Status Code"; + statusCodeRow.detailText = statusCodeString; + [rows addObject:statusCodeRow]; + } + + if (transaction.error) { + FLEXNetworkDetailRow *errorRow = [[FLEXNetworkDetailRow alloc] init]; + errorRow.title = @"Error"; + errorRow.detailText = transaction.error.localizedDescription; + [rows addObject:errorRow]; + } + + FLEXNetworkDetailRow *responseBodyRow = [[FLEXNetworkDetailRow alloc] init]; + responseBodyRow.title = @"Response Body"; + NSData *responseData = [[FLEXNetworkRecorder defaultRecorder] cachedResponseBodyForTransaction:transaction]; + if ([responseData length] > 0) { + responseBodyRow.detailText = @"tap to view"; + // Avoid a long lived strong reference to the response data in case we need to purge it from the cache. + __weak NSData *weakResponseData = responseData; + responseBodyRow.selectionFuture = ^{ + UIViewController *responseBodyDetailViewController = nil; + NSData *strongResponseData = weakResponseData; + if (strongResponseData) { + responseBodyDetailViewController = [self detailViewControllerForMIMEType:transaction.response.MIMEType data:strongResponseData]; + if (!responseBodyDetailViewController) { + NSString *alertMessage = [NSString stringWithFormat:@"FLEX does not have a viewer for responses with MIME type: %@", transaction.response.MIMEType]; + [[[UIAlertView alloc] initWithTitle:@"Can't View Response" message:alertMessage delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } + responseBodyDetailViewController.title = @"Response"; + } else { + NSString *alertMessage = @"The response has been purged from the cache"; + [[[UIAlertView alloc] initWithTitle:@"Can't View Response" message:alertMessage delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + } + return responseBodyDetailViewController; + }; + } else { + BOOL emptyResponse = transaction.receivedDataLength == 0; + responseBodyRow.detailText = emptyResponse ? @"empty" : @"not in cache"; + } + [rows addObject:responseBodyRow]; + + FLEXNetworkDetailRow *responseSizeRow = [[FLEXNetworkDetailRow alloc] init]; + responseSizeRow.title = @"Response Size"; + responseSizeRow.detailText = [NSByteCountFormatter stringFromByteCount:transaction.receivedDataLength countStyle:NSByteCountFormatterCountStyleBinary]; + [rows addObject:responseSizeRow]; + + FLEXNetworkDetailRow *mimeTypeRow = [[FLEXNetworkDetailRow alloc] init]; + mimeTypeRow.title = @"MIME Type"; + mimeTypeRow.detailText = transaction.response.MIMEType; + [rows addObject:mimeTypeRow]; + + FLEXNetworkDetailRow *mechanismRow = [[FLEXNetworkDetailRow alloc] init]; + mechanismRow.title = @"Mechanism"; + mechanismRow.detailText = transaction.requestMechanism; + [rows addObject:mechanismRow]; + + NSDateFormatter *startTimeFormatter = [[NSDateFormatter alloc] init]; + startTimeFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; + + FLEXNetworkDetailRow *localStartTimeRow = [[FLEXNetworkDetailRow alloc] init]; + localStartTimeRow.title = [NSString stringWithFormat:@"Start Time (%@)", [[NSTimeZone localTimeZone] abbreviationForDate:transaction.startTime]]; + localStartTimeRow.detailText = [startTimeFormatter stringFromDate:transaction.startTime]; + [rows addObject:localStartTimeRow]; + + startTimeFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + + FLEXNetworkDetailRow *utcStartTimeRow = [[FLEXNetworkDetailRow alloc] init]; + utcStartTimeRow.title = @"Start Time (UTC)"; + utcStartTimeRow.detailText = [startTimeFormatter stringFromDate:transaction.startTime]; + [rows addObject:utcStartTimeRow]; + + FLEXNetworkDetailRow *unixStartTime = [[FLEXNetworkDetailRow alloc] init]; + unixStartTime.title = @"Unix Start Time"; + unixStartTime.detailText = [NSString stringWithFormat:@"%f", [transaction.startTime timeIntervalSince1970]]; + [rows addObject:unixStartTime]; + + FLEXNetworkDetailRow *durationRow = [[FLEXNetworkDetailRow alloc] init]; + durationRow.title = @"Total Duration"; + durationRow.detailText = [FLEXUtility stringFromRequestDuration:transaction.duration]; + [rows addObject:durationRow]; + + FLEXNetworkDetailRow *latencyRow = [[FLEXNetworkDetailRow alloc] init]; + latencyRow.title = @"Latency"; + latencyRow.detailText = [FLEXUtility stringFromRequestDuration:transaction.latency]; + [rows addObject:latencyRow]; + + FLEXNetworkDetailSection *generalSection = [[FLEXNetworkDetailSection alloc] init]; + generalSection.title = @"General"; + generalSection.rows = rows; + + return generalSection; +} + ++ (FLEXNetworkDetailSection *)requestHeadersSectionForTransaction:(FLEXNetworkTransaction *)transaction +{ + FLEXNetworkDetailSection *requestHeadersSection = [[FLEXNetworkDetailSection alloc] init]; + requestHeadersSection.title = @"Request Headers"; + requestHeadersSection.rows = [self networkDetailRowsFromDictionary:transaction.request.allHTTPHeaderFields]; + + return requestHeadersSection; +} + ++ (FLEXNetworkDetailSection *)postBodySectionForTransaction:(FLEXNetworkTransaction *)transaction +{ + FLEXNetworkDetailSection *postBodySection = [[FLEXNetworkDetailSection alloc] init]; + postBodySection.title = @"Request Body Parameters"; + if ([transaction.cachedRequestBody length] > 0) { + NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"]; + if ([contentType hasPrefix:@"application/x-www-form-urlencoded"]) { + NSString *bodyString = [[NSString alloc] initWithData:[self postBodyDataForTransaction:transaction] encoding:NSUTF8StringEncoding]; + postBodySection.rows = [self networkDetailRowsFromDictionary:[FLEXUtility dictionaryFromQuery:bodyString]]; + } + } + return postBodySection; +} + ++ (FLEXNetworkDetailSection *)queryParametersSectionForTransaction:(FLEXNetworkTransaction *)transaction +{ + NSDictionary *queryDictionary = [FLEXUtility dictionaryFromQuery:transaction.request.URL.query]; + FLEXNetworkDetailSection *querySection = [[FLEXNetworkDetailSection alloc] init]; + querySection.title = @"Query Parameters"; + querySection.rows = [self networkDetailRowsFromDictionary:queryDictionary]; + + return querySection; +} + ++ (FLEXNetworkDetailSection *)responseHeadersSectionForTransaction:(FLEXNetworkTransaction *)transaction +{ + FLEXNetworkDetailSection *responseHeadersSection = [[FLEXNetworkDetailSection alloc] init]; + responseHeadersSection.title = @"Response Headers"; + if ([transaction.response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)transaction.response; + responseHeadersSection.rows = [self networkDetailRowsFromDictionary:httpResponse.allHeaderFields]; + } + return responseHeadersSection; +} + ++ (NSArray *)networkDetailRowsFromDictionary:(NSDictionary *)dictionary +{ + NSMutableArray *rows = [NSMutableArray arrayWithCapacity:[dictionary count]]; + NSArray *sortedKeys = [[dictionary allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + for (NSString *key in sortedKeys) { + NSString *value = dictionary[key]; + FLEXNetworkDetailRow *row = [[FLEXNetworkDetailRow alloc] init]; + row.title = key; + row.detailText = [value description]; + [rows addObject:row]; + } + return [rows copy]; +} + ++ (UIViewController *)detailViewControllerForMIMEType:(NSString *)mimeType data:(NSData *)data +{ + // FIXME (RKO): Don't rely on UTF8 string encoding + UIViewController *detailViewController = nil; + if ([FLEXUtility isValidJSONData:data]) { + NSString *prettyJSON = [FLEXUtility prettyJSONStringFromData:data]; + if ([prettyJSON length] > 0) { + detailViewController = [[FLEXWebViewController alloc] initWithText:prettyJSON]; + } + } else if ([mimeType hasPrefix:@"image/"]) { + UIImage *image = [UIImage imageWithData:data]; + detailViewController = [[FLEXImagePreviewViewController alloc] initWithImage:image]; + } else if ([mimeType isEqual:@"application/x-plist"]) { + id propertyList = [NSPropertyListSerialization propertyListWithData:data options:0 format:NULL error:NULL]; + detailViewController = [[FLEXWebViewController alloc] initWithText:[propertyList description]]; + } + + // Fall back to trying to show the response as text + if (!detailViewController) { + NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if ([text length] > 0) { + detailViewController = [[FLEXWebViewController alloc] initWithText:text]; + } + } + return detailViewController; +} + ++ (NSData *)postBodyDataForTransaction:(FLEXNetworkTransaction *)transaction +{ + NSData *bodyData = transaction.cachedRequestBody; + if ([bodyData length] > 0) { + NSString *contentEncoding = [transaction.request valueForHTTPHeaderField:@"Content-Encoding"]; + if ([contentEncoding rangeOfString:@"deflate" options:NSCaseInsensitiveSearch].length > 0 || [contentEncoding rangeOfString:@"gzip" options:NSCaseInsensitiveSearch].length > 0) { + bodyData = [FLEXUtility inflatedDataFromCompressedData:bodyData]; + } + } + return bodyData; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.h new file mode 100755 index 0000000..385573d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.h @@ -0,0 +1,21 @@ +// +// FLEXNetworkTransactionTableViewCell.h +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import + +extern NSString *const kFLEXNetworkTransactionCellIdentifier; + +@class FLEXNetworkTransaction; + +@interface FLEXNetworkTransactionTableViewCell : UITableViewCell + +@property (nonatomic, strong) FLEXNetworkTransaction *transaction; + ++ (CGFloat)preferredCellHeight; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.m new file mode 100755 index 0000000..3037989 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/FLEXNetworkTransactionTableViewCell.m @@ -0,0 +1,180 @@ +// +// FLEXNetworkTransactionTableViewCell.m +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright (c) 2015 Flipboard. All rights reserved. +// + +#import "FLEXNetworkTransactionTableViewCell.h" +#import "FLEXNetworkTransaction.h" +#import "FLEXUtility.h" +#import "FLEXResources.h" + +NSString *const kFLEXNetworkTransactionCellIdentifier = @"kFLEXNetworkTransactionCellIdentifier"; + +@interface FLEXNetworkTransactionTableViewCell () + +@property (nonatomic, strong) UIImageView *thumbnailImageView; +@property (nonatomic, strong) UILabel *nameLabel; +@property (nonatomic, strong) UILabel *pathLabel; +@property (nonatomic, strong) UILabel *transactionDetailsLabel; + +@end + +@implementation FLEXNetworkTransactionTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + self.nameLabel = [[UILabel alloc] init]; + self.nameLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + [self.contentView addSubview:self.nameLabel]; + + self.pathLabel = [[UILabel alloc] init]; + self.pathLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + self.pathLabel.textColor = [UIColor colorWithWhite:0.4 alpha:1.0]; + [self.contentView addSubview:self.pathLabel]; + + self.thumbnailImageView = [[UIImageView alloc] init]; + self.thumbnailImageView.layer.borderColor = [[UIColor blackColor] CGColor]; + self.thumbnailImageView.layer.borderWidth = 1.0; + self.thumbnailImageView.contentMode = UIViewContentModeScaleAspectFit; + [self.contentView addSubview:self.thumbnailImageView]; + + self.transactionDetailsLabel = [[UILabel alloc] init]; + self.transactionDetailsLabel.font = [FLEXUtility defaultFontOfSize:10.0]; + self.transactionDetailsLabel.textColor = [UIColor colorWithWhite:0.65 alpha:1.0]; + [self.contentView addSubview:self.transactionDetailsLabel]; + } + return self; +} + +- (void)setTransaction:(FLEXNetworkTransaction *)transaction +{ + if (_transaction != transaction) { + _transaction = transaction; + [self setNeedsLayout]; + } +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + const CGFloat kVerticalPadding = 8.0; + const CGFloat kLeftPadding = 10.0; + const CGFloat kImageDimension = 32.0; + + CGFloat thumbnailOriginY = round((self.contentView.bounds.size.height - kImageDimension) / 2.0); + self.thumbnailImageView.frame = CGRectMake(kLeftPadding, thumbnailOriginY, kImageDimension, kImageDimension); + self.thumbnailImageView.image = self.transaction.responseThumbnail; + + CGFloat textOriginX = CGRectGetMaxX(self.thumbnailImageView.frame) + kLeftPadding; + CGFloat availableTextWidth = self.contentView.bounds.size.width - textOriginX; + + self.nameLabel.text = [self nameLabelText]; + CGSize nameLabelPreferredSize = [self.nameLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; + self.nameLabel.frame = CGRectMake(textOriginX, kVerticalPadding, availableTextWidth, nameLabelPreferredSize.height); + self.nameLabel.textColor = self.transaction.error ? [UIColor redColor] : [UIColor blackColor]; + + self.pathLabel.text = [self pathLabelText]; + CGSize pathLabelPreferredSize = [self.pathLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; + CGFloat pathLabelOriginY = ceil((self.contentView.bounds.size.height - pathLabelPreferredSize.height) / 2.0); + self.pathLabel.frame = CGRectMake(textOriginX, pathLabelOriginY, availableTextWidth, pathLabelPreferredSize.height); + + self.transactionDetailsLabel.text = [self transactionDetailsLabelText]; + CGSize transactionLabelPreferredSize = [self.transactionDetailsLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; + CGFloat transactionDetailsOriginX = textOriginX; + CGFloat transactionDetailsLabelOriginY = CGRectGetMaxY(self.contentView.bounds) - kVerticalPadding - transactionLabelPreferredSize.height; + CGFloat transactionDetailsLabelWidth = self.contentView.bounds.size.width - transactionDetailsOriginX; + self.transactionDetailsLabel.frame = CGRectMake(transactionDetailsOriginX, transactionDetailsLabelOriginY, transactionDetailsLabelWidth, transactionLabelPreferredSize.height); +} + +- (NSString *)nameLabelText +{ + NSURL *url = self.transaction.request.URL; + NSString *name = [url lastPathComponent]; + if ([name length] == 0) { + name = @"/"; + } + NSString *query = [url query]; + if (query) { + name = [name stringByAppendingFormat:@"?%@", query]; + } + return name; +} + +- (NSString *)pathLabelText +{ + NSURL *url = self.transaction.request.URL; + NSMutableArray *mutablePathComponents = [[url pathComponents] mutableCopy]; + if ([mutablePathComponents count] > 0) { + [mutablePathComponents removeLastObject]; + } + NSString *path = [url host]; + for (NSString *pathComponent in mutablePathComponents) { + path = [path stringByAppendingPathComponent:pathComponent]; + } + return path; +} + +- (NSString *)transactionDetailsLabelText +{ + NSMutableArray *detailComponents = [NSMutableArray array]; + + NSString *timestamp = [[self class] timestampStringFromRequestDate:self.transaction.startTime]; + if ([timestamp length] > 0) { + [detailComponents addObject:timestamp]; + } + + // Omit method for GET (assumed as default) + NSString *httpMethod = self.transaction.request.HTTPMethod; + if ([httpMethod length] > 0) { + [detailComponents addObject:httpMethod]; + } + + if (self.transaction.transactionState == FLEXNetworkTransactionStateFinished || self.transaction.transactionState == FLEXNetworkTransactionStateFailed) { + NSString *statusCodeString = [FLEXUtility statusCodeStringFromURLResponse:self.transaction.response]; + if ([statusCodeString length] > 0) { + [detailComponents addObject:statusCodeString]; + } + + if (self.transaction.receivedDataLength > 0) { + NSString *responseSize = [NSByteCountFormatter stringFromByteCount:self.transaction.receivedDataLength countStyle:NSByteCountFormatterCountStyleBinary]; + [detailComponents addObject:responseSize]; + } + + NSString *totalDuration = [FLEXUtility stringFromRequestDuration:self.transaction.duration]; + NSString *latency = [FLEXUtility stringFromRequestDuration:self.transaction.latency]; + NSString *duration = [NSString stringWithFormat:@"%@ (%@)", totalDuration, latency]; + [detailComponents addObject:duration]; + } else { + // Unstarted, Awaiting Response, Receiving Data, etc. + NSString *state = [FLEXNetworkTransaction readableStringFromTransactionState:self.transaction.transactionState]; + [detailComponents addObject:state]; + } + + return [detailComponents componentsJoinedByString:@" ・ "]; +} + ++ (NSString *)timestampStringFromRequestDate:(NSDate *)date +{ + static NSDateFormatter *dateFormatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"HH:mm:ss"; + }); + return [dateFormatter stringFromDate:date]; +} + ++ (CGFloat)preferredCellHeight +{ + return 65.0; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.h new file mode 100755 index 0000000..6e8c1d3 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.h @@ -0,0 +1,29 @@ +// +// FLEXNetworkObserver.h +// Derived from: +// +// PDAFNetworkDomainController.h +// PonyDebugger +// +// Created by Mike Lewis on 2/27/12. +// +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import + +extern NSString *const kFLEXNetworkObserverEnabledStateChangedNotification; + +/// This class swizzles NSURLConnection and NSURLSession delegate methods to observe events in the URL loading system. +/// High level network events are sent to the default FLEXNetworkRecorder instance which maintains the request history and caches response bodies. +@interface FLEXNetworkObserver : NSObject + +/// Swizzling occurs when the observer is enabled for the first time. +/// This reduces the impact of FLEX if network debugging is not desired. +/// NOTE: this setting persists between launches of the app. ++ (void)setEnabled:(BOOL)enabled; ++ (BOOL)isEnabled; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.m new file mode 100755 index 0000000..8c626e1 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/FLEXNetworkObserver.m @@ -0,0 +1,1120 @@ +// +// FLEXNetworkObserver.m +// Derived from: +// +// PDAFNetworkDomainController.m +// PonyDebugger +// +// Created by Mike Lewis on 2/27/12. +// +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import "FLEXNetworkObserver.h" +#import "FLEXNetworkRecorder.h" +#import "FLEXUtility.h" + +#import +#import +#import + +NSString *const kFLEXNetworkObserverEnabledStateChangedNotification = @"kFLEXNetworkObserverEnabledStateChangedNotification"; +static NSString *const kFLEXNetworkObserverEnabledDefaultsKey = @"com.flex.FLEXNetworkObserver.enableOnLaunch"; + +typedef void (^NSURLSessionAsyncCompletion)(id fileURLOrData, NSURLResponse *response, NSError *error); + +@interface FLEXInternalRequestState : NSObject + +@property (nonatomic, copy) NSURLRequest *request; +@property (nonatomic, strong) NSMutableData *dataAccumulator; + +@end + +@implementation FLEXInternalRequestState + +@end + +@interface FLEXNetworkObserver (NSURLConnectionHelpers) + +- (void)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response delegate:(id )delegate; +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response delegate:(id )delegate; + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data delegate:(id )delegate; + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection delegate:(id )delegate; +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error delegate:(id )delegate; + +- (void)connectionWillCancel:(NSURLConnection *)connection; + +@end + + +@interface FLEXNetworkObserver (NSURLSessionTaskHelpers) + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask +didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite delegate:(id )delegate; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data delegate:(id )delegate; + +- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task; + +@end + +@interface FLEXNetworkObserver () + +@property (nonatomic, strong) NSMutableDictionary *requestStatesForRequestIDs; +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + +@implementation FLEXNetworkObserver + +#pragma mark - Public Methods + ++ (void)setEnabled:(BOOL)enabled +{ + BOOL previouslyEnabled = [self isEnabled]; + + [[NSUserDefaults standardUserDefaults] setBool:enabled forKey:kFLEXNetworkObserverEnabledDefaultsKey]; + + if (enabled) { + // Inject if needed. This injection is protected with a dispatch_once, so we're ok calling it multiple times. + // By doing the injection lazily, we keep the impact of the tool lower when this feature isn't enabled. + [self injectIntoAllNSURLConnectionDelegateClasses]; + } + + if (previouslyEnabled != enabled) { + [[NSNotificationCenter defaultCenter] postNotificationName:kFLEXNetworkObserverEnabledStateChangedNotification object:self]; + } +} + ++ (BOOL)isEnabled +{ + return [[[NSUserDefaults standardUserDefaults] objectForKey:kFLEXNetworkObserverEnabledDefaultsKey] boolValue]; +} + ++ (void)load +{ + // We don't want to do the swizzling from +load because not all the classes may be loaded at this point. + dispatch_async(dispatch_get_main_queue(), ^{ + if ([self isEnabled]) { + [self injectIntoAllNSURLConnectionDelegateClasses]; + } + }); +} + +#pragma mark - Statics + ++ (instancetype)sharedObserver +{ + static FLEXNetworkObserver *sharedObserver = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedObserver = [[[self class] alloc] init]; + }); + return sharedObserver; +} + ++ (NSString *)nextRequestID +{ + return [[NSUUID UUID] UUIDString]; +} + +#pragma mark Delegate Injection Convenience Methods + +/// All swizzled delegate methods should make use of this guard. +/// This will prevent duplicated sniffing when the original implementation calls up to a superclass implementation which we've also swizzled. +/// The superclass implementation (and implementations in classes above that) will be executed without inteference if called from the original implementation. ++ (void)sniffWithoutDuplicationForObject:(NSObject *)object selector:(SEL)selector sniffingBlock:(void (^)(void))sniffingBlock originalImplementationBlock:(void (^)(void))originalImplementationBlock +{ + // If we don't have an object to detect nested calls on, just run the original implmentation and bail. + // This case can happen if someone besides the URL loading system calls the delegate methods directly. + // See https://github.com/Flipboard/FLEX/issues/61 for an example. + if (!object) { + originalImplementationBlock(); + return; + } + + const void *key = selector; + + // Don't run the sniffing block if we're inside a nested call + if (!objc_getAssociatedObject(object, key)) { + sniffingBlock(); + } + + // Mark that we're calling through to the original so we can detect nested calls + objc_setAssociatedObject(object, key, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + originalImplementationBlock(); + objc_setAssociatedObject(object, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - Delegate Injection + ++ (void)injectIntoAllNSURLConnectionDelegateClasses +{ + // Only allow swizzling once. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Swizzle any classes that implement one of these selectors. + const SEL selectors[] = { + @selector(connectionDidFinishLoading:), + @selector(connection:willSendRequest:redirectResponse:), + @selector(connection:didReceiveResponse:), + @selector(connection:didReceiveData:), + @selector(connection:didFailWithError:), + @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:), + @selector(URLSession:dataTask:didReceiveData:), + @selector(URLSession:dataTask:didReceiveResponse:completionHandler:), + @selector(URLSession:task:didCompleteWithError:), + @selector(URLSession:dataTask:didBecomeDownloadTask:delegate:), + @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:), + @selector(URLSession:downloadTask:didFinishDownloadingToURL:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + Class *classes = NULL; + int numClasses = objc_getClassList(NULL, 0); + + if (numClasses > 0) { + classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses); + numClasses = objc_getClassList(classes, numClasses); + for (NSInteger classIndex = 0; classIndex < numClasses; ++classIndex) { + Class class = classes[classIndex]; + + if (class == [FLEXNetworkObserver class]) { + continue; + } + + // Use the runtime API rather than the methods on NSObject to avoid sending messages to + // classes we're not interested in swizzling. Otherwise we hit +initialize on all classes. + // NOTE: calling class_getInstanceMethod() DOES send +initialize to the class. That's why we iterate through the method list. + unsigned int methodCount = 0; + Method *methods = class_copyMethodList(class, &methodCount); + BOOL matchingSelectorFound = NO; + for (unsigned int methodIndex = 0; methodIndex < methodCount; methodIndex++) { + for (int selectorIndex = 0; selectorIndex < numSelectors; ++selectorIndex) { + if (method_getName(methods[methodIndex]) == selectors[selectorIndex]) { + [self injectIntoDelegateClass:class]; + matchingSelectorFound = YES; + break; + } + } + if (matchingSelectorFound) { + break; + } + } + free(methods); + } + + free(classes); + } + + [self injectIntoNSURLConnectionCancel]; + [self injectIntoNSURLSessionTaskResume]; + + [self injectIntoNSURLConnectionAsynchronousClassMethod]; + [self injectIntoNSURLConnectionSynchronousClassMethod]; + + [self injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods]; + [self injectIntoNSURLSessionAsyncUploadTaskMethods]; + }); +} + ++ (void)injectIntoDelegateClass:(Class)cls +{ + // Connections + [self injectWillSendRequestIntoDelegateClass:cls]; + [self injectDidReceiveDataIntoDelegateClass:cls]; + [self injectDidReceiveResponseIntoDelegateClass:cls]; + [self injectDidFinishLoadingIntoDelegateClass:cls]; + [self injectDidFailWithErrorIntoDelegateClass:cls]; + + // Sessions + [self injectTaskWillPerformHTTPRedirectionIntoDelegateClass:cls]; + [self injectTaskDidReceiveDataIntoDelegateClass:cls]; + [self injectTaskDidReceiveResponseIntoDelegateClass:cls]; + [self injectTaskDidCompleteWithErrorIntoDelegateClass:cls]; + [self injectRespondsToSelectorIntoDelegateClass:cls]; + + // Data tasks + [self injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:cls]; + + // Download tasks + [self injectDownloadTaskDidWriteDataIntoDelegateClass:cls]; + [self injectDownloadTaskDidFinishDownloadingIntoDelegateClass:cls]; +} + ++ (void)injectIntoNSURLConnectionCancel +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class class = [NSURLConnection class]; + SEL selector = @selector(cancel); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + Method originalCancel = class_getInstanceMethod(class, selector); + + void (^swizzleBlock)(NSURLConnection *) = ^(NSURLConnection *slf) { + [[FLEXNetworkObserver sharedObserver] connectionWillCancel:slf]; + ((void(*)(id, SEL))objc_msgSend)(slf, swizzledSelector); + }; + + IMP implementation = imp_implementationWithBlock(swizzleBlock); + class_addMethod(class, swizzledSelector, implementation, method_getTypeEncoding(originalCancel)); + Method newCancel = class_getInstanceMethod(class, swizzledSelector); + method_exchangeImplementations(originalCancel, newCancel); + }); +} + ++ (void)injectIntoNSURLSessionTaskResume +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // In iOS 7 resume lives in __NSCFLocalSessionTask + // In iOS 8 resume lives in NSURLSessionTask + // In iOS 9 resume lives in __NSCFURLSessionTask + Class class = Nil; + if (![[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { + class = NSClassFromString([@[@"__", @"NSC", @"FLocalS", @"ession", @"Task"] componentsJoinedByString:@""]); + } else if ([[NSProcessInfo processInfo] operatingSystemVersion].majorVersion < 9) { + class = [NSURLSessionTask class]; + } else { + class = NSClassFromString([@[@"__", @"NSC", @"FURLS", @"ession", @"Task"] componentsJoinedByString:@""]); + } + SEL selector = @selector(resume); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Method originalResume = class_getInstanceMethod(class, selector); + + void (^swizzleBlock)(NSURLSessionTask *) = ^(NSURLSessionTask *slf) { + [[FLEXNetworkObserver sharedObserver] URLSessionTaskWillResume:slf]; + ((void(*)(id, SEL))objc_msgSend)(slf, swizzledSelector); + }; + + IMP implementation = imp_implementationWithBlock(swizzleBlock); + class_addMethod(class, swizzledSelector, implementation, method_getTypeEncoding(originalResume)); + Method newResume = class_getInstanceMethod(class, swizzledSelector); + method_exchangeImplementations(originalResume, newResume); + }); +} + ++ (void)injectIntoNSURLConnectionAsynchronousClassMethod +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class class = objc_getMetaClass(class_getName([NSURLConnection class])); + SEL selector = @selector(sendAsynchronousRequest:queue:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + typedef void (^NSURLConnectionAsyncCompletion)(NSURLResponse* response, NSData* data, NSError* connectionError); + + void (^asyncSwizzleBlock)(Class, NSURLRequest *, NSOperationQueue *, NSURLConnectionAsyncCompletion) = ^(Class slf, NSURLRequest *request, NSOperationQueue *queue, NSURLConnectionAsyncCompletion completion) { + if ([FLEXNetworkObserver isEnabled]) { + NSString *requestID = [self nextRequestID]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:nil]; + NSString *mechanism = [self mechansimFromClassMethod:selector onClass:class]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + NSURLConnectionAsyncCompletion completionWrapper = ^(NSURLResponse *response, NSData *data, NSError *connectionError) { + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (connectionError) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:connectionError]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + + // Call through to the original completion handler + if (completion) { + completion(response, data, connectionError); + } + }; + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, queue, completionWrapper); + } else { + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, queue, completion); + } + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:class withBlock:asyncSwizzleBlock swizzledSelector:swizzledSelector]; + }); +} + ++ (void)injectIntoNSURLConnectionSynchronousClassMethod +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class class = objc_getMetaClass(class_getName([NSURLConnection class])); + SEL selector = @selector(sendSynchronousRequest:returningResponse:error:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + NSData *(^syncSwizzleBlock)(Class, NSURLRequest *, NSURLResponse **, NSError **) = ^NSData *(Class slf, NSURLRequest *request, NSURLResponse **response, NSError **error) { + NSData *data = nil; + if ([FLEXNetworkObserver isEnabled]) { + NSString *requestID = [self nextRequestID]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:nil]; + NSString *mechanism = [self mechansimFromClassMethod:selector onClass:class]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + NSError *temporaryError = nil; + NSURLResponse *temporaryResponse = nil; + data = ((id(*)(id, SEL, id, NSURLResponse **, NSError **))objc_msgSend)(slf, swizzledSelector, request, &temporaryResponse, &temporaryError); + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:temporaryResponse]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (temporaryError) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:temporaryError]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + if (error) { + *error = temporaryError; + } + if (response) { + *response = temporaryResponse; + } + } else { + data = ((id(*)(id, SEL, id, NSURLResponse **, NSError **))objc_msgSend)(slf, swizzledSelector, request, response, error); + } + + return data; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:class withBlock:syncSwizzleBlock swizzledSelector:swizzledSelector]; + }); +} + ++ (void)injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class class = [NSURLSession class]; + + // The method signatures here are close enough that we can use the same logic to inject into all of them. + const SEL selectors[] = { + @selector(dataTaskWithRequest:completionHandler:), + @selector(dataTaskWithURL:completionHandler:), + @selector(downloadTaskWithRequest:completionHandler:), + @selector(downloadTaskWithResumeData:completionHandler:), + @selector(downloadTaskWithURL:completionHandler:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { + SEL selector = selectors[selectorIndex]; + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:class]) { + // iOS 7 does not implement these methods on NSURLSession. We actually want to + // swizzle __NSCFURLSession, which we can get from the class of the shared session + class = [[NSURLSession sharedSession] class]; + } + + NSURLSessionTask *(^asyncDataOrDownloadSwizzleBlock)(Class, id, NSURLSessionAsyncCompletion) = ^NSURLSessionTask *(Class slf, id argument, NSURLSessionAsyncCompletion completion) { + NSURLSessionTask *task = nil; + // If completion block was not provided sender expect to receive delegated methods or does not + // interested in callback at all. In this case we should just call original method implementation + // with nil completion block. + if ([FLEXNetworkObserver isEnabled] && completion) { + NSString *requestID = [self nextRequestID]; + NSString *mechanism = [self mechansimFromClassMethod:selector onClass:class]; + NSURLSessionAsyncCompletion completionWrapper = [self asyncCompletionWrapperForRequestID:requestID mechanism:mechanism completion:completion]; + task = ((id(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, argument, completionWrapper); + [self setRequestID:requestID forConnectionOrTask:task]; + } else { + task = ((id(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, argument, completion); + } + return task; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:class withBlock:asyncDataOrDownloadSwizzleBlock swizzledSelector:swizzledSelector]; + } + }); +} + ++ (void)injectIntoNSURLSessionAsyncUploadTaskMethods +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class class = [NSURLSession class]; + + // The method signatures here are close enough that we can use the same logic to inject into both of them. + // Note that they have 3 arguments, so we can't easily combine with the data and download method above. + const SEL selectors[] = { + @selector(uploadTaskWithRequest:fromData:completionHandler:), + @selector(uploadTaskWithRequest:fromFile:completionHandler:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { + SEL selector = selectors[selectorIndex]; + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:class]) { + // iOS 7 does not implement these methods on NSURLSession. We actually want to + // swizzle __NSCFURLSession, which we can get from the class of the shared session + class = [[NSURLSession sharedSession] class]; + } + + NSURLSessionUploadTask *(^asyncUploadTaskSwizzleBlock)(Class, NSURLRequest *, id, NSURLSessionAsyncCompletion) = ^NSURLSessionUploadTask *(Class slf, NSURLRequest *request, id argument, NSURLSessionAsyncCompletion completion) { + NSURLSessionUploadTask *task = nil; + if ([FLEXNetworkObserver isEnabled]) { + NSString *requestID = [self nextRequestID]; + NSString *mechanism = [self mechansimFromClassMethod:selector onClass:class]; + NSURLSessionAsyncCompletion completionWrapper = [self asyncCompletionWrapperForRequestID:requestID mechanism:mechanism completion:completion]; + task = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, argument, completionWrapper); + [self setRequestID:requestID forConnectionOrTask:task]; + } else { + task = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, argument, completion); + } + return task; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:class withBlock:asyncUploadTaskSwizzleBlock swizzledSelector:swizzledSelector]; + } + }); +} + ++ (NSString *)mechansimFromClassMethod:(SEL)selector onClass:(Class)class +{ + return [NSString stringWithFormat:@"+[%@ %@]", NSStringFromClass(class), NSStringFromSelector(selector)]; +} + ++ (NSURLSessionAsyncCompletion)asyncCompletionWrapperForRequestID:(NSString *)requestID mechanism:(NSString *)mechanism completion:(NSURLSessionAsyncCompletion)completion +{ + NSURLSessionAsyncCompletion completionWrapper = ^(id fileURLOrData, NSURLResponse *response, NSError *error) { + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + NSData *data = nil; + if ([fileURLOrData isKindOfClass:[NSURL class]]) { + data = [NSData dataWithContentsOfURL:fileURLOrData]; + } else if ([fileURLOrData isKindOfClass:[NSData class]]) { + data = fileURLOrData; + } + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (error) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + + // Call through to the original completion handler + if (completion) { + completion(fileURLOrData, response, error); + } + }; + return completionWrapper; +} + ++ (void)injectWillSendRequestIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:willSendRequest:redirectResponse:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef NSURLRequest *(^NSURLConnectionWillSendRequestBlock)(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response); + + NSURLConnectionWillSendRequestBlock undefinedBlock = ^NSURLRequest *(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response) { + [[FLEXNetworkObserver sharedObserver] connection:connection willSendRequest:request redirectResponse:response delegate:slf]; + return request; + }; + + NSURLConnectionWillSendRequestBlock implementationBlock = ^NSURLRequest *(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response) { + __block NSURLRequest *returnValue = nil; + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, request, response); + } originalImplementationBlock:^{ + returnValue = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, connection, request, response); + }]; + return returnValue; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidReceiveResponseIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didReceiveResponse:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidReceiveResponseBlock)(id slf, NSURLConnection *connection, NSURLResponse *response); + + NSURLConnectionDidReceiveResponseBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSURLResponse *response) { + [[FLEXNetworkObserver sharedObserver] connection:connection didReceiveResponse:response delegate:slf]; + }; + + NSURLConnectionDidReceiveResponseBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSURLResponse *response) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, response); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, response); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidReceiveDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didReceiveData:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidReceiveDataBlock)(id slf, NSURLConnection *connection, NSData *data); + + NSURLConnectionDidReceiveDataBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSData *data) { + [[FLEXNetworkObserver sharedObserver] connection:connection didReceiveData:data delegate:slf]; + }; + + NSURLConnectionDidReceiveDataBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSData *data) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, data); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, data); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidFinishLoadingIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connectionDidFinishLoading:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidFinishLoadingBlock)(id slf, NSURLConnection *connection); + + NSURLConnectionDidFinishLoadingBlock undefinedBlock = ^(id slf, NSURLConnection *connection) { + [[FLEXNetworkObserver sharedObserver] connectionDidFinishLoading:connection delegate:slf]; + }; + + NSURLConnectionDidFinishLoadingBlock implementationBlock = ^(id slf, NSURLConnection *connection) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledSelector, connection); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidFailWithErrorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didFailWithError:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidFailWithErrorBlock)(id slf, NSURLConnection *connection, NSError *error); + + NSURLConnectionDidFailWithErrorBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSError *error) { + [[FLEXNetworkObserver sharedObserver] connection:connection didFailWithError:error delegate:slf]; + }; + + NSURLConnectionDidFailWithErrorBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSError *error) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, error); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, error); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectTaskWillPerformHTTPRedirectionIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionWillPerformHTTPRedirectionBlock)(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)); + + NSURLSessionWillPerformHTTPRedirectionBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)) { + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task willPerformHTTPRedirection:response newRequest:newRequest completionHandler:completionHandler delegate:slf]; + }; + + NSURLSessionWillPerformHTTPRedirectionBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, response, newRequest, completionHandler); + } originalImplementationBlock:^{ + ((id(*)(id, SEL, id, id, id, id, void(^)()))objc_msgSend)(slf, swizzledSelector, session, task, response, newRequest, completionHandler); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectTaskDidReceiveDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didReceiveData:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidReceiveDataBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); + + NSURLSessionDidReceiveDataBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didReceiveData:data delegate:slf]; + }; + + NSURLSessionDidReceiveDataBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, dataTask, data); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, dataTask, data); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didBecomeDownloadTask:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidBecomeDownloadTaskBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); + + NSURLSessionDidBecomeDownloadTaskBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didBecomeDownloadTask:downloadTask delegate:slf]; + }; + + NSURLSessionDidBecomeDownloadTaskBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, dataTask, downloadTask); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, dataTask, downloadTask); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectTaskDidReceiveResponseIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didReceiveResponse:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidReceiveResponseBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)); + + NSURLSessionDidReceiveResponseBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler delegate:slf]; + }; + + NSURLSessionDidReceiveResponseBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, dataTask, response, completionHandler); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id, void(^)()))objc_msgSend)(slf, swizzledSelector, session, dataTask, response, completionHandler); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectTaskDidCompleteWithErrorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:task:didCompleteWithError:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionTaskDidCompleteWithErrorBlock)(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error); + + NSURLSessionTaskDidCompleteWithErrorBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error) { + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task didCompleteWithError:error delegate:slf]; + }; + + NSURLSessionTaskDidCompleteWithErrorBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, error); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, task, error); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + +// Used for overriding AFNetworking behavior ++ (void)injectRespondsToSelectorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(respondsToSelector:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + //Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + Method method = class_getInstanceMethod(cls, selector); + struct objc_method_description methodDescription = *method_getDescription(method); + + BOOL (^undefinedBlock)(id , SEL) = ^(id slf, SEL sel) { + return YES; + }; + + BOOL (^implementationBlock)(id , SEL) = ^(id slf, SEL sel) { + if (sel == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { + return undefinedBlock(slf, sel); + } + return ((BOOL(*)(id, SEL, SEL))objc_msgSend)(slf, swizzledSelector, sel); + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + + ++ (void)injectDownloadTaskDidFinishDownloadingIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:downloadTask:didFinishDownloadingToURL:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDownloadDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDownloadTaskDidFinishDownloadingBlock)(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location); + + NSURLSessionDownloadTaskDidFinishDownloadingBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location) { + NSData *data = [NSData dataWithContentsOfFile:location.relativePath]; + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task didFinishDownloadingToURL:location data:data delegate:slf]; + }; + + NSURLSessionDownloadTaskDidFinishDownloadingBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, location); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, task, location); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDownloadTaskDidWriteDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDownloadDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDownloadTaskDidWriteDataBlock)(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); + + NSURLSessionDownloadTaskDidWriteDataBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { + [[FLEXNetworkObserver sharedObserver] URLSession:session downloadTask:task didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite delegate:slf]; + }; + + NSURLSessionDownloadTaskDidWriteDataBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, int64_t, int64_t, int64_t))objc_msgSend)(slf, swizzledSelector, session, task, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + +static char const * const kFLEXRequestIDKey = "kFLEXRequestIDKey"; + ++ (NSString *)requestIDForConnectionOrTask:(id)connectionOrTask +{ + NSString *requestID = objc_getAssociatedObject(connectionOrTask, kFLEXRequestIDKey); + if (!requestID) { + requestID = [self nextRequestID]; + [self setRequestID:requestID forConnectionOrTask:connectionOrTask]; + } + return requestID; +} + ++ (void)setRequestID:(NSString *)requestID forConnectionOrTask:(id)connectionOrTask +{ + objc_setAssociatedObject(connectionOrTask, kFLEXRequestIDKey, requestID, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - Initialization + +- (id)init +{ + self = [super init]; + if (self) { + self.requestStatesForRequestIDs = [[NSMutableDictionary alloc] init]; + self.queue = dispatch_queue_create("com.flex.FLEXNetworkObserver", DISPATCH_QUEUE_SERIAL); + } + return self; +} + +#pragma mark - Private Methods + +- (void)performBlock:(dispatch_block_t)block +{ + if ([[self class] isEnabled]) { + dispatch_async(_queue, block); + } +} + +- (FLEXInternalRequestState *)requestStateForRequestID:(NSString *)requestID +{ + FLEXInternalRequestState *requestState = self.requestStatesForRequestIDs[requestID]; + if (!requestState) { + requestState = [[FLEXInternalRequestState alloc] init]; + [self.requestStatesForRequestIDs setObject:requestState forKey:requestID]; + } + return requestState; +} + +- (void)removeRequestStateForRequestID:(NSString *)requestID +{ + [self.requestStatesForRequestIDs removeObjectForKey:requestID]; +} + +@end + + +@implementation FLEXNetworkObserver (NSURLConnectionHelpers) + +- (void)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + requestState.request = request; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:response]; + NSString *mechanism = [NSString stringWithFormat:@"NSURLConnection (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + NSMutableData *dataAccumulator = nil; + if (response.expectedContentLength < 0) { + dataAccumulator = [[NSMutableData alloc] init]; + } else { + dataAccumulator = [[NSMutableData alloc] initWithCapacity:(NSUInteger)response.expectedContentLength]; + } + requestState.dataAccumulator = dataAccumulator; + + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data delegate:(id)delegate +{ + // Just to be safe since we're doing this async + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [requestState.dataAccumulator appendData:data]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:data.length]; + }]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:requestState.dataAccumulator]; + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + // Cancellations can occur prior to the willSendRequest:... NSURLConnection delegate call. + // These are pretty common and clutter up the logs. Only record the failure if the recorder already knows about the request through willSendRequest:... + if (requestState.request) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } + + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)connectionWillCancel:(NSURLConnection *)connection +{ + [self performBlock:^{ + // Mimic the behavior of NSURLSession which is to create an error on cancellation. + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"cancelled" }; + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]; + [self connection:connection didFailWithError:error delegate:nil]; + }]; +} + +@end + + +@implementation FLEXNetworkObserver (NSURLSessionTaskHelpers) + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:response]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + NSMutableData *dataAccumulator = nil; + if (response.expectedContentLength < 0) { + dataAccumulator = [[NSMutableData alloc] init]; + } else { + dataAccumulator = [[NSMutableData alloc] initWithCapacity:(NSUInteger)response.expectedContentLength]; + } + requestState.dataAccumulator = dataAccumulator; + + NSString *requestMechanism = [NSString stringWithFormat:@"NSURLSessionDataTask (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:requestMechanism forRequestID:requestID]; + + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask delegate:(id)delegate +{ + [self performBlock:^{ + // By setting the request ID of the download task to match the data task, + // it can pick up where the data task left off. + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + [[self class] setRequestID:requestID forConnectionOrTask:downloadTask]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data delegate:(id)delegate +{ + // Just to be safe since we're doing this async + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + [requestState.dataAccumulator appendData:data]; + + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:data.length]; + }]; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + if (error) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:requestState.dataAccumulator]; + } + + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + if (!requestState.dataAccumulator) { + NSUInteger unsignedBytesExpectedToWrite = totalBytesExpectedToWrite > 0 ? (NSUInteger)totalBytesExpectedToWrite : 0; + requestState.dataAccumulator = [[NSMutableData alloc] initWithCapacity:unsignedBytesExpectedToWrite]; + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:downloadTask.response]; + + NSString *requestMechanism = [NSString stringWithFormat:@"NSURLSessionDownloadTask (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:requestMechanism forRequestID:requestID]; + } + + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:bytesWritten]; + }]; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data delegate:(id)delegate +{ + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [requestState.dataAccumulator appendData:data]; + }]; +} + +- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task +{ + // Since resume can be called multiple times on the same task, only treat the first resume as + // the equivalent to connection:willSendRequest:... + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + if (!requestState.request) { + requestState.request = task.currentRequest; + + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:task.currentRequest redirectResponse:nil]; + } + }]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/LICENSE b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/LICENSE new file mode 100755 index 0000000..23750c6 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Network/PonyDebugger/LICENSE @@ -0,0 +1,16 @@ + +PonyDebugger +Copyright 2012 Square Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.h new file mode 100755 index 0000000..761ee06 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXArrayExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXArrayExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.m new file mode 100755 index 0000000..ed1b1eb --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXArrayExplorerViewController.m @@ -0,0 +1,78 @@ +// +// FLEXArrayExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXArrayExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXObjectExplorerFactory.h" + +@interface FLEXArrayExplorerViewController () + +@property (nonatomic, readonly) NSArray *array; + +@end + +@implementation FLEXArrayExplorerViewController + +- (NSArray *)array +{ + return [self.object isKindOfClass:[NSArray class]] ? self.object : nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Array Indices"; +} + +- (NSArray *)customSectionRowCookies +{ + // Use index numbers as the row cookies + NSMutableArray *cookies = [NSMutableArray arrayWithCapacity:[self.array count]]; + for (NSUInteger i = 0; i < [self.array count]; i++) { + [cookies addObject:@(i)]; + } + return cookies; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + return [rowCookie description]; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[self detailObjectForRowCookie:rowCookie]]; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + return [FLEXObjectExplorerFactory explorerViewControllerForObject:[self detailObjectForRowCookie:rowCookie]]; +} + +- (BOOL)shouldShowDescription +{ + return NO; +} + + +#pragma mark - Helpers + +- (id)detailObjectForRowCookie:(id)rowCookie +{ + NSUInteger index = [rowCookie unsignedIntegerValue]; + return self.array[index]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.h new file mode 100755 index 0000000..9bb36ce --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXClassExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXClassExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.m new file mode 100755 index 0000000..561f128 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXClassExplorerViewController.m @@ -0,0 +1,132 @@ +// +// FLEXClassExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXClassExplorerViewController.h" +#import "FLEXMethodCallingViewController.h" +#import "FLEXInstancesTableViewController.h" + +typedef NS_ENUM(NSUInteger, FLEXClassExplorerRow) { + FLEXClassExplorerRowNew, + FLEXClassExplorerRowAlloc, + FLEXClassExplorerRowLiveInstances +}; + +@interface FLEXClassExplorerViewController () + +@property (nonatomic, readonly) Class theClass; + +@end + +@implementation FLEXClassExplorerViewController + +- (Class)theClass +{ + Class theClass = Nil; + if (class_isMetaClass(object_getClass(self.object))) { + theClass = self.object; + } + return theClass; +} + +#pragma mark - Superclass Overrides + +- (NSArray *)possibleExplorerSections +{ + // Move class methods to between our custom section and the properties section since + // we are more interested in the class sections than in the instance level sections. + NSMutableArray *mutableSections = [[super possibleExplorerSections] mutableCopy]; + [mutableSections removeObject:@(FLEXObjectExplorerSectionClassMethods)]; + [mutableSections insertObject:@(FLEXObjectExplorerSectionClassMethods) atIndex:[mutableSections indexOfObject:@(FLEXObjectExplorerSectionProperties)]]; + return mutableSections; +} + +- (NSString *)customSectionTitle +{ + return @"Shortcuts"; +} + +- (NSArray *)customSectionRowCookies +{ + NSMutableArray *cookies = [NSMutableArray array]; + if ([self.theClass respondsToSelector:@selector(new)]) { + [cookies addObject:@(FLEXClassExplorerRowNew)]; + } + if ([self.theClass respondsToSelector:@selector(alloc)]) { + [cookies addObject:@(FLEXClassExplorerRowAlloc)]; + } + [cookies addObject:@(FLEXClassExplorerRowLiveInstances)]; + return cookies; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + NSString *title = nil; + FLEXClassExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXClassExplorerRowNew: + title = @"+ (id)new"; + break; + + case FLEXClassExplorerRowAlloc: + title = @"+ (id)alloc"; + break; + + case FLEXClassExplorerRowLiveInstances: + title = @"Live Instances"; + break; + } + return title; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return nil; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + FLEXClassExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXClassExplorerRowNew: + drillInViewController = [[FLEXMethodCallingViewController alloc] initWithTarget:self.theClass method:class_getClassMethod(self.theClass, @selector(new))]; + break; + + case FLEXClassExplorerRowAlloc: + drillInViewController = [[FLEXMethodCallingViewController alloc] initWithTarget:self.theClass method:class_getClassMethod(self.theClass, @selector(alloc))]; + break; + + case FLEXClassExplorerRowLiveInstances: + drillInViewController = [FLEXInstancesTableViewController instancesTableViewControllerForClassName:NSStringFromClass(self.theClass)]; + break; + } + return drillInViewController; +} + +- (BOOL)shouldShowDescription +{ + // Redundant with our title. + return NO; +} + +- (BOOL)canCallInstanceMethods +{ + return NO; +} + +- (BOOL)canHaveInstanceState +{ + return NO; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.h new file mode 100755 index 0000000..8ed698b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXDefaultsExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXDefaultsExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.m new file mode 100755 index 0000000..c3c26f2 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDefaultsExplorerViewController.m @@ -0,0 +1,73 @@ +// +// FLEXDefaultsExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/23/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXDefaultsExplorerViewController.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXDefaultEditorViewController.h" + +@interface FLEXDefaultsExplorerViewController () + +@property (nonatomic, readonly) NSUserDefaults *defaults; + +@end + +@implementation FLEXDefaultsExplorerViewController + +- (NSUserDefaults *)defaults +{ + return [self.object isKindOfClass:[NSUserDefaults class]] ? self.object : nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Defaults"; +} + +- (NSArray *)customSectionRowCookies +{ + return [[[self.defaults dictionaryRepresentation] allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + return rowCookie; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[self.defaults objectForKey:rowCookie]]; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + NSString *key = rowCookie; + id drillInObject = [self.defaults objectForKey:key]; + if ([FLEXDefaultEditorViewController canEditDefaultWithValue:drillInObject]) { + drillInViewController = [[FLEXDefaultEditorViewController alloc] initWithDefaults:self.defaults key:key]; + } else { + drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:drillInObject]; + } + return drillInViewController; +} + +- (BOOL)shouldShowDescription +{ + return NO; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.h new file mode 100755 index 0000000..77b9c80 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXDictionaryExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXDictionaryExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.m new file mode 100755 index 0000000..253ae65 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXDictionaryExplorerViewController.m @@ -0,0 +1,64 @@ +// +// FLEXDictionaryExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXDictionaryExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXObjectExplorerFactory.h" + +@interface FLEXDictionaryExplorerViewController () + +@property (nonatomic, readonly) NSDictionary *dictionary; + +@end + +@implementation FLEXDictionaryExplorerViewController + +- (NSDictionary *)dictionary +{ + return [self.object isKindOfClass:[NSDictionary class]] ? self.object : nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Dictionary Objects"; +} + +- (NSArray *)customSectionRowCookies +{ + return [self.dictionary allKeys]; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + return [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:rowCookie]; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:self.dictionary[rowCookie]]; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + return [FLEXObjectExplorerFactory explorerViewControllerForObject:self.dictionary[rowCookie]]; +} + +- (BOOL)shouldShowDescription +{ + return NO; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.h new file mode 100755 index 0000000..c82827a --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.h @@ -0,0 +1,22 @@ +// +// FLEXGlobalsTableViewControllerEntry.h +// UICatalog +// +// Created by Javier Soto on 7/26/14. +// Copyright (c) 2014 f. All rights reserved. +// + +#import +#import + +typedef NSString *(^FLEXGlobalsTableViewControllerEntryNameFuture)(void); +typedef UIViewController *(^FLEXGlobalsTableViewControllerViewControllerFuture)(void); + +@interface FLEXGlobalsTableViewControllerEntry : NSObject + +@property (nonatomic, readonly, copy) FLEXGlobalsTableViewControllerEntryNameFuture entryNameFuture; +@property (nonatomic, readonly, copy) FLEXGlobalsTableViewControllerViewControllerFuture viewControllerFuture; + ++ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture viewControllerFuture:(FLEXGlobalsTableViewControllerViewControllerFuture)viewControllerFuture; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.m new file mode 100755 index 0000000..0a9306b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXGlobalsTableViewControllerEntry.m @@ -0,0 +1,25 @@ +// +// FLEXGlobalsTableViewControllerEntry.m +// UICatalog +// +// Created by Javier Soto on 7/26/14. +// Copyright (c) 2014 f. All rights reserved. +// + +#import "FLEXGlobalsTableViewControllerEntry.h" + +@implementation FLEXGlobalsTableViewControllerEntry + ++ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture viewControllerFuture:(FLEXGlobalsTableViewControllerViewControllerFuture)viewControllerFuture +{ + NSParameterAssert(nameFuture); + NSParameterAssert(viewControllerFuture); + + FLEXGlobalsTableViewControllerEntry *entry = [[self alloc] init]; + entry->_entryNameFuture = [nameFuture copy]; + entry->_viewControllerFuture = [viewControllerFuture copy]; + + return entry; +} + +@end \ No newline at end of file diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.h new file mode 100755 index 0000000..ea8cf5e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXImageExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/12/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXImageExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.m new file mode 100755 index 0000000..d529181 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXImageExplorerViewController.m @@ -0,0 +1,69 @@ +// +// FLEXImageExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/12/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXImageExplorerViewController.h" +#import "FLEXImagePreviewViewController.h" + +typedef NS_ENUM(NSUInteger, FLEXImageExplorerRow) { + FLEXImageExplorerRowImage +}; + +@interface FLEXImageExplorerViewController () + +@property (nonatomic, readonly) UIImage *image; + +@end + +@implementation FLEXImageExplorerViewController + +- (UIImage *)image +{ + return [self.object isKindOfClass:[UIImage class]] ? self.object : nil; +} + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Shortcuts"; +} + +- (NSArray *)customSectionRowCookies +{ + return @[@(FLEXImageExplorerRowImage)]; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + NSString *title = nil; + if ([rowCookie isEqual:@(FLEXImageExplorerRowImage)]) { + title = @"Show Image"; + } + return title; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return nil; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + if ([rowCookie isEqual:@(FLEXImageExplorerRowImage)]) { + drillInViewController = [[FLEXImagePreviewViewController alloc] initWithImage:self.image]; + } + return drillInViewController; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.h new file mode 100755 index 0000000..f9a157c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXLayerExplorerViewController.h +// UICatalog +// +// Created by Ryan Olson on 12/14/14. +// Copyright (c) 2014 f. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXLayerExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.m new file mode 100755 index 0000000..e55184e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXLayerExplorerViewController.m @@ -0,0 +1,92 @@ +// +// FLEXLayerExplorerViewController.m +// UICatalog +// +// Created by Ryan Olson on 12/14/14. +// Copyright (c) 2014 f. All rights reserved. +// + +#import "FLEXLayerExplorerViewController.h" +#import "FLEXImagePreviewViewController.h" + +typedef NS_ENUM(NSUInteger, FLEXLayerExplorerRow) { + FLEXLayerExplorerRowPreview +}; + +@interface FLEXLayerExplorerViewController () + +@property (nonatomic, readonly) CALayer *layerToExplore; + +@end + +@implementation FLEXLayerExplorerViewController + +- (CALayer *)layerToExplore +{ + return [self.object isKindOfClass:[CALayer class]] ? self.object : nil; +} + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Shortcuts"; +} + +- (NSArray *)customSectionRowCookies +{ + return @[@(FLEXLayerExplorerRowPreview)]; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + NSString *title = nil; + + if ([rowCookie isKindOfClass:[NSNumber class]]) { + FLEXLayerExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXLayerExplorerRowPreview: + title = @"Preview Image"; + break; + } + } + + return title; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + + if ([rowCookie isKindOfClass:[NSNumber class]]) { + FLEXLayerExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXLayerExplorerRowPreview: + drillInViewController = [[self class] imagePreviewViewControllerForLayer:self.layerToExplore]; + break; + } + } + + return drillInViewController; +} + ++ (UIViewController *)imagePreviewViewControllerForLayer:(CALayer *)layer +{ + UIViewController *imagePreviewViewController = nil; + if (!CGRectIsEmpty(layer.bounds)) { + UIGraphicsBeginImageContextWithOptions(layer.bounds.size, NO, 0.0); + CGContextRef imageContext = UIGraphicsGetCurrentContext(); + [layer renderInContext:imageContext]; + UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + imagePreviewViewController = [[FLEXImagePreviewViewController alloc] initWithImage:previewImage]; + } + return imagePreviewViewController; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.h new file mode 100755 index 0000000..0115670 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.h @@ -0,0 +1,17 @@ +// +// FLEXObjectExplorerFactory.h +// Flipboard +// +// Created by Ryan Olson on 5/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@class FLEXObjectExplorerViewController; + +@interface FLEXObjectExplorerFactory : NSObject + ++ (FLEXObjectExplorerViewController *)explorerViewControllerForObject:(id)object; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.m new file mode 100755 index 0000000..05dd666 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerFactory.m @@ -0,0 +1,65 @@ +// +// FLEXObjectExplorerFactory.m +// Flipboard +// +// Created by Ryan Olson on 5/15/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerFactory.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXArrayExplorerViewController.h" +#import "FLEXSetExplorerViewController.h" +#import "FLEXDictionaryExplorerViewController.h" +#import "FLEXDefaultsExplorerViewController.h" +#import "FLEXViewControllerExplorerViewController.h" +#import "FLEXViewExplorerViewController.h" +#import "FLEXImageExplorerViewController.h" +#import "FLEXClassExplorerViewController.h" +#import "FLEXLayerExplorerViewController.h" +#import + +@implementation FLEXObjectExplorerFactory + ++ (FLEXObjectExplorerViewController *)explorerViewControllerForObject:(id)object +{ + // Bail for nil object. We can't explore nil. + if (!object) { + return nil; + } + + static NSDictionary *explorerSubclassesForObjectTypeStrings = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + explorerSubclassesForObjectTypeStrings = @{NSStringFromClass([NSArray class]) : [FLEXArrayExplorerViewController class], + NSStringFromClass([NSSet class]) : [FLEXSetExplorerViewController class], + NSStringFromClass([NSDictionary class]) : [FLEXDictionaryExplorerViewController class], + NSStringFromClass([NSUserDefaults class]) : [FLEXDefaultsExplorerViewController class], + NSStringFromClass([UIViewController class]) : [FLEXViewControllerExplorerViewController class], + NSStringFromClass([UIView class]) : [FLEXViewExplorerViewController class], + NSStringFromClass([UIImage class]) : [FLEXImageExplorerViewController class], + NSStringFromClass([CALayer class]) : [FLEXLayerExplorerViewController class]}; + }); + + Class explorerClass = nil; + BOOL objectIsClass = class_isMetaClass(object_getClass(object)); + if (objectIsClass) { + explorerClass = [FLEXClassExplorerViewController class]; + } else { + explorerClass = [FLEXObjectExplorerViewController class]; + for (NSString *objectTypeString in explorerSubclassesForObjectTypeStrings) { + Class objectClass = NSClassFromString(objectTypeString); + if ([object isKindOfClass:objectClass]) { + explorerClass = explorerSubclassesForObjectTypeStrings[objectTypeString]; + break; + } + } + } + + FLEXObjectExplorerViewController *explorerViewController = [[explorerClass alloc] init]; + explorerViewController.object = object; + + return explorerViewController; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.h new file mode 100755 index 0000000..781a859 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.h @@ -0,0 +1,51 @@ +// +// FLEXObjectExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +typedef NS_ENUM(NSUInteger, FLEXObjectExplorerSection) { + FLEXObjectExplorerSectionDescription, + FLEXObjectExplorerSectionCustom, + FLEXObjectExplorerSectionProperties, + FLEXObjectExplorerSectionIvars, + FLEXObjectExplorerSectionMethods, + FLEXObjectExplorerSectionClassMethods, + FLEXObjectExplorerSectionSuperclasses, + FLEXObjectExplorerSectionReferencingInstances +}; + +@interface FLEXObjectExplorerViewController : UITableViewController + +@property (nonatomic, strong) id object; + +// Sublasses can override the methods below to provide data in a custom section. +// The subclass should provide an array of "row cookies" to allow retreival of individual row data later on. +// The objects in the rowCookies array will be used to call the row title, subtitle, etc methods to consturct the rows. +// The cookies approach is used here because we may filter the visible rows based on the search text entered by the user. +- (NSString *)customSectionTitle; +- (NSArray *)customSectionRowCookies; +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie; +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie; +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie; +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie; + +// More subclass configuration hooks. + +/// Whether to allow showing/drilling in to current values for ivars and properties. Defalut is YES. +- (BOOL)canHaveInstanceState; + +/// Whether to allow drilling in to method calling interfaces for instance methods. Default is YES. +- (BOOL)canCallInstanceMethods; + +/// If the custom section data makes the description redundant, subclasses can choose to hide it. Default is YES. +- (BOOL)shouldShowDescription; + +/// Subclasses can reorder/change which sections can display directly by overriding this method. +- (NSArray *)possibleExplorerSections; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.m new file mode 100755 index 0000000..a01953b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXObjectExplorerViewController.m @@ -0,0 +1,1033 @@ +// +// FLEXObjectExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-03. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" +#import "FLEXUtility.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXMultilineTableViewCell.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXPropertyEditorViewController.h" +#import "FLEXIvarEditorViewController.h" +#import "FLEXMethodCallingViewController.h" +#import "FLEXInstancesTableViewController.h" +#import + +// Convenience boxes to keep runtime properties, ivars, and methods in foundation collections. +@interface FLEXPropertyBox : NSObject +@property (nonatomic, assign) objc_property_t property; +@end +@implementation FLEXPropertyBox +@end + +@interface FLEXIvarBox : NSObject +@property (nonatomic, assign) Ivar ivar; +@end +@implementation FLEXIvarBox +@end + +@interface FLEXMethodBox : NSObject +@property (nonatomic, assign) Method method; +@end +@implementation FLEXMethodBox +@end + +static const NSInteger kFLEXObjectExplorerScopeNoInheritanceIndex = 0; +static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1; + +@interface FLEXObjectExplorerViewController () + +@property (nonatomic, strong) NSArray *properties; +@property (nonatomic, strong) NSArray *inheritedProperties; +@property (nonatomic, strong) NSArray *filteredProperties; + +@property (nonatomic, strong) NSArray *ivars; +@property (nonatomic, strong) NSArray *inheritedIvars; +@property (nonatomic, strong) NSArray *filteredIvars; + +@property (nonatomic, strong) NSArray *methods; +@property (nonatomic, strong) NSArray *inheritedMethods; +@property (nonatomic, strong) NSArray *filteredMethods; + +@property (nonatomic, strong) NSArray *classMethods; +@property (nonatomic, strong) NSArray *inheritedClassMethods; +@property (nonatomic, strong) NSArray *filteredClassMethods; + +@property (nonatomic, strong) NSArray *superclasses; +@property (nonatomic, strong) NSArray *filteredSuperclasses; + +@property (nonatomic, strong) NSArray *cachedCustomSectionRowCookies; +@property (nonatomic, strong) NSIndexSet *customSectionVisibleIndexes; + +@property (nonatomic, strong) UISearchBar *searchBar; +@property (nonatomic, strong) NSString *filterText; +@property (nonatomic, assign) BOOL includeInheritance; + +@end + +@implementation FLEXObjectExplorerViewController + +- (id)initWithStyle:(UITableViewStyle)style +{ + // Force grouped style + return [super initWithStyle:UITableViewStyleGrouped]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.searchBar = [[UISearchBar alloc] init]; + self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText]; + self.searchBar.delegate = self; + self.searchBar.showsScopeBar = YES; + self.searchBar.scopeButtonTitles = @[@"No Inheritance", @"Include Inheritance"]; + [self.searchBar sizeToFit]; + self.tableView.tableHeaderView = self.searchBar; + + self.refreshControl = [[UIRefreshControl alloc] init]; + [self.refreshControl addTarget:self action:@selector(refreshControlDidRefresh:) forControlEvents:UIControlEventValueChanged]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Reload the entire table view rather than just the visible cells because the filtered rows + // may have changed (i.e. a change in the description row that causes it to get filtered out). + [self updateTableData]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + [self.searchBar endEditing:YES]; +} + +- (void)refreshControlDidRefresh:(id)sender +{ + [self updateTableData]; + [self.refreshControl endRefreshing]; +} + + +#pragma mark - Search + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText +{ + self.filterText = searchText; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; +} + +- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope +{ + if (selectedScope == kFLEXObjectExplorerScopeIncludeInheritanceIndex) { + self.includeInheritance = YES; + } else if (selectedScope == kFLEXObjectExplorerScopeNoInheritanceIndex) { + self.includeInheritance = NO; + } +} + + +#pragma mark - Setter overrides + +- (void)setObject:(id)object +{ + _object = object; + // Use [object class] here rather than object_getClass because we don't want to show the KVO prefix for observed objects. + self.title = [[object class] description]; + [self updateTableData]; +} + +- (void)setIncludeInheritance:(BOOL)includeInheritance +{ + if (_includeInheritance != includeInheritance) { + _includeInheritance = includeInheritance; + [self updateDisplayedData]; + } +} + +- (void)setFilterText:(NSString *)filterText +{ + if (_filterText != filterText || ![_filterText isEqual:filterText]) { + _filterText = filterText; + [self updateDisplayedData]; + } +} + + +#pragma mark - Reloading + +- (void)updateTableData +{ + [self updateCustomData]; + [self updateProperties]; + [self updateIvars]; + [self updateMethods]; + [self updateClassMethods]; + [self updateSuperclasses]; + [self updateDisplayedData]; +} + +- (void)updateDisplayedData +{ + [self updateFilteredCustomData]; + [self updateFilteredProperties]; + [self updateFilteredIvars]; + [self updateFilteredMethods]; + [self updateFilteredClassMethods]; + [self updateFilteredSuperclasses]; + + if (self.isViewLoaded) { + [self.tableView reloadData]; + } +} + +- (BOOL)shouldShowDescription +{ + BOOL showDescription = YES; + + // Not if it's empty or nil. + NSString *descripition = [FLEXUtility safeDescriptionForObject:self.object]; + if (showDescription) { + showDescription = [descripition length] > 0; + } + + // Not if we have filter text that doesn't match the desctiption. + if (showDescription && [self.filterText length] > 0) { + showDescription = [descripition rangeOfString:self.filterText options:NSCaseInsensitiveSearch].length > 0; + } + + return showDescription; +} + + +#pragma mark - Properties + +- (void)updateProperties +{ + Class class = [self.object class]; + self.properties = [[self class] propertiesForClass:class]; + self.inheritedProperties = [[self class] inheritedPropertiesForClass:class]; +} + ++ (NSArray *)propertiesForClass:(Class)class +{ + NSMutableArray *boxedProperties = [NSMutableArray array]; + unsigned int propertyCount = 0; + objc_property_t *propertyList = class_copyPropertyList(class, &propertyCount); + if (propertyList) { + for (unsigned int i = 0; i < propertyCount; i++) { + FLEXPropertyBox *propertyBox = [[FLEXPropertyBox alloc] init]; + propertyBox.property = propertyList[i]; + [boxedProperties addObject:propertyBox]; + } + free(propertyList); + } + return boxedProperties; +} + ++ (NSArray *)inheritedPropertiesForClass:(Class)class +{ + NSMutableArray *inheritedProperties = [NSMutableArray array]; + while ((class = [class superclass])) { + [inheritedProperties addObjectsFromArray:[self propertiesForClass:class]]; + } + return inheritedProperties; +} + +- (void)updateFilteredProperties +{ + NSArray *candidateProperties = self.properties; + if (self.includeInheritance) { + candidateProperties = [candidateProperties arrayByAddingObjectsFromArray:self.inheritedProperties]; + } + + NSArray *unsortedFilteredProperties = nil; + if ([self.filterText length] > 0) { + NSMutableArray *mutableUnsortedFilteredProperties = [NSMutableArray array]; + for (FLEXPropertyBox *propertyBox in candidateProperties) { + NSString *prettyName = [FLEXRuntimeUtility prettyNameForProperty:propertyBox.property]; + if ([prettyName rangeOfString:self.filterText options:NSCaseInsensitiveSearch].location != NSNotFound) { + [mutableUnsortedFilteredProperties addObject:propertyBox]; + } + } + unsortedFilteredProperties = mutableUnsortedFilteredProperties; + } else { + unsortedFilteredProperties = candidateProperties; + } + + self.filteredProperties = [unsortedFilteredProperties sortedArrayUsingComparator:^NSComparisonResult(FLEXPropertyBox *propertyBox1, FLEXPropertyBox *propertyBox2) { + NSString *name1 = [NSString stringWithUTF8String:property_getName(propertyBox1.property)]; + NSString *name2 = [NSString stringWithUTF8String:property_getName(propertyBox2.property)]; + return [name1 caseInsensitiveCompare:name2]; + }]; +} + +- (NSString *)titleForPropertyAtIndex:(NSInteger)index +{ + FLEXPropertyBox *propertyBox = self.filteredProperties[index]; + return [FLEXRuntimeUtility prettyNameForProperty:propertyBox.property]; +} + +- (id)valueForPropertyAtIndex:(NSInteger)index +{ + id value = nil; + if ([self canHaveInstanceState]) { + FLEXPropertyBox *propertyBox = self.filteredProperties[index]; + value = [FLEXRuntimeUtility valueForProperty:propertyBox.property onObject:self.object]; + } + return value; +} + + +#pragma mark - Ivars + +- (void)updateIvars +{ + Class class = [self.object class]; + self.ivars = [[self class] ivarsForClass:class]; + self.inheritedIvars = [[self class] inheritedIvarsForClass:class]; +} + ++ (NSArray *)ivarsForClass:(Class)class +{ + NSMutableArray *boxedIvars = [NSMutableArray array]; + unsigned int ivarCount = 0; + Ivar *ivarList = class_copyIvarList(class, &ivarCount); + if (ivarList) { + for (unsigned int i = 0; i < ivarCount; i++) { + FLEXIvarBox *ivarBox = [[FLEXIvarBox alloc] init]; + ivarBox.ivar = ivarList[i]; + [boxedIvars addObject:ivarBox]; + } + free(ivarList); + } + return boxedIvars; +} + ++ (NSArray *)inheritedIvarsForClass:(Class)class +{ + NSMutableArray *inheritedIvars = [NSMutableArray array]; + while ((class = [class superclass])) { + [inheritedIvars addObjectsFromArray:[self ivarsForClass:class]]; + } + return inheritedIvars; +} + +- (void)updateFilteredIvars +{ + NSArray *candidateIvars = self.ivars; + if (self.includeInheritance) { + candidateIvars = [candidateIvars arrayByAddingObjectsFromArray:self.inheritedIvars]; + } + + NSArray *unsortedFilteredIvars = nil; + if ([self.filterText length] > 0) { + NSMutableArray *mutableUnsortedFilteredIvars = [NSMutableArray array]; + for (FLEXIvarBox *ivarBox in candidateIvars) { + NSString *prettyName = [FLEXRuntimeUtility prettyNameForIvar:ivarBox.ivar]; + if ([prettyName rangeOfString:self.filterText options:NSCaseInsensitiveSearch].location != NSNotFound) { + [mutableUnsortedFilteredIvars addObject:ivarBox]; + } + } + unsortedFilteredIvars = mutableUnsortedFilteredIvars; + } else { + unsortedFilteredIvars = candidateIvars; + } + + self.filteredIvars = [unsortedFilteredIvars sortedArrayUsingComparator:^NSComparisonResult(FLEXIvarBox *ivarBox1, FLEXIvarBox *ivarBox2) { + NSString *name1 = [NSString stringWithUTF8String:ivar_getName(ivarBox1.ivar)]; + NSString *name2 = [NSString stringWithUTF8String:ivar_getName(ivarBox2.ivar)]; + return [name1 caseInsensitiveCompare:name2]; + }]; +} + +- (NSString *)titleForIvarAtIndex:(NSInteger)index +{ + FLEXIvarBox *ivarBox = self.filteredIvars[index]; + return [FLEXRuntimeUtility prettyNameForIvar:ivarBox.ivar]; +} + +- (id)valueForIvarAtIndex:(NSInteger)index +{ + id value = nil; + if ([self canHaveInstanceState]) { + FLEXIvarBox *ivarBox = self.filteredIvars[index]; + value = [FLEXRuntimeUtility valueForIvar:ivarBox.ivar onObject:self.object]; + } + return value; +} + + +#pragma mark - Methods + +- (void)updateMethods +{ + Class class = [self.object class]; + self.methods = [[self class] methodsForClass:class]; + self.inheritedMethods = [[self class] inheritedMethodsForClass:class]; +} + +- (void)updateFilteredMethods +{ + self.filteredMethods = [self filteredMethodsFromMethods:self.methods inheritedMethods:self.inheritedMethods areClassMethods:NO]; +} + +- (void)updateClassMethods +{ + const char *className = [NSStringFromClass([self.object class]) UTF8String]; + Class metaClass = objc_getMetaClass(className); + self.classMethods = [[self class] methodsForClass:metaClass]; + self.inheritedClassMethods = [[self class] inheritedMethodsForClass:metaClass]; +} + +- (void)updateFilteredClassMethods +{ + self.filteredClassMethods = [self filteredMethodsFromMethods:self.classMethods inheritedMethods:self.inheritedClassMethods areClassMethods:YES]; +} + ++ (NSArray *)methodsForClass:(Class)class +{ + NSMutableArray *boxedMethods = [NSMutableArray array]; + unsigned int methodCount = 0; + Method *methodList = class_copyMethodList(class, &methodCount); + if (methodList) { + for (unsigned int i = 0; i < methodCount; i++) { + FLEXMethodBox *methodBox = [[FLEXMethodBox alloc] init]; + methodBox.method = methodList[i]; + [boxedMethods addObject:methodBox]; + } + free(methodList); + } + return boxedMethods; +} + ++ (NSArray *)inheritedMethodsForClass:(Class)class +{ + NSMutableArray *inheritedMethods = [NSMutableArray array]; + while ((class = [class superclass])) { + [inheritedMethods addObjectsFromArray:[self methodsForClass:class]]; + } + return inheritedMethods; +} + +- (NSArray *)filteredMethodsFromMethods:(NSArray *)methods inheritedMethods:(NSArray *)inheritedMethods areClassMethods:(BOOL)areClassMethods +{ + NSArray *candidateMethods = methods; + if (self.includeInheritance) { + candidateMethods = [candidateMethods arrayByAddingObjectsFromArray:inheritedMethods]; + } + + NSArray *unsortedFilteredMethods = nil; + if ([self.filterText length] > 0) { + NSMutableArray *mutableUnsortedFilteredMethods = [NSMutableArray array]; + for (FLEXMethodBox *methodBox in candidateMethods) { + NSString *prettyName = [FLEXRuntimeUtility prettyNameForMethod:methodBox.method isClassMethod:areClassMethods]; + if ([prettyName rangeOfString:self.filterText options:NSCaseInsensitiveSearch].location != NSNotFound) { + [mutableUnsortedFilteredMethods addObject:methodBox]; + } + } + unsortedFilteredMethods = mutableUnsortedFilteredMethods; + } else { + unsortedFilteredMethods = candidateMethods; + } + + NSArray *sortedFilteredMethods = [unsortedFilteredMethods sortedArrayUsingComparator:^NSComparisonResult(FLEXMethodBox *methodBox1, FLEXMethodBox *methodBox2) { + NSString *name1 = NSStringFromSelector(method_getName(methodBox1.method)); + NSString *name2 = NSStringFromSelector(method_getName(methodBox2.method)); + return [name1 caseInsensitiveCompare:name2]; + }]; + + return sortedFilteredMethods; +} + +- (NSString *)titleForMethodAtIndex:(NSInteger)index +{ + FLEXMethodBox *methodBox = self.filteredMethods[index]; + return [FLEXRuntimeUtility prettyNameForMethod:methodBox.method isClassMethod:NO]; +} + +- (NSString *)titleForClassMethodAtIndex:(NSInteger)index +{ + FLEXMethodBox *classMethodBox = self.filteredClassMethods[index]; + return [FLEXRuntimeUtility prettyNameForMethod:classMethodBox.method isClassMethod:YES]; +} + + +#pragma mark - Superclasses + ++ (NSArray *)superclassesForClass:(Class)class +{ + NSMutableArray *superClasses = [NSMutableArray array]; + while ((class = [class superclass])) { + [superClasses addObject:class]; + } + return superClasses; +} + +- (void)updateSuperclasses +{ + self.superclasses = [[self class] superclassesForClass:[self.object class]]; +} + +- (void)updateFilteredSuperclasses +{ + if ([self.filterText length] > 0) { + NSMutableArray *filteredSuperclasses = [NSMutableArray array]; + for (Class superclass in self.superclasses) { + if ([NSStringFromClass(superclass) rangeOfString:self.filterText options:NSCaseInsensitiveSearch].length > 0) { + [filteredSuperclasses addObject:superclass]; + } + } + self.filteredSuperclasses = filteredSuperclasses; + } else { + self.filteredSuperclasses = self.superclasses; + } +} + + +#pragma mark - Table View Data Helpers + +- (NSArray *)possibleExplorerSections +{ + static NSArray *possibleSections = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + possibleSections = @[@(FLEXObjectExplorerSectionDescription), + @(FLEXObjectExplorerSectionCustom), + @(FLEXObjectExplorerSectionProperties), + @(FLEXObjectExplorerSectionIvars), + @(FLEXObjectExplorerSectionMethods), + @(FLEXObjectExplorerSectionClassMethods), + @(FLEXObjectExplorerSectionSuperclasses), + @(FLEXObjectExplorerSectionReferencingInstances)]; + }); + return possibleSections; +} + +- (NSArray *)visibleExplorerSections +{ + NSMutableArray *visibleSections = [NSMutableArray array]; + + for (NSNumber *possibleSection in [self possibleExplorerSections]) { + FLEXObjectExplorerSection explorerSection = [possibleSection unsignedIntegerValue]; + if ([self numberOfRowsForExplorerSection:explorerSection] > 0) { + [visibleSections addObject:possibleSection]; + } + } + + return visibleSections; +} + +- (NSString *)sectionTitleWithBaseName:(NSString *)baseName totalCount:(NSUInteger)totalCount filteredCount:(NSUInteger)filteredCount +{ + NSString *sectionTitle = nil; + if (totalCount == filteredCount) { + sectionTitle = [baseName stringByAppendingFormat:@" (%lu)", (unsigned long)totalCount]; + } else { + sectionTitle = [baseName stringByAppendingFormat:@" (%lu of %lu)", (unsigned long)filteredCount, (unsigned long)totalCount]; + } + return sectionTitle; +} + +- (FLEXObjectExplorerSection)explorerSectionAtIndex:(NSInteger)sectionIndex +{ + return [[[self visibleExplorerSections] objectAtIndex:sectionIndex] unsignedIntegerValue]; +} + +- (NSInteger)numberOfRowsForExplorerSection:(FLEXObjectExplorerSection)section +{ + NSInteger numberOfRows = 0; + switch (section) { + case FLEXObjectExplorerSectionDescription: + numberOfRows = [self shouldShowDescription] ? 1 : 0; + break; + + case FLEXObjectExplorerSectionCustom: + numberOfRows = [self.customSectionVisibleIndexes count]; + break; + + case FLEXObjectExplorerSectionProperties: + numberOfRows = [self.filteredProperties count]; + break; + + case FLEXObjectExplorerSectionIvars: + numberOfRows = [self.filteredIvars count]; + break; + + case FLEXObjectExplorerSectionMethods: + numberOfRows = [self.filteredMethods count]; + break; + + case FLEXObjectExplorerSectionClassMethods: + numberOfRows = [self.filteredClassMethods count]; + break; + + case FLEXObjectExplorerSectionSuperclasses: + numberOfRows = [self.filteredSuperclasses count]; + break; + + case FLEXObjectExplorerSectionReferencingInstances: + // Hide this section if there is fliter text since there's nothing searchable (only 1 row, always the same). + numberOfRows = [self.filterText length] == 0 ? 1 : 0; + break; + } + return numberOfRows; +} + +- (NSString *)titleForRow:(NSInteger)row inExplorerSection:(FLEXObjectExplorerSection)section +{ + NSString *title = nil; + switch (section) { + case FLEXObjectExplorerSectionDescription: + title = [FLEXUtility safeDescriptionForObject:self.object]; + break; + + case FLEXObjectExplorerSectionCustom: + title = [self customSectionTitleForRowCookie:[self customSectionRowCookieForVisibleRow:row]]; + break; + + case FLEXObjectExplorerSectionProperties: + title = [self titleForPropertyAtIndex:row]; + break; + + case FLEXObjectExplorerSectionIvars: + title = [self titleForIvarAtIndex:row]; + break; + + case FLEXObjectExplorerSectionMethods: + title = [self titleForMethodAtIndex:row]; + break; + + case FLEXObjectExplorerSectionClassMethods: + title = [self titleForClassMethodAtIndex:row]; + break; + + case FLEXObjectExplorerSectionSuperclasses: + title = NSStringFromClass(self.filteredSuperclasses[row]); + break; + + case FLEXObjectExplorerSectionReferencingInstances: + title = @"Other objects with ivars referencing this object"; + break; + } + return title; +} + +- (NSString *)subtitleForRow:(NSInteger)row inExplorerSection:(FLEXObjectExplorerSection)section +{ + NSString *subtitle = nil; + switch (section) { + case FLEXObjectExplorerSectionDescription: + break; + + case FLEXObjectExplorerSectionCustom: + subtitle = [self customSectionSubtitleForRowCookie:[self customSectionRowCookieForVisibleRow:row]]; + break; + + case FLEXObjectExplorerSectionProperties: + subtitle = [self canHaveInstanceState] ? [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[self valueForPropertyAtIndex:row]] : nil; + break; + + case FLEXObjectExplorerSectionIvars: + subtitle = [self canHaveInstanceState] ? [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[self valueForIvarAtIndex:row]] : nil; + break; + + case FLEXObjectExplorerSectionMethods: + break; + + case FLEXObjectExplorerSectionClassMethods: + break; + + case FLEXObjectExplorerSectionSuperclasses: + break; + + case FLEXObjectExplorerSectionReferencingInstances: + break; + } + return subtitle; +} + +- (BOOL)canDrillInToRow:(NSInteger)row inExplorerSection:(FLEXObjectExplorerSection)section +{ + BOOL canDrillIn = NO; + switch (section) { + case FLEXObjectExplorerSectionDescription: + break; + + case FLEXObjectExplorerSectionCustom: + canDrillIn = [self customSectionCanDrillIntoRowWithCookie:[self customSectionRowCookieForVisibleRow:row]]; + break; + + case FLEXObjectExplorerSectionProperties: { + if ([self canHaveInstanceState]) { + FLEXPropertyBox *propertyBox = self.filteredProperties[row]; + objc_property_t property = propertyBox.property; + id currentValue = [self valueForPropertyAtIndex:row]; + BOOL canEdit = [FLEXPropertyEditorViewController canEditProperty:property currentValue:currentValue]; + BOOL canExplore = currentValue != nil; + canDrillIn = canEdit || canExplore; + } + } break; + + case FLEXObjectExplorerSectionIvars: { + if ([self canHaveInstanceState]) { + FLEXIvarBox *ivarBox = self.filteredIvars[row]; + Ivar ivar = ivarBox.ivar; + id currentValue = [self valueForIvarAtIndex:row]; + BOOL canEdit = [FLEXIvarEditorViewController canEditIvar:ivar currentValue:currentValue]; + BOOL canExplore = currentValue != nil; + canDrillIn = canEdit || canExplore; + } + } break; + + case FLEXObjectExplorerSectionMethods: + canDrillIn = [self canCallInstanceMethods]; + break; + + case FLEXObjectExplorerSectionClassMethods: + canDrillIn = YES; + break; + + case FLEXObjectExplorerSectionSuperclasses: + canDrillIn = YES; + break; + + case FLEXObjectExplorerSectionReferencingInstances: + canDrillIn = YES; + break; + } + return canDrillIn; +} + +- (BOOL)canCopyRow:(NSInteger)row inExplorerSection:(FLEXObjectExplorerSection)section +{ + BOOL canCopy = NO; + + switch (section) { + case FLEXObjectExplorerSectionDescription: + canCopy = YES; + break; + + default: + break; + } + return canCopy; +} + +- (NSString *)titleForExplorerSection:(FLEXObjectExplorerSection)section +{ + NSString *title = nil; + switch (section) { + case FLEXObjectExplorerSectionDescription: { + title = @"Description"; + } break; + + case FLEXObjectExplorerSectionCustom: { + title = [self customSectionTitle]; + } break; + + case FLEXObjectExplorerSectionProperties: { + NSUInteger totalCount = [self.properties count]; + if (self.includeInheritance) { + totalCount += [self.inheritedProperties count]; + } + title = [self sectionTitleWithBaseName:@"Properties" totalCount:totalCount filteredCount:[self.filteredProperties count]]; + } break; + + case FLEXObjectExplorerSectionIvars: { + NSUInteger totalCount = [self.ivars count]; + if (self.includeInheritance) { + totalCount += [self.inheritedIvars count]; + } + title = [self sectionTitleWithBaseName:@"Ivars" totalCount:totalCount filteredCount:[self.filteredIvars count]]; + } break; + + case FLEXObjectExplorerSectionMethods: { + NSUInteger totalCount = [self.methods count]; + if (self.includeInheritance) { + totalCount += [self.inheritedMethods count]; + } + title = [self sectionTitleWithBaseName:@"Methods" totalCount:totalCount filteredCount:[self.filteredMethods count]]; + } break; + + case FLEXObjectExplorerSectionClassMethods: { + NSUInteger totalCount = [self.classMethods count]; + if (self.includeInheritance) { + totalCount += [self.inheritedClassMethods count]; + } + title = [self sectionTitleWithBaseName:@"Class Methods" totalCount:totalCount filteredCount:[self.filteredClassMethods count]]; + } break; + + case FLEXObjectExplorerSectionSuperclasses: { + title = [self sectionTitleWithBaseName:@"Superclasses" totalCount:[self.superclasses count] filteredCount:[self.filteredSuperclasses count]]; + } break; + + case FLEXObjectExplorerSectionReferencingInstances: { + title = @"Object Graph"; + } break; + } + return title; +} + +- (UIViewController *)drillInViewControllerForRow:(NSUInteger)row inExplorerSection:(FLEXObjectExplorerSection)section +{ + UIViewController *viewController = nil; + switch (section) { + case FLEXObjectExplorerSectionDescription: + break; + + case FLEXObjectExplorerSectionCustom: + viewController = [self customSectionDrillInViewControllerForRowCookie:[self customSectionRowCookieForVisibleRow:row]]; + break; + + case FLEXObjectExplorerSectionProperties: { + FLEXPropertyBox *propertyBox = self.filteredProperties[row]; + objc_property_t property = propertyBox.property; + id currentValue = [self valueForPropertyAtIndex:row]; + if ([FLEXPropertyEditorViewController canEditProperty:property currentValue:currentValue]) { + viewController = [[FLEXPropertyEditorViewController alloc] initWithTarget:self.object property:property]; + } else if (currentValue) { + viewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:currentValue]; + } + } break; + + case FLEXObjectExplorerSectionIvars: { + FLEXIvarBox *ivarBox = self.filteredIvars[row]; + Ivar ivar = ivarBox.ivar; + id currentValue = [self valueForIvarAtIndex:row]; + if ([FLEXIvarEditorViewController canEditIvar:ivar currentValue:currentValue]) { + viewController = [[FLEXIvarEditorViewController alloc] initWithTarget:self.object ivar:ivar]; + } else if (currentValue) { + viewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:currentValue]; + } + } break; + + case FLEXObjectExplorerSectionMethods: { + FLEXMethodBox *methodBox = self.filteredMethods[row]; + Method method = methodBox.method; + viewController = [[FLEXMethodCallingViewController alloc] initWithTarget:self.object method:method]; + } break; + + case FLEXObjectExplorerSectionClassMethods: { + FLEXMethodBox *methodBox = self.filteredClassMethods[row]; + Method method = methodBox.method; + viewController = [[FLEXMethodCallingViewController alloc] initWithTarget:[self.object class] method:method]; + } break; + + case FLEXObjectExplorerSectionSuperclasses: { + Class superclass = self.filteredSuperclasses[row]; + viewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:superclass]; + } break; + + case FLEXObjectExplorerSectionReferencingInstances: { + viewController = [FLEXInstancesTableViewController instancesTableViewControllerForInstancesReferencingObject:self.object]; + } break; + } + return viewController; +} + + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [[self visibleExplorerSections] count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:section]; + return [self numberOfRowsForExplorerSection:explorerSection]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:section]; + return [self titleForExplorerSection:explorerSection]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + + BOOL useDescriptionCell = explorerSection == FLEXObjectExplorerSectionDescription; + NSString *cellIdentifier = useDescriptionCell ? kFLEXMultilineTableViewCellIdentifier : @"cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; + if (!cell) { + if (useDescriptionCell) { + cell = [[FLEXMultilineTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; + cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + } else { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; + UIFont *cellFont = [FLEXUtility defaultTableViewCellLabelFont]; + cell.textLabel.font = cellFont; + cell.detailTextLabel.font = cellFont; + cell.detailTextLabel.textColor = [UIColor grayColor]; + } + } + + cell.textLabel.text = [self titleForRow:indexPath.row inExplorerSection:explorerSection]; + cell.detailTextLabel.text = [self subtitleForRow:indexPath.row inExplorerSection:explorerSection]; + cell.accessoryType = [self canDrillInToRow:indexPath.row inExplorerSection:explorerSection] ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + CGFloat height = self.tableView.rowHeight; + if (explorerSection == FLEXObjectExplorerSectionDescription) { + NSString *text = [self titleForRow:indexPath.row inExplorerSection:explorerSection]; + NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{ NSFontAttributeName : [FLEXUtility defaultTableViewCellLabelFont] }]; + CGFloat preferredHeight = [FLEXMultilineTableViewCell preferredHeightWithAttributedText:attributedText inTableViewWidth:self.tableView.frame.size.width style:tableView.style showsAccessory:NO]; + height = MAX(height, preferredHeight); + } + return height; +} + + +#pragma mark - Table View Delegate + +- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + return [self canDrillInToRow:indexPath.row inExplorerSection:explorerSection]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + UIViewController *detailViewController = [self drillInViewControllerForRow:indexPath.row inExplorerSection:explorerSection]; + if (detailViewController) { + [self.navigationController pushViewController:detailViewController animated:YES]; + } else { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + } +} + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath +{ + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + BOOL canCopy = [self canCopyRow:indexPath.row inExplorerSection:explorerSection]; + return canCopy; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + BOOL canPerformAction = NO; + + if (action == @selector(copy:)) { + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + BOOL canCopy = [self canCopyRow:indexPath.row inExplorerSection:explorerSection]; + canPerformAction = canCopy; + } + + return canPerformAction; +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender +{ + if (action == @selector(copy:)) { + FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section]; + NSString *stringToCopy = @""; + + NSString *title = [self titleForRow:indexPath.row inExplorerSection:explorerSection]; + if ([title length] > 0) { + stringToCopy = [stringToCopy stringByAppendingString:title]; + } + + NSString *subtitle = [self subtitleForRow:indexPath.row inExplorerSection:explorerSection]; + if ([subtitle length] > 0) { + if ([stringToCopy length] > 0) { + stringToCopy = [stringToCopy stringByAppendingString:@"\n\n"]; + } + stringToCopy = [stringToCopy stringByAppendingString:subtitle]; + } + + [[UIPasteboard generalPasteboard] setString:stringToCopy]; + } +} + + +#pragma mark - Custom Section + +- (void)updateCustomData +{ + self.cachedCustomSectionRowCookies = [self customSectionRowCookies]; +} + +- (void)updateFilteredCustomData +{ + NSIndexSet *filteredIndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self.cachedCustomSectionRowCookies count])]; + if ([self.filterText length] > 0) { + filteredIndexSet = [filteredIndexSet indexesPassingTest:^BOOL(NSUInteger index, BOOL *stop) { + BOOL matches = NO; + NSString *rowTitle = [self customSectionTitleForRowCookie:self.cachedCustomSectionRowCookies[index]]; + if ([rowTitle rangeOfString:self.filterText options:NSCaseInsensitiveSearch].location != NSNotFound) { + matches = YES; + } + return matches; + }]; + } + self.customSectionVisibleIndexes = filteredIndexSet; +} + +- (id)customSectionRowCookieForVisibleRow:(NSUInteger)row +{ + return [[self.cachedCustomSectionRowCookies objectsAtIndexes:self.customSectionVisibleIndexes] objectAtIndex:row]; +} + + +#pragma mark - Subclasses Can Override + +- (NSString *)customSectionTitle +{ + return nil; +} + +- (NSArray *)customSectionRowCookies +{ + return nil; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + return nil; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return nil; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return NO; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + return nil; +} + +- (BOOL)canHaveInstanceState +{ + return YES; +} + +- (BOOL)canCallInstanceMethods +{ + return YES; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.h new file mode 100755 index 0000000..7e43870 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXSetExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXSetExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.m new file mode 100755 index 0000000..f6e5fd1 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXSetExplorerViewController.m @@ -0,0 +1,64 @@ +// +// FLEXSetExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 5/16/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXSetExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXObjectExplorerFactory.h" + +@interface FLEXSetExplorerViewController () + +@property (nonatomic, readonly) NSSet *set; + +@end + +@implementation FLEXSetExplorerViewController + +- (NSSet *)set +{ + return [self.object isKindOfClass:[NSSet class]] ? self.object : nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Set Objects"; +} + +- (NSArray *)customSectionRowCookies +{ + return [self.set allObjects]; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + return [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:rowCookie]; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + return nil; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + return [FLEXObjectExplorerFactory explorerViewControllerForObject:rowCookie]; +} + +- (BOOL)shouldShowDescription +{ + return NO; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.h new file mode 100755 index 0000000..7b7ed75 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXViewControllerExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/11/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXViewControllerExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.m new file mode 100755 index 0000000..a9e5900 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewControllerExplorerViewController.m @@ -0,0 +1,96 @@ +// +// FLEXViewControllerExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/11/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXViewControllerExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXObjectExplorerFactory.h" + +typedef NS_ENUM(NSUInteger, FLEXViewControllerExplorerRow) { + FLEXViewControllerExplorerRowPush, + FLEXViewControllerExplorerRowView +}; + +@interface FLEXViewControllerExplorerViewController () + +@property (nonatomic, readonly) UIViewController *viewController; + +@end + +@implementation FLEXViewControllerExplorerViewController + +- (UIViewController *)viewController +{ + return [self.object isKindOfClass:[UIViewController class]] ? self.object : nil; +} + +- (BOOL)canPushViewController +{ + // Only show the "Push View Controller" option if it's not already part of the hierarchy to avoid really disrupting the app. + return self.viewController.view.window == nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Shortcuts"; +} + +- (NSArray *)customSectionRowCookies +{ + NSArray *rowCookies = @[@(FLEXViewControllerExplorerRowView)]; + if ([self canPushViewController]) { + rowCookies = [@[@(FLEXViewControllerExplorerRowPush)] arrayByAddingObjectsFromArray:rowCookies]; + } + return rowCookies; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + NSString *title = nil; + if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowPush)]) { + title = @"Push View Controller"; + } else if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowView)]) { + title = @"@property UIView *view"; + } + return title; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + NSString *subtitle = nil; + if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowView)]) { + subtitle = [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:self.viewController.view]; + } + return subtitle; +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + BOOL canDrillIn = NO; + if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowPush)]) { + canDrillIn = [self canPushViewController]; + }else if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowView)]) { + canDrillIn = self.viewController.view != nil; + } + return canDrillIn; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowPush)]) { + drillInViewController = self.viewController; + } else if ([rowCookie isEqual:@(FLEXViewControllerExplorerRowView)]) { + drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:self.viewController.view]; + } + return drillInViewController; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.h new file mode 100755 index 0000000..241ff1d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.h @@ -0,0 +1,13 @@ +// +// FLEXViewExplorerViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/11/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXObjectExplorerViewController.h" + +@interface FLEXViewExplorerViewController : FLEXObjectExplorerViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.m new file mode 100755 index 0000000..fe9ccc9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ObjectExplorers/FLEXViewExplorerViewController.m @@ -0,0 +1,217 @@ +// +// FLEXViewExplorerViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/11/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXViewExplorerViewController.h" +#import "FLEXRuntimeUtility.h" +#import "FLEXUtility.h" +#import "FLEXObjectExplorerFactory.h" +#import "FLEXImagePreviewViewController.h" +#import "FLEXPropertyEditorViewController.h" + +typedef NS_ENUM(NSUInteger, FLEXViewExplorerRow) { + FLEXViewExplorerRowViewController, + FLEXViewExplorerRowPreview, + FLEXViewExplorerRowViewControllerForAncestor +}; + +@interface FLEXViewExplorerViewController () + +// Don't clash with UIViewController's view property +@property (nonatomic, readonly) UIView *viewToExplore; + +@end + +@implementation FLEXViewExplorerViewController + +- (UIView *)viewToExplore +{ + return [self.object isKindOfClass:[UIView class]] ? self.object : nil; +} + + +#pragma mark - Superclass Overrides + +- (NSString *)customSectionTitle +{ + return @"Shortcuts"; +} + +- (NSArray *)customSectionRowCookies +{ + NSMutableArray *rowCookies = [NSMutableArray array]; + + if ([FLEXUtility viewControllerForView:self.viewToExplore]) { + [rowCookies addObject:@(FLEXViewExplorerRowViewController)]; + }else{ + [rowCookies addObject:@(FLEXViewExplorerRowViewControllerForAncestor)]; + } + + [rowCookies addObject:@(FLEXViewExplorerRowPreview)]; + [rowCookies addObjectsFromArray:[self shortcutPropertyNames]]; + + return rowCookies; +} + +- (NSArray *)shortcutPropertyNames +{ + NSArray *propertyNames = @[@"frame", @"bounds", @"center", @"transform", @"backgroundColor", @"alpha", @"opaque", @"hidden", @"clipsToBounds", @"userInteractionEnabled", @"layer"]; + + if ([self.viewToExplore isKindOfClass:[UILabel class]]) { + propertyNames = [@[@"text", @"font", @"textColor"] arrayByAddingObjectsFromArray:propertyNames]; + } + + return propertyNames; +} + +- (NSString *)customSectionTitleForRowCookie:(id)rowCookie +{ + NSString *title = nil; + + if ([rowCookie isKindOfClass:[NSNumber class]]) { + FLEXViewExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXViewExplorerRowViewController: + title = @"View Controller"; + break; + + case FLEXViewExplorerRowPreview: + title = @"Preview Image"; + break; + + case FLEXViewExplorerRowViewControllerForAncestor: + title = @"View Controller For Ancestor"; + break; + } + } else if ([rowCookie isKindOfClass:[NSString class]]) { + objc_property_t property = [self viewPropertyForName:rowCookie]; + if (property) { + NSString *prettyPropertyName = [FLEXRuntimeUtility prettyNameForProperty:property]; + // Since we're outside of the "properties" section, prepend @property for clarity. + title = [NSString stringWithFormat:@"@property %@", prettyPropertyName]; + } + } + + return title; +} + +- (NSString *)customSectionSubtitleForRowCookie:(id)rowCookie +{ + NSString *subtitle = nil; + + if ([rowCookie isKindOfClass:[NSNumber class]]) { + FLEXViewExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXViewExplorerRowViewController: + subtitle = [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[FLEXUtility viewControllerForView:self.viewToExplore]]; + break; + + case FLEXViewExplorerRowPreview: + break; + + case FLEXViewExplorerRowViewControllerForAncestor: + subtitle = [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:[FLEXUtility viewControllerForAncestralView:self.viewToExplore]]; + break; + } + } else if ([rowCookie isKindOfClass:[NSString class]]) { + objc_property_t property = [self viewPropertyForName:rowCookie]; + if (property) { + id value = [FLEXRuntimeUtility valueForProperty:property onObject:self.viewToExplore]; + subtitle = [FLEXRuntimeUtility descriptionForIvarOrPropertyValue:value]; + } + } + + return subtitle; +} + +- (objc_property_t)viewPropertyForName:(NSString *)propertyName +{ + return class_getProperty([self.viewToExplore class], [propertyName UTF8String]); +} + +- (BOOL)customSectionCanDrillIntoRowWithCookie:(id)rowCookie +{ + return YES; +} + +- (UIViewController *)customSectionDrillInViewControllerForRowCookie:(id)rowCookie +{ + UIViewController *drillInViewController = nil; + + if ([rowCookie isKindOfClass:[NSNumber class]]) { + FLEXViewExplorerRow row = [rowCookie unsignedIntegerValue]; + switch (row) { + case FLEXViewExplorerRowViewController: + drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:[FLEXUtility viewControllerForView:self.viewToExplore]]; + break; + + case FLEXViewExplorerRowPreview: + drillInViewController = [[self class] imagePreviewViewControllerForView:self.viewToExplore]; + break; + + case FLEXViewExplorerRowViewControllerForAncestor: + drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:[FLEXUtility viewControllerForAncestralView:self.viewToExplore]]; + break; + } + } else if ([rowCookie isKindOfClass:[NSString class]]) { + objc_property_t property = [self viewPropertyForName:rowCookie]; + if (property) { + id currentValue = [FLEXRuntimeUtility valueForProperty:property onObject:self.viewToExplore]; + if ([FLEXPropertyEditorViewController canEditProperty:property currentValue:currentValue]) { + drillInViewController = [[FLEXPropertyEditorViewController alloc] initWithTarget:self.object property:property]; + } else { + drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:currentValue]; + } + } + } + + return drillInViewController; +} + ++ (UIViewController *)imagePreviewViewControllerForView:(UIView *)view +{ + UIViewController *imagePreviewViewController = nil; + if (!CGRectIsEmpty(view.bounds)) { + CGSize viewSize = view.bounds.size; + UIGraphicsBeginImageContextWithOptions(viewSize, NO, 0.0); + [view drawViewHierarchyInRect:CGRectMake(0, 0, viewSize.width, viewSize.height) afterScreenUpdates:YES]; + UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + imagePreviewViewController = [[FLEXImagePreviewViewController alloc] initWithImage:previewImage]; + } + return imagePreviewViewController; +} + + +#pragma mark - Runtime Adjustment + ++ (void)initialize +{ + // A quirk of UIView: a lot of the "@property"s are not actually properties from the perspective of the runtime. + // We add these properties to the class at runtime if they haven't been added yet. + // This way, we can use our property editor to access and change them. + // The property attributes match the declared attributes in UIView.h + NSDictionary *frameAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(@encode(CGRect)), kFLEXUtilityAttributeNonAtomic : @""}; + [FLEXRuntimeUtility tryAddPropertyWithName:"frame" attributes:frameAttributes toClass:[UIView class]]; + + NSDictionary *alphaAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(@encode(CGFloat)), kFLEXUtilityAttributeNonAtomic : @""}; + [FLEXRuntimeUtility tryAddPropertyWithName:"alpha" attributes:alphaAttributes toClass:[UIView class]]; + + NSDictionary *clipsAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(@encode(BOOL)), kFLEXUtilityAttributeNonAtomic : @""}; + [FLEXRuntimeUtility tryAddPropertyWithName:"clipsToBounds" attributes:clipsAttributes toClass:[UIView class]]; + + NSDictionary *opaqueAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(@encode(BOOL)), kFLEXUtilityAttributeNonAtomic : @"", kFLEXUtilityAttributeCustomGetter : @"isOpaque"}; + [FLEXRuntimeUtility tryAddPropertyWithName:"opaque" attributes:opaqueAttributes toClass:[UIView class]]; + + NSDictionary *hiddenAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(@encode(BOOL)), kFLEXUtilityAttributeNonAtomic : @"", kFLEXUtilityAttributeCustomGetter : @"isHidden"}; + [FLEXRuntimeUtility tryAddPropertyWithName:"hidden" attributes:hiddenAttributes toClass:[UIView class]]; + + NSDictionary *backgroundColorAttributes = @{kFLEXUtilityAttributeTypeEncoding : @(FLEXEncodeClass(UIColor)), kFLEXUtilityAttributeNonAtomic : @"", kFLEXUtilityAttributeCopy : @""}; + [FLEXRuntimeUtility tryAddPropertyWithName:"backgroundColor" attributes:backgroundColorAttributes toClass:[UIView class]]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.h new file mode 100755 index 0000000..f6de0c7 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.h @@ -0,0 +1,49 @@ +// +// FLEXExplorerToolbar.h +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@class FLEXToolbarItem; + +@interface FLEXExplorerToolbar : UIView + +/// Toolbar item for selecting views. +/// Users of the toolbar can configure the enabled/selected state and event targets/actions. +@property (nonatomic, strong, readonly) FLEXToolbarItem *selectItem; + +/// Toolbar item for presenting a list with the view hierarchy. +/// Users of the toolbar can configure the enabled state and event targets/actions. +@property (nonatomic, strong, readonly) FLEXToolbarItem *hierarchyItem; + +/// Toolbar item for moving views. +/// Users of the toolbar can configure the enabled/selected state and event targets/actions. +@property (nonatomic, strong, readonly) FLEXToolbarItem *moveItem; + +/// Toolbar item for inspecting details of the selected view. +/// Users of the toolbar can configure the enabled state and event targets/actions. +@property (nonatomic, strong, readonly) FLEXToolbarItem *globalsItem; + +/// Toolbar item for hiding the explorer. +/// Users of the toolbar can configure the event targets/actions. +@property (nonatomic, strong, readonly) FLEXToolbarItem *closeItem; + +/// A view for moving the entire toolbar. +/// Users of the toolbar can attach a pan gesture recognizer to decide how to reposition the toolbar. +@property (nonatomic, strong, readonly) UIView *dragHandle; + +/// A color matching the overlay on color on the selected view. +@property (nonatomic, strong) UIColor *selectedViewOverlayColor; + +/// Description text for the selected view displayed below the toolbar items. +@property (nonatomic, copy) NSString *selectedViewDescription; + +/// Area where details of the selected view are shown +/// Users of the toolbar can attach a tap gesture recognizer to show additional details. +@property (nonatomic, strong, readonly) UIView *selectedViewDescriptionContainer; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.m new file mode 100755 index 0000000..c257101 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXExplorerToolbar.m @@ -0,0 +1,226 @@ +// +// FLEXExplorerToolbar.m +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXExplorerToolbar.h" +#import "FLEXToolbarItem.h" +#import "FLEXResources.h" +#import "FLEXUtility.h" + +@interface FLEXExplorerToolbar () + +@property (nonatomic, strong, readwrite) FLEXToolbarItem *selectItem; +@property (nonatomic, strong, readwrite) FLEXToolbarItem *moveItem; +@property (nonatomic, strong, readwrite) FLEXToolbarItem *globalsItem; +@property (nonatomic, strong, readwrite) FLEXToolbarItem *closeItem; +@property (nonatomic, strong, readwrite) FLEXToolbarItem *hierarchyItem; +@property (nonatomic, strong, readwrite) UIView *dragHandle; + +@property (nonatomic, strong) UIImageView *dragHandleImageView; + +@property (nonatomic, strong) NSArray *toolbarItems; + +@property (nonatomic, strong) UIView *selectedViewDescriptionContainer; +@property (nonatomic, strong) UIView *selectedViewColorIndicator; +@property (nonatomic, strong) UILabel *selectedViewDescriptionLabel; + +@end + +@implementation FLEXExplorerToolbar + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + NSMutableArray *toolbarItems = [NSMutableArray array]; + + self.dragHandle = [[UIView alloc] init]; + self.dragHandle.backgroundColor = [FLEXToolbarItem defaultBackgroundColor]; + [self addSubview:self.dragHandle]; + + UIImage *dragHandle = [FLEXResources dragHandle]; + self.dragHandleImageView = [[UIImageView alloc] initWithImage:dragHandle]; + [self.dragHandle addSubview:self.dragHandleImageView]; + + UIImage *globalsIcon = [FLEXResources globeIcon]; + self.globalsItem = [FLEXToolbarItem toolbarItemWithTitle:@"menu" image:globalsIcon]; + [self addSubview:self.globalsItem]; + [toolbarItems addObject:self.globalsItem]; + + UIImage *listIcon = [FLEXResources listIcon]; + self.hierarchyItem = [FLEXToolbarItem toolbarItemWithTitle:@"views" image:listIcon]; + [self addSubview:self.hierarchyItem]; + [toolbarItems addObject:self.hierarchyItem]; + + UIImage *selectIcon = [FLEXResources selectIcon]; + self.selectItem = [FLEXToolbarItem toolbarItemWithTitle:@"select" image:selectIcon]; + [self addSubview:self.selectItem]; + [toolbarItems addObject:self.selectItem]; + + UIImage *moveIcon = [FLEXResources moveIcon]; + self.moveItem = [FLEXToolbarItem toolbarItemWithTitle:@"move" image:moveIcon]; + [self addSubview:self.moveItem]; + [toolbarItems addObject:self.moveItem]; + + UIImage *closeIcon = [FLEXResources closeIcon]; + self.closeItem = [FLEXToolbarItem toolbarItemWithTitle:@"close" image:closeIcon]; + [self addSubview:self.closeItem]; + [toolbarItems addObject:self.closeItem]; + + self.toolbarItems = toolbarItems; + self.backgroundColor = [UIColor clearColor]; + + self.selectedViewDescriptionContainer = [[UIView alloc] init]; + self.selectedViewDescriptionContainer.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.95]; + self.selectedViewDescriptionContainer.hidden = YES; + [self addSubview:self.selectedViewDescriptionContainer]; + + self.selectedViewColorIndicator = [[UIView alloc] init]; + self.selectedViewColorIndicator.backgroundColor = [UIColor redColor]; + [self.selectedViewDescriptionContainer addSubview:self.selectedViewColorIndicator]; + + self.selectedViewDescriptionLabel = [[UILabel alloc] init]; + self.selectedViewDescriptionLabel.backgroundColor = [UIColor clearColor]; + self.selectedViewDescriptionLabel.font = [[self class] descriptionLabelFont]; + [self.selectedViewDescriptionContainer addSubview:self.selectedViewDescriptionLabel]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // Drag Handle + const CGFloat kToolbarItemHeight = [[self class] toolbarItemHeight]; + self.dragHandle.frame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, [[self class] dragHandleWidth], kToolbarItemHeight); + CGRect dragHandleImageFrame = self.dragHandleImageView.frame; + dragHandleImageFrame.origin.x = FLEXFloor((self.dragHandle.frame.size.width - dragHandleImageFrame.size.width) / 2.0); + dragHandleImageFrame.origin.y = FLEXFloor((self.dragHandle.frame.size.height - dragHandleImageFrame.size.height) / 2.0); + self.dragHandleImageView.frame = dragHandleImageFrame; + + + // Toolbar Items + CGFloat originX = CGRectGetMaxX(self.dragHandle.frame); + CGFloat originY = self.bounds.origin.y; + CGFloat height = kToolbarItemHeight; + CGFloat width = FLEXFloor((CGRectGetMaxX(self.bounds) - originX) / [self.toolbarItems count]); + for (UIView *toolbarItem in self.toolbarItems) { + toolbarItem.frame = CGRectMake(originX, originY, width, height); + originX = CGRectGetMaxX(toolbarItem.frame); + } + + // Make sure the last toolbar item goes to the edge to account for any accumulated rounding effects. + UIView *lastToolbarItem = [self.toolbarItems lastObject]; + CGRect lastToolbarItemFrame = lastToolbarItem.frame; + lastToolbarItemFrame.size.width = CGRectGetMaxX(self.bounds) - lastToolbarItemFrame.origin.x; + lastToolbarItem.frame = lastToolbarItemFrame; + + const CGFloat kSelectedViewColorDiameter = [[self class] selectedViewColorIndicatorDiameter]; + const CGFloat kDescriptionLabelHeight = [[self class] descriptionLabelHeight]; + const CGFloat kHorizontalPadding = [[self class] horizontalPadding]; + const CGFloat kDescriptionVerticalPadding = [[self class] descriptionVerticalPadding]; + const CGFloat kDescriptionContainerHeight = [[self class] descriptionContainerHeight]; + + CGRect descriptionContainerFrame = CGRectZero; + descriptionContainerFrame.size.height = kDescriptionContainerHeight; + descriptionContainerFrame.origin.y = CGRectGetMaxY(self.bounds) - kDescriptionContainerHeight; + descriptionContainerFrame.size.width = self.bounds.size.width; + self.selectedViewDescriptionContainer.frame = descriptionContainerFrame; + + // Selected View Color + CGRect selectedViewColorFrame = CGRectZero; + selectedViewColorFrame.size.width = kSelectedViewColorDiameter; + selectedViewColorFrame.size.height = kSelectedViewColorDiameter; + selectedViewColorFrame.origin.x = kHorizontalPadding; + selectedViewColorFrame.origin.y = FLEXFloor((kDescriptionContainerHeight - kSelectedViewColorDiameter) / 2.0); + self.selectedViewColorIndicator.frame = selectedViewColorFrame; + self.selectedViewColorIndicator.layer.cornerRadius = ceil(selectedViewColorFrame.size.height / 2.0); + + // Selected View Description + CGRect descriptionLabelFrame = CGRectZero; + CGFloat descriptionOriginX = CGRectGetMaxX(selectedViewColorFrame) + kHorizontalPadding; + descriptionLabelFrame.size.height = kDescriptionLabelHeight; + descriptionLabelFrame.origin.x = descriptionOriginX; + descriptionLabelFrame.origin.y = kDescriptionVerticalPadding; + descriptionLabelFrame.size.width = CGRectGetMaxX(self.selectedViewDescriptionContainer.bounds) - kHorizontalPadding - descriptionOriginX; + self.selectedViewDescriptionLabel.frame = descriptionLabelFrame; +} + + +#pragma mark - Setter Overrides + +- (void)setSelectedViewOverlayColor:(UIColor *)selectedViewOverlayColor +{ + if (![_selectedViewOverlayColor isEqual:selectedViewOverlayColor]) { + _selectedViewOverlayColor = selectedViewOverlayColor; + self.selectedViewColorIndicator.backgroundColor = selectedViewOverlayColor; + } +} + +- (void)setSelectedViewDescription:(NSString *)selectedViewDescription +{ + if (![_selectedViewDescription isEqual:selectedViewDescription]) { + _selectedViewDescription = selectedViewDescription; + self.selectedViewDescriptionLabel.text = selectedViewDescription; + BOOL showDescription = [selectedViewDescription length] > 0; + self.selectedViewDescriptionContainer.hidden = !showDescription; + } +} + + +#pragma mark - Sizing Convenience Methods + ++ (UIFont *)descriptionLabelFont +{ + return [UIFont systemFontOfSize:12.0]; +} + ++ (CGFloat)toolbarItemHeight +{ + return 44.0; +} + ++ (CGFloat)dragHandleWidth +{ + return 30.0; +} + ++ (CGFloat)descriptionLabelHeight +{ + return ceil([[self descriptionLabelFont] lineHeight]); +} + ++ (CGFloat)descriptionVerticalPadding +{ + return 2.0; +} + ++ (CGFloat)descriptionContainerHeight +{ + return [self descriptionVerticalPadding] * 2.0 + [self descriptionLabelHeight]; +} + ++ (CGFloat)selectedViewColorIndicatorDiameter +{ + return ceil([self descriptionLabelHeight] / 2.0); +} + ++ (CGFloat)horizontalPadding +{ + return 11.0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGFloat height = 0.0; + height += [[self class] toolbarItemHeight]; + height += [[self class] descriptionContainerHeight]; + return CGSizeMake(size.width, height); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.h new file mode 100755 index 0000000..9c297e0 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.h @@ -0,0 +1,17 @@ +// +// FLEXToolbarItem.h +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXToolbarItem : UIButton + ++ (instancetype)toolbarItemWithTitle:(NSString *)title image:(UIImage *)image; + ++ (UIColor *)defaultBackgroundColor; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.m new file mode 100755 index 0000000..734f7f8 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Toolbar/FLEXToolbarItem.m @@ -0,0 +1,133 @@ +// +// FLEXToolbarItem.m +// Flipboard +// +// Created by Ryan Olson on 4/4/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXToolbarItem.h" +#import "FLEXUtility.h" + +@interface FLEXToolbarItem () + +@property (nonatomic, copy) NSAttributedString *attributedTitle; +@property (nonatomic, strong) UIImage *image; + +@end + +@implementation FLEXToolbarItem + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [[self class] defaultBackgroundColor]; + [self setTitleColor:[[self class] defaultTitleColor] forState:UIControlStateNormal]; + [self setTitleColor:[[self class] disabledTitleColor] forState:UIControlStateDisabled]; + } + return self; +} + ++ (instancetype)toolbarItemWithTitle:(NSString *)title image:(UIImage *)image +{ + FLEXToolbarItem *toolbarItem = [self buttonWithType:UIButtonTypeCustom]; + NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title attributes:[self titleAttributes]]; + toolbarItem.attributedTitle = attributedTitle; + toolbarItem.image = image; + [toolbarItem setAttributedTitle:attributedTitle forState:UIControlStateNormal]; + [toolbarItem setImage:image forState:UIControlStateNormal]; + return toolbarItem; +} + + +#pragma mark - Display Defaults + ++ (NSDictionary *)titleAttributes +{ + return @{NSFontAttributeName : [FLEXUtility defaultFontOfSize:12.0]}; +} + ++ (UIColor *)defaultTitleColor +{ + return [UIColor blackColor]; +} + ++ (UIColor *)disabledTitleColor +{ + return [UIColor colorWithWhite:121.0/255.0 alpha:1.0]; +} + ++ (UIColor *)highlightedBackgroundColor +{ + return [UIColor colorWithWhite:0.9 alpha:1.0]; +} + ++ (UIColor *)selectedBackgroundColor +{ + return [UIColor colorWithRed:199.0/255.0 green:199.0/255.0 blue:255.0/255.0 alpha:1.0]; +} + ++ (UIColor *)defaultBackgroundColor +{ + return [UIColor colorWithWhite:1.0 alpha:0.95]; +} + ++ (CGFloat)topMargin +{ + return 2.0; +} + + +#pragma mark - State Changes + +- (void)setHighlighted:(BOOL)highlighted +{ + [super setHighlighted:highlighted]; + [self updateBackgroundColor]; +} + +- (void)setSelected:(BOOL)selected +{ + [super setSelected:selected]; + [self updateBackgroundColor]; +} + +- (void)updateBackgroundColor +{ + if (self.highlighted) { + self.backgroundColor = [[self class] highlightedBackgroundColor]; + } else if (self.selected) { + self.backgroundColor = [[self class] selectedBackgroundColor]; + } else { + self.backgroundColor = [[self class] defaultBackgroundColor]; + } +} + + +#pragma mark - UIButton Layout Overrides + +- (CGRect)titleRectForContentRect:(CGRect)contentRect +{ + // Bottom aligned and centered. + CGRect titleRect = CGRectZero; + CGSize titleSize = [self.attributedTitle boundingRectWithSize:contentRect.size options:0 context:nil].size; + titleSize = CGSizeMake(ceil(titleSize.width), ceil(titleSize.height)); + titleRect.size = titleSize; + titleRect.origin.y = contentRect.origin.y + CGRectGetMaxY(contentRect) - titleSize.height; + titleRect.origin.x = contentRect.origin.x + FLEXFloor((contentRect.size.width - titleSize.width) / 2.0); + return titleRect; +} + +- (CGRect)imageRectForContentRect:(CGRect)contentRect +{ + CGSize imageSize = self.image.size; + CGRect titleRect = [self titleRectForContentRect:contentRect]; + CGFloat availableHeight = contentRect.size.height - titleRect.size.height - [[self class] topMargin]; + CGFloat originY = [[self class] topMargin] + FLEXFloor((availableHeight - imageSize.height) / 2.0); + CGFloat originX = FLEXFloor((contentRect.size.width - imageSize.width) / 2.0); + CGRect imageRect = CGRectMake(originX, originY, imageSize.width, imageSize.height); + return imageRect; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.h new file mode 100755 index 0000000..87109f0 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.h @@ -0,0 +1,17 @@ +// +// FLEXHeapEnumerator.h +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +typedef void (^flex_object_enumeration_block_t)(__unsafe_unretained id object, __unsafe_unretained Class actualClass); + +@interface FLEXHeapEnumerator : NSObject + ++ (void)enumerateLiveObjectsUsingBlock:(flex_object_enumeration_block_t)block; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.m new file mode 100755 index 0000000..53c3acc --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXHeapEnumerator.m @@ -0,0 +1,96 @@ +// +// FLEXHeapEnumerator.m +// Flipboard +// +// Created by Ryan Olson on 5/28/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXHeapEnumerator.h" +#import +#import +#import + +static CFMutableSetRef registeredClasses; + +// Mimics the objective-c object stucture for checking if a range of memory is an object. +typedef struct { + Class isa; +} flex_maybe_object_t; + +@implementation FLEXHeapEnumerator + +static void range_callback(task_t task, void *context, unsigned type, vm_range_t *ranges, unsigned rangeCount) +{ + flex_object_enumeration_block_t block = (__bridge flex_object_enumeration_block_t)context; + if (!block) { + return; + } + + for (unsigned int i = 0; i < rangeCount; i++) { + vm_range_t range = ranges[i]; + flex_maybe_object_t *tryObject = (flex_maybe_object_t *)range.address; + Class tryClass = NULL; +#ifdef __arm64__ + // See http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html + extern uint64_t objc_debug_isa_class_mask WEAK_IMPORT_ATTRIBUTE; + tryClass = (__bridge Class)((void *)((uint64_t)tryObject->isa & objc_debug_isa_class_mask)); +#else + tryClass = tryObject->isa; +#endif + // If the class pointer matches one in our set of class pointers from the runtime, then we should have an object. + if (CFSetContainsValue(registeredClasses, (__bridge const void *)(tryClass))) { + block((__bridge id)tryObject, tryClass); + } + } +} + +static kern_return_t reader(__unused task_t remote_task, vm_address_t remote_address, __unused vm_size_t size, void **local_memory) +{ + *local_memory = (void *)remote_address; + return KERN_SUCCESS; +} + ++ (void)enumerateLiveObjectsUsingBlock:(flex_object_enumeration_block_t)block +{ + if (!block) { + return; + } + + // Refresh the class list on every call in case classes are added to the runtime. + [self updateRegisteredClasses]; + + // Inspired by: + // http://llvm.org/svn/llvm-project/lldb/tags/RELEASE_34/final/examples/darwin/heap_find/heap/heap_find.cpp + // https://gist.github.com/samdmarshall/17f4e66b5e2e579fd396 + + vm_address_t *zones = NULL; + unsigned int zoneCount = 0; + kern_return_t result = malloc_get_all_zones(TASK_NULL, reader, &zones, &zoneCount); + + if (result == KERN_SUCCESS) { + for (unsigned int i = 0; i < zoneCount; i++) { + malloc_zone_t *zone = (malloc_zone_t *)zones[i]; + if (zone->introspect && zone->introspect->enumerator) { + zone->introspect->enumerator(TASK_NULL, (__bridge void *)block, MALLOC_PTR_IN_USE_RANGE_TYPE, (vm_address_t)zone, reader, &range_callback); + } + } + } +} + ++ (void)updateRegisteredClasses +{ + if (!registeredClasses) { + registeredClasses = CFSetCreateMutable(NULL, 0, NULL); + } else { + CFSetRemoveAllValues(registeredClasses); + } + unsigned int count = 0; + Class *classes = objc_copyClassList(&count); + for (unsigned int i = 0; i < count; i++) { + CFSetAddValue(registeredClasses, (__bridge const void *)(classes[i])); + } + free(classes); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.h new file mode 100755 index 0000000..e688c85 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.h @@ -0,0 +1,13 @@ +// +// FLEXKeyboardHelpViewController.h +// UICatalog +// +// Created by Ryan Olson on 9/19/15. +// Copyright © 2015 f. All rights reserved. +// + +#import + +@interface FLEXKeyboardHelpViewController : UIViewController + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.m new file mode 100755 index 0000000..5282b34 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardHelpViewController.m @@ -0,0 +1,44 @@ +// +// FLEXKeyboardHelpViewController.m +// UICatalog +// +// Created by Ryan Olson on 9/19/15. +// Copyright © 2015 f. All rights reserved. +// + +#import "FLEXKeyboardHelpViewController.h" +#import "FLEXKeyboardShortcutManager.h" + +@interface FLEXKeyboardHelpViewController () + +@property (nonatomic, strong) UITextView *textView; + +@end + +@implementation FLEXKeyboardHelpViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; + self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + [self.view addSubview:self.textView]; +#if TARGET_OS_SIMULATOR + self.textView.text = [[FLEXKeyboardShortcutManager sharedManager] keyboardShortcutsDescription]; +#endif + self.textView.backgroundColor = [UIColor blackColor]; + self.textView.textColor = [UIColor whiteColor]; + self.textView.font = [UIFont boldSystemFontOfSize:14.0]; + self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; + + self.title = @"Simulator Shortcuts"; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)]; +} + +- (void)donePressed:(id)sender +{ + [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.h new file mode 100755 index 0000000..732a8cb --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.h @@ -0,0 +1,24 @@ +// +// FLEXKeyboardShortcutManager.h +// FLEX +// +// Created by Ryan Olson on 9/19/15. +// Copyright © 2015 Flipboard. All rights reserved. +// + +#import + +#if TARGET_OS_SIMULATOR + +@interface FLEXKeyboardShortcutManager : NSObject + ++ (instancetype)sharedManager; + +- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description; +- (NSString *)keyboardShortcutsDescription; + +@property (nonatomic, assign, getter=isEnabled) BOOL enabled; + +@end + +#endif diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.m new file mode 100755 index 0000000..b55138e --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXKeyboardShortcutManager.m @@ -0,0 +1,306 @@ +// +// FLEXKeyboardShortcutManager.m +// FLEX +// +// Created by Ryan Olson on 9/19/15. +// Copyright © 2015 Flipboard. All rights reserved. +// + +#import "FLEXKeyboardShortcutManager.h" +#import "FLEXUtility.h" +#import +#import + +#if TARGET_OS_SIMULATOR + +@interface UIEvent (UIPhysicalKeyboardEvent) + +@property (nonatomic, strong) NSString *_modifiedInput; +@property (nonatomic, strong) NSString *_unmodifiedInput; +@property (nonatomic, assign) UIKeyModifierFlags _modifierFlags; +@property (nonatomic, assign) BOOL _isKeyDown; +@property (nonatomic, assign) long _keyCode; + +@end + +@interface FLEXKeyInput : NSObject + +@property (nonatomic, copy, readonly) NSString *key; +@property (nonatomic, assign, readonly) UIKeyModifierFlags flags; +@property (nonatomic, copy, readonly) NSString *helpDescription; + +@end + +@implementation FLEXKeyInput + +- (BOOL)isEqual:(id)object +{ + BOOL isEqual = NO; + if ([object isKindOfClass:[FLEXKeyInput class]]) { + FLEXKeyInput *keyCommand = (FLEXKeyInput *)object; + BOOL equalKeys = self.key == keyCommand.key || [self.key isEqual:keyCommand.key]; + BOOL equalFlags = self.flags == keyCommand.flags; + isEqual = equalKeys && equalFlags; + } + return isEqual; +} + +- (NSUInteger)hash +{ + return [self.key hash] ^ self.flags; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [[self class] keyInputForKey:self.key flags:self.flags helpDescription:self.helpDescription]; +} + +- (NSString *)description +{ + NSDictionary *keyMappings = @{ UIKeyInputUpArrow : @"↑", + UIKeyInputDownArrow : @"↓", + UIKeyInputLeftArrow : @"←", + UIKeyInputRightArrow : @"→", + UIKeyInputEscape : @"␛", + @" " : @"␠"}; + + NSString *prettyKey = nil; + if (self.key && keyMappings[self.key]) { + prettyKey = keyMappings[self.key]; + } else { + prettyKey = [self.key uppercaseString]; + } + + NSString *prettyFlags = @""; + if (self.flags & UIKeyModifierControl) { + prettyFlags = [prettyFlags stringByAppendingString:@"⌃"]; + } + if (self.flags & UIKeyModifierAlternate) { + prettyFlags = [prettyFlags stringByAppendingString:@"⌥"]; + } + if (self.flags & UIKeyModifierShift) { + prettyFlags = [prettyFlags stringByAppendingString:@"⇧"]; + } + if (self.flags & UIKeyModifierCommand) { + prettyFlags = [prettyFlags stringByAppendingString:@"⌘"]; + } + + // Fudging to get easy columns with tabs + if ([prettyFlags length] < 2) { + prettyKey = [prettyKey stringByAppendingString:@"\t"]; + } + + return [NSString stringWithFormat:@"%@%@\t%@", prettyFlags, prettyKey, self.helpDescription]; +} + ++ (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags +{ + return [self keyInputForKey:key flags:flags helpDescription:nil]; +} + ++ (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription +{ + FLEXKeyInput *keyInput = [[self alloc] init]; + if (keyInput) { + keyInput->_key = key; + keyInput->_flags = flags; + keyInput->_helpDescription = helpDescription; + } + return keyInput; +} + +@end + +@interface FLEXKeyboardShortcutManager () + +@property (nonatomic, strong) NSMutableDictionary *actionsForKeyInputs; + +@property (nonatomic, assign, getter=isPressingShift) BOOL pressingShift; +@property (nonatomic, assign, getter=isPressingCommand) BOOL pressingCommand; +@property (nonatomic, assign, getter=isPressingControl) BOOL pressingControl; + +@end + +@implementation FLEXKeyboardShortcutManager + ++ (instancetype)sharedManager +{ + static FLEXKeyboardShortcutManager *sharedManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedManager = [[[self class] alloc] init]; + }); + return sharedManager; +} + ++ (void)load +{ + SEL originalKeyEventSelector = NSSelectorFromString(@"handleKeyUIEvent:"); + SEL swizzledKeyEventSelector = [FLEXUtility swizzledSelectorForSelector:originalKeyEventSelector]; + + void (^handleKeyUIEventSwizzleBlock)(UIApplication *, UIEvent *) = ^(UIApplication *slf, UIEvent *event) { + + [[[self class] sharedManager] handleKeyboardEvent:event]; + + ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledKeyEventSelector, event); + }; + + [FLEXUtility replaceImplementationOfKnownSelector:originalKeyEventSelector onClass:[UIApplication class] withBlock:handleKeyUIEventSwizzleBlock swizzledSelector:swizzledKeyEventSelector]; + + if ([[UITouch class] instancesRespondToSelector:@selector(maximumPossibleForce)]) { + SEL originalSendEventSelector = NSSelectorFromString(@"sendEvent:"); + SEL swizzledSendEventSelector = [FLEXUtility swizzledSelectorForSelector:originalSendEventSelector]; + + void (^sendEventSwizzleBlock)(UIApplication *, UIEvent *) = ^(UIApplication *slf, UIEvent *event) { + if (event.type == UIEventTypeTouches) { + FLEXKeyboardShortcutManager *keyboardManager = [FLEXKeyboardShortcutManager sharedManager]; + NSInteger pressureLevel = 0; + if (keyboardManager.isPressingShift) { + pressureLevel++; + } + if (keyboardManager.isPressingCommand) { + pressureLevel++; + } + if (keyboardManager.isPressingControl) { + pressureLevel++; + } + if (pressureLevel > 0) { + for (UITouch *touch in [event allTouches]) { + double adjustedPressureLevel = pressureLevel * 20 * touch.maximumPossibleForce; + [touch setValue:@(adjustedPressureLevel) forKey:@"_pressure"]; + } + } + } + + ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledSendEventSelector, event); + }; + + [FLEXUtility replaceImplementationOfKnownSelector:originalSendEventSelector onClass:[UIApplication class] withBlock:sendEventSwizzleBlock swizzledSelector:swizzledSendEventSelector]; + + SEL originalSupportsTouchPressureSelector = NSSelectorFromString(@"_supportsForceTouch"); + SEL swizzledSupportsTouchPressureSelector = [FLEXUtility swizzledSelectorForSelector:originalSupportsTouchPressureSelector]; + + BOOL (^supportsTouchPressureSwizzleBlock)(UIDevice *) = ^BOOL(UIDevice *slf) { + return YES; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:originalSupportsTouchPressureSelector onClass:[UIDevice class] withBlock:supportsTouchPressureSwizzleBlock swizzledSelector:swizzledSupportsTouchPressureSelector]; + } +} + +- (instancetype)init +{ + self = [super init]; + + if (self) { + _actionsForKeyInputs = [NSMutableDictionary dictionary]; + _enabled = YES; + } + + return self; +} + +- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description +{ + FLEXKeyInput *keyInput = [FLEXKeyInput keyInputForKey:key flags:modifiers helpDescription:description]; + [self.actionsForKeyInputs setObject:action forKey:keyInput]; +} + +static const long kFLEXControlKeyCode = 0xe0; +static const long kFLEXShiftKeyCode = 0xe1; +static const long kFLEXCommandKeyCode = 0xe3; + +- (void)handleKeyboardEvent:(UIEvent *)event +{ + if (!self.enabled) { + return; + } + + NSString *modifiedInput = nil; + NSString *unmodifiedInput = nil; + UIKeyModifierFlags flags = 0; + BOOL isKeyDown = NO; + + if ([event respondsToSelector:@selector(_modifiedInput)]) { + modifiedInput = [event _modifiedInput]; + } + + if ([event respondsToSelector:@selector(_unmodifiedInput)]) { + unmodifiedInput = [event _unmodifiedInput]; + } + + if ([event respondsToSelector:@selector(_modifierFlags)]) { + flags = [event _modifierFlags]; + } + + if ([event respondsToSelector:@selector(_isKeyDown)]) { + isKeyDown = [event _isKeyDown]; + } + + BOOL interactionEnabled = ![[UIApplication sharedApplication] isIgnoringInteractionEvents]; + BOOL hasFirstResponder = NO; + if (isKeyDown && [modifiedInput length] > 0 && interactionEnabled) { + UIResponder *firstResponder = nil; + for (UIWindow *window in [FLEXUtility allWindows]) { + firstResponder = [window valueForKey:@"firstResponder"]; + if (firstResponder) { + hasFirstResponder = YES; + break; + } + } + + // Ignore key commands (except escape) when there's an active responder + if (firstResponder) { + if ([unmodifiedInput isEqual:UIKeyInputEscape]) { + [firstResponder resignFirstResponder]; + } + } else { + FLEXKeyInput *exactMatch = [FLEXKeyInput keyInputForKey:unmodifiedInput flags:flags]; + + dispatch_block_t actionBlock = self.actionsForKeyInputs[exactMatch]; + + if (!actionBlock) { + FLEXKeyInput *shiftMatch = [FLEXKeyInput keyInputForKey:modifiedInput flags:flags&(!UIKeyModifierShift)]; + actionBlock = self.actionsForKeyInputs[shiftMatch]; + } + + if (!actionBlock) { + FLEXKeyInput *capitalMatch = [FLEXKeyInput keyInputForKey:[unmodifiedInput uppercaseString] flags:flags]; + actionBlock = self.actionsForKeyInputs[capitalMatch]; + } + + if (actionBlock) { + actionBlock(); + } + } + } + + // Calling _keyCode on events from the simulator keyboard will crash. + // It is only safe to call _keyCode when there's not an active responder. + if (!hasFirstResponder && [event respondsToSelector:@selector(_keyCode)]) { + long keyCode = [event _keyCode]; + if (keyCode == kFLEXControlKeyCode) { + self.pressingControl = isKeyDown; + } else if (keyCode == kFLEXCommandKeyCode) { + self.pressingCommand = isKeyDown; + } else if (keyCode == kFLEXShiftKeyCode) { + self.pressingShift = isKeyDown; + } + } +} + +- (NSString *)keyboardShortcutsDescription +{ + NSMutableString *description = [NSMutableString string]; + NSArray *keyInputs = [[self.actionsForKeyInputs allKeys] sortedArrayUsingComparator:^NSComparisonResult(FLEXKeyInput *_Nonnull input1, FLEXKeyInput *_Nonnull input2) { + return [input1.key caseInsensitiveCompare:input2.key]; + }]; + for (FLEXKeyInput *keyInput in keyInputs) { + [description appendFormat:@"%@\n", keyInput]; + } + return [description copy]; +} + +@end + +#endif diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.h new file mode 100755 index 0000000..b462df9 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.h @@ -0,0 +1,17 @@ +// +// FLEXMultilineTableViewCell.h +// UICatalog +// +// Created by Ryan Olson on 2/13/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import + +extern NSString *const kFLEXMultilineTableViewCellIdentifier; + +@interface FLEXMultilineTableViewCell : UITableViewCell + ++ (CGFloat)preferredHeightWithAttributedText:(NSAttributedString *)attributedText inTableViewWidth:(CGFloat)tableViewWidth style:(UITableViewStyle)style showsAccessory:(BOOL)showsAccessory; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.m new file mode 100755 index 0000000..de9b647 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXMultilineTableViewCell.m @@ -0,0 +1,55 @@ +// +// FLEXMultilineTableViewCell.m +// UICatalog +// +// Created by Ryan Olson on 2/13/15. +// Copyright (c) 2015 f. All rights reserved. +// + +#import "FLEXMultilineTableViewCell.h" + +NSString *const kFLEXMultilineTableViewCellIdentifier = @"kFLEXMultilineTableViewCellIdentifier"; + +@implementation FLEXMultilineTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.textLabel.numberOfLines = 0; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.textLabel.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, [[self class] labelInsets]); +} + ++ (UIEdgeInsets)labelInsets +{ + return UIEdgeInsetsMake(10.0, 15.0, 10.0, 15.0); +} + ++ (CGFloat)preferredHeightWithAttributedText:(NSAttributedString *)attributedText inTableViewWidth:(CGFloat)tableViewWidth style:(UITableViewStyle)style showsAccessory:(BOOL)showsAccessory +{ + CGFloat labelWidth = tableViewWidth; + + // Content view inset due to accessory view observed on iOS 8.1 iPhone 6. + if (showsAccessory) { + labelWidth -= 34.0; + } + + UIEdgeInsets labelInsets = [self labelInsets]; + labelWidth -= (labelInsets.left + labelInsets.right); + + CGSize constrainSize = CGSizeMake(labelWidth, CGFLOAT_MAX); + CGFloat preferredLabelHeight = ceil([attributedText boundingRectWithSize:constrainSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height); + CGFloat preferredCellHeight = preferredLabelHeight + labelInsets.top + labelInsets.bottom + 1.0; + + return preferredCellHeight; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.h new file mode 100755 index 0000000..58f7dc3 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.h @@ -0,0 +1,33 @@ +// +// FLEXResources.h +// FLEX +// +// Created by Ryan Olson on 6/8/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import +#import + +@interface FLEXResources : NSObject + ++ (UIImage *)closeIcon; ++ (UIImage *)dragHandle; ++ (UIImage *)globeIcon; ++ (UIImage *)hierarchyIndentPattern; ++ (UIImage *)listIcon; ++ (UIImage *)moveIcon; ++ (UIImage *)selectIcon; + ++ (UIImage *)jsonIcon; ++ (UIImage *)textPlainIcon; ++ (UIImage *)htmlIcon; ++ (UIImage *)audioIcon; ++ (UIImage *)jsIcon; ++ (UIImage *)plistIcon; ++ (UIImage *)textIcon; ++ (UIImage *)videoIcon; ++ (UIImage *)xmlIcon; ++ (UIImage *)binaryIcon; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.m new file mode 100755 index 0000000..7916d58 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXResources.m @@ -0,0 +1,167 @@ +// +// FLEXResources.m +// FLEX +// +// Created by Ryan Olson on 6/8/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXResources.h" + +static const u_int8_t FLEXCloseIcon[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3b, 0xd6, 0x95, 0x4a, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x00, 0xb8, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x9d, 0x92, 0xb1, 0x0d, 0x02, 0x31, 0x10, 0x04, 0x0d, 0x1f, 0x50, 0x01, 0x0d, 0x90, 0x53, 0xdb, 0x8b, 0x2a, 0x48, 0x48, 0x09, 0x49, 0xc8, 0x89, 0xc8, 0xe9, 0xe3, 0x0b, 0xa0, 0x0e, 0xd8, 0xb1, 0x6c, 0xc4, 0x9f, 0xd6, 0x7e, 0xc4, 0x49, 0x2b, 0xdb, 0x77, 0xb7, 0x7b, 0x6b, 0xcb, 0x43, 0x4a, 0xe9, 0x20, 0xdc, 0x84, 0xad, 0xf0, 0x10, 0x7a, 0xb1, 0x52, 0xf1, 0x28, 0x5c, 0x85, 0x17, 0x8d, 0xcf, 0xb2, 0xe1, 0x70, 0x11, 0x68, 0x70, 0x41, 0x9e, 0x3a, 0x7d, 0x00, 0x5e, 0x56, 0xaa, 0x89, 0x96, 0x40, 0x24, 0xd2, 0x87, 0x83, 0x3c, 0xe9, 0x5b, 0x31, 0x0a, 0x38, 0xe2, 0xcc, 0x61, 0xab, 0x61, 0x2d, 0xf1, 0x9e, 0x30, 0xc3, 0x73, 0x38, 0x81, 0x49, 0x95, 0xa5, 0x2b, 0x15, 0xba, 0xbf, 0x42, 0x25, 0xcf, 0xac, 0x7e, 0x18, 0x61, 0x83, 0xd5, 0x38, 0x91, 0x33, 0xf9, 0x6e, 0x38, 0xeb, 0x3f, 0x4d, 0x76, 0xc4, 0xe8, 0xc0, 0x5a, 0x77, 0x44, 0x1a, 0x17, 0x5f, 0xbb, 0x45, 0x24, 0x4f, 0x74, 0xeb, 0xfc, 0x94, 0x7a, 0x2f, 0x56, 0x67, 0xcd, 0x09, 0xe4, 0x1f, 0xf6, 0xf7, 0xdf, 0x1e, 0xca, 0xd4, 0xbd, 0xd6, 0xb3, 0x30, 0x96, 0xb3, 0x16, 0x1b, 0x77, 0x65, 0x37, 0xc2, 0x4e, 0x38, 0xbd, 0x01, 0xa7, 0x78, 0x6a, 0x4b, 0x16, 0xe1, 0xee, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXCloseIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x30, 0xae, 0xa2, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x01, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x48, 0x0d, 0xc5, 0x97, 0x6b, 0x0e, 0x02, 0x21, 0x0c, 0x84, 0x89, 0x3f, 0xf4, 0xe8, 0x7b, 0x23, 0xe3, 0x8d, 0x38, 0x86, 0x32, 0xc4, 0x6e, 0xd8, 0x86, 0x47, 0x3b, 0x25, 0xd9, 0x4d, 0x2a, 0xb0, 0xb6, 0xf3, 0xb5, 0xd0, 0x18, 0x4c, 0x29, 0xa5, 0x67, 0xb1, 0xa3, 0x58, 0xfe, 0x1b, 0xe6, 0x78, 0xb7, 0xeb, 0x19, 0xea, 0x03, 0xf4, 0x55, 0xf6, 0x2e, 0xeb, 0xd7, 0x06, 0x32, 0x34, 0xa0, 0xa5, 0xf5, 0xc1, 0xac, 0x95, 0xea, 0x2f, 0xb0, 0x8e, 0xc2, 0x47, 0x50, 0x68, 0xe7, 0x19, 0x38, 0x02, 0x9f, 0x41, 0x4f, 0x30, 0xca, 0xc6, 0x62, 0x64, 0xde, 0xca, 0x57, 0x50, 0x70, 0xc0, 0xac, 0x8d, 0xd4, 0x3b, 0x87, 0x36, 0x11, 0x2b, 0xdc, 0x02, 0x85, 0xd6, 0xd9, 0xbc, 0xd6, 0x00, 0xf8, 0x8d, 0x1e, 0x5a, 0x83, 0x0e, 0x2c, 0x99, 0x44, 0x62, 0x6b, 0x21, 0x8c, 0x00, 0x13, 0xd3, 0xdd, 0x35, 0x8f, 0x90, 0xc7, 0xb7, 0x0b, 0xd3, 0x2f, 0x2d, 0x82, 0x9f, 0x12, 0x04, 0x6b, 0x9b, 0x50, 0xcf, 0xad, 0x4d, 0x79, 0xe1, 0x5b, 0xe0, 0x1a, 0xd4, 0xae, 0x29, 0xa8, 0x64, 0xc0, 0xc2, 0x43, 0x50, 0x16, 0xbe, 0x05, 0xda, 0xc2, 0x57, 0xe7, 0x89, 0x6d, 0x86, 0x0f, 0x76, 0x69, 0xf9, 0x3c, 0x96, 0x1e, 0x37, 0x3a, 0x78, 0xcf, 0x79, 0xcb, 0x56, 0x7b, 0xa1, 0xd2, 0xd5, 0x21, 0x38, 0x0b, 0x0d, 0xc1, 0x2d, 0xd0, 0xed, 0x3f, 0x20, 0x16, 0xa8, 0x6c, 0xa5, 0xc7, 0x77, 0xda, 0xa6, 0x8c, 0x10, 0x13, 0x73, 0x49, 0x22, 0x22, 0x40, 0xc7, 0xd2, 0x81, 0x4d, 0xea, 0x6e, 0x0d, 0x5c, 0x43, 0x70, 0x66, 0xd2, 0x8d, 0xbd, 0x51, 0xce, 0xb4, 0xe1, 0x74, 0xa7, 0x56, 0x78, 0xbd, 0xfa, 0x1c, 0x9b, 0xa0, 0x92, 0x89, 0x05, 0x0e, 0xe6, 0xf0, 0x5e, 0x8d, 0xca, 0xad, 0x95, 0x0a, 0x54, 0xc6, 0x15, 0x3c, 0xc3, 0x11, 0x1f, 0x91, 0xed, 0x15, 0x98, 0x1e, 0x67, 0xf0, 0x0a, 0x3e, 0x3a, 0x60, 0xb6, 0x52, 0x2b, 0x1c, 0xcc, 0x7b, 0xfe, 0xb4, 0xfd, 0x00, 0xb3, 0x4a, 0x9f, 0x54, 0x63, 0x5e, 0xe3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXDragHandle[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x26, 0x08, 0x06, 0x00, 0x00, 0x00, 0xfd, 0x5c, 0x0a, 0xf0, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9e, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x38, 0x32, 0x38, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x36, 0x36, 0x38, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x8a, 0x6f, 0x99, 0x54, 0x00, 0x00, 0x00, 0x4b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0x63, 0x60, 0x60, 0x60, 0xd8, 0x0a, 0xc4, 0xff, 0x09, 0xe0, 0xad, 0x4c, 0x40, 0x05, 0xc4, 0x00, 0x90, 0x41, 0x34, 0x00, 0xa3, 0x6e, 0xa4, 0x4e, 0xa0, 0x8e, 0x86, 0xe3, 0x68, 0x38, 0x22, 0xe7, 0xf5, 0x81, 0xce, 0xd7, 0x9b, 0x80, 0xd1, 0xf1, 0x97, 0x00, 0xde, 0xc4, 0x02, 0x54, 0xc0, 0x0a, 0xc4, 0x84, 0xca, 0x20, 0x56, 0x46, 0xa0, 0x22, 0x10, 0x20, 0xa4, 0xf0, 0x1f, 0x44, 0x19, 0x91, 0xe4, 0xc8, 0x73, 0x23, 0x00, 0x28, 0x34, 0x66, 0xcc, 0x96, 0x10, 0xe2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXDragHandle2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x6d, 0x54, 0x97, 0x97, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9e, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x38, 0x32, 0x38, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x36, 0x36, 0x38, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x8a, 0x6f, 0x99, 0x54, 0x00, 0x00, 0x00, 0x7c, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0xd5, 0xc1, 0x09, 0xc0, 0x30, 0x0c, 0x43, 0x51, 0xd3, 0xed, 0xba, 0xff, 0x08, 0x19, 0xa4, 0x8d, 0x0f, 0xe9, 0x5d, 0x8d, 0x74, 0xca, 0x0f, 0xf8, 0x68, 0x61, 0x93, 0x07, 0xae, 0xaa, 0xba, 0x67, 0x8d, 0x59, 0xcf, 0x66, 0x75, 0x46, 0x67, 0x59, 0xc2, 0xd6, 0x30, 0xe3, 0xea, 0x44, 0xf7, 0xb3, 0xaf, 0xec, 0x1e, 0xf0, 0xc4, 0x3c, 0xfb, 0xa7, 0x38, 0x50, 0xe3, 0xf0, 0x38, 0x8a, 0x38, 0xfc, 0x7d, 0x0a, 0xbe, 0x13, 0x70, 0x1c, 0x9a, 0xc0, 0xc2, 0x38, 0xc4, 0x61, 0x80, 0x95, 0x1c, 0x89, 0x43, 0x1c, 0xca, 0x68, 0x02, 0x0d, 0x38, 0xc4, 0x61, 0x80, 0x95, 0x1c, 0x89, 0x43, 0x1c, 0xca, 0x68, 0x02, 0x0d, 0x38, 0xc4, 0x61, 0x80, 0x95, 0x1c, 0x89, 0x43, 0x1c, 0xca, 0x68, 0x02, 0x0d, 0x38, 0xdc, 0x73, 0xf8, 0x02, 0x86, 0x61, 0x32, 0xdb, 0x80, 0xa1, 0x94, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXGlobeIcon[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x08, 0x06, 0x00, 0x00, 0x00, 0x56, 0xce, 0x8e, 0x57, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x01, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0xad, 0x94, 0x3f, 0x4a, 0x03, 0x41, 0x14, 0x87, 0x93, 0xb4, 0x42, 0x7a, 0x2d, 0x2c, 0xed, 0x85, 0x14, 0x16, 0x41, 0x42, 0x4e, 0x10, 0xb0, 0x13, 0x3c, 0x88, 0x20, 0xa9, 0xbc, 0x82, 0x60, 0x95, 0x5a, 0x2b, 0x0b, 0x6f, 0x90, 0x52, 0x4c, 0xbc, 0x41, 0x0a, 0x0b, 0x15, 0x0b, 0x0f, 0x10, 0x02, 0xf1, 0xfb, 0x96, 0x79, 0xc3, 0xc4, 0x6c, 0xd0, 0x48, 0x7e, 0xf0, 0xed, 0xbe, 0x79, 0xff, 0xf6, 0xcd, 0x6c, 0x36, 0x8d, 0x46, 0xbd, 0xba, 0xb8, 0x87, 0x30, 0x85, 0x79, 0x42, 0x5b, 0x9f, 0xb1, 0x5f, 0xd5, 0x26, 0x63, 0x04, 0x33, 0x78, 0x80, 0x77, 0xb8, 0x80, 0x65, 0xb2, 0xf5, 0x19, 0x33, 0xc7, 0xdc, 0x5a, 0x9d, 0xe0, 0x7d, 0x85, 0x1b, 0x38, 0x82, 0x4f, 0x38, 0x06, 0x65, 0x23, 0x6d, 0x7d, 0xc6, 0xcc, 0x31, 0xd7, 0x9a, 0x15, 0xd9, 0xdd, 0xc0, 0x20, 0x79, 0x2f, 0xb9, 0x9b, 0x1c, 0xb2, 0x91, 0xd2, 0x67, 0x4c, 0x99, 0x6b, 0xcd, 0xca, 0x64, 0x8e, 0x5a, 0x16, 0xbe, 0xb0, 0x3e, 0x85, 0x50, 0x34, 0xd2, 0x67, 0x2c, 0x64, 0x8d, 0xb5, 0x95, 0x3c, 0xbc, 0x19, 0x5c, 0x83, 0x05, 0xdb, 0xf2, 0x45, 0x4d, 0xb7, 0xc5, 0xa5, 0x0f, 0x77, 0x70, 0x05, 0x4d, 0xe8, 0xc1, 0x38, 0xd9, 0xae, 0x45, 0x85, 0x6d, 0xac, 0x57, 0xac, 0x6f, 0xb1, 0xfb, 0x2d, 0x2e, 0x1d, 0x78, 0x86, 0xd0, 0x01, 0xc6, 0x5b, 0x2c, 0x6a, 0xee, 0xbe, 0x49, 0x73, 0x42, 0xd6, 0x76, 0x36, 0x35, 0x32, 0x79, 0x93, 0x7c, 0x48, 0xd9, 0x68, 0xc2, 0xda, 0x61, 0xaa, 0xa7, 0x6f, 0x7b, 0x2e, 0x6b, 0xf9, 0x4e, 0xe4, 0x68, 0x67, 0x10, 0x67, 0x70, 0x8e, 0x7d, 0x5f, 0xac, 0x7f, 0x9e, 0x91, 0x31, 0x73, 0x22, 0xdf, 0xda, 0xc7, 0x68, 0x54, 0x8d, 0x86, 0x43, 0x39, 0xfa, 0x7e, 0x65, 0xd5, 0x5f, 0x8c, 0x95, 0x67, 0x98, 0xcf, 0x38, 0x5e, 0xff, 0x5e, 0xaa, 0x3b, 0xe4, 0xfe, 0x01, 0x3e, 0x24, 0xe4, 0x56, 0x94, 0x3e, 0x63, 0xe6, 0x28, 0x6b, 0xfc, 0xe9, 0xe4, 0xef, 0x6f, 0xc4, 0xe2, 0x09, 0xd6, 0xf6, 0xfe, 0x07, 0xdf, 0x94, 0x9c, 0xac, 0x9d, 0x7d, 0x22, 0x76, 0xdc, 0xc9, 0x47, 0x1b, 0xa3, 0x39, 0x99, 0xdb, 0x74, 0xdf, 0xff, 0xfe, 0x1b, 0x89, 0x66, 0xde, 0x3d, 0xbc, 0x21, 0xb8, 0xff, 0x39, 0x2c, 0x92, 0xad, 0x2f, 0x1f, 0x2c, 0x76, 0xd6, 0x37, 0xcc, 0x0f, 0x82, 0x53, 0x11, 0x25, 0x5b, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXGlobeIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x08, 0x06, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x98, 0x98, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x03, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xcd, 0x98, 0x3d, 0x6b, 0x54, 0x51, 0x10, 0x86, 0x8d, 0xb1, 0xf3, 0x83, 0xac, 0x60, 0x61, 0x20, 0x58, 0x88, 0x1f, 0xa8, 0x9d, 0x85, 0x85, 0x58, 0x2e, 0x04, 0x4c, 0x61, 0x6a, 0x05, 0x7f, 0x84, 0x56, 0x0a, 0xd9, 0x3f, 0xa0, 0x90, 0xfc, 0x80, 0xfc, 0x00, 0x3b, 0x85, 0xa4, 0x31, 0x92, 0x46, 0x04, 0x2d, 0x6c, 0x44, 0xc5, 0x0f, 0x62, 0x96, 0x14, 0xa6, 0x52, 0x51, 0x23, 0x04, 0x62, 0x8c, 0xef, 0xb3, 0x39, 0x6f, 0x98, 0x7b, 0x72, 0x37, 0x7b, 0x57, 0x76, 0x13, 0x07, 0xde, 0xcc, 0x9c, 0x99, 0x79, 0x67, 0x86, 0x7b, 0xef, 0x39, 0x7b, 0x6f, 0x06, 0xf6, 0x75, 0x2f, 0x35, 0x51, 0xae, 0x0a, 0x75, 0xe1, 0x82, 0x70, 0x5a, 0x38, 0x28, 0x20, 0xbf, 0x84, 0x0f, 0xc2, 0x6b, 0x61, 0x4e, 0x98, 0x15, 0xbe, 0x09, 0x7d, 0x91, 0x71, 0x55, 0x9d, 0x17, 0xd6, 0x84, 0x8d, 0x8a, 0x20, 0x17, 0x0e, 0xdc, 0x9e, 0xc9, 0x65, 0x55, 0x7a, 0x26, 0x54, 0x1d, 0xa2, 0x5d, 0x1e, 0x35, 0xa8, 0xf5, 0xcf, 0x32, 0x28, 0xe6, 0xa4, 0x90, 0x37, 0xf8, 0x93, 0x7c, 0xeb, 0xd2, 0x13, 0xc2, 0xb9, 0x90, 0x83, 0x8d, 0x8f, 0x18, 0x3c, 0xe7, 0xc6, 0x1a, 0xd4, 0xa4, 0x76, 0x57, 0x32, 0xa4, 0xec, 0xc7, 0x42, 0x2c, 0xb4, 0xaa, 0xf5, 0x94, 0xd0, 0x4c, 0xfe, 0xdb, 0xd2, 0x16, 0xe7, 0x79, 0x4d, 0x0c, 0x5f, 0x53, 0x80, 0x03, 0xd7, 0x39, 0x68, 0x6a, 0xd3, 0xa3, 0x92, 0x90, 0xf8, 0x56, 0x88, 0x05, 0x1e, 0x6a, 0x7d, 0x42, 0xb8, 0x95, 0xfc, 0xaf, 0xa4, 0x0f, 0x08, 0x16, 0xe7, 0x7a, 0x4d, 0x8c, 0x1c, 0xfc, 0x70, 0xe0, 0x52, 0xc3, 0x79, 0x68, 0x7a, 0x74, 0x1c, 0x8a, 0x4b, 0x19, 0xaf, 0x0c, 0x97, 0xbc, 0x21, 0x0c, 0x24, 0x2c, 0x48, 0x53, 0x8c, 0x5d, 0x16, 0xc5, 0x8d, 0xa2, 0x8f, 0x1c, 0xfc, 0x70, 0xcc, 0xa7, 0x56, 0xbc, 0x8d, 0xf4, 0xda, 0xf1, 0xf6, 0x4d, 0x2a, 0xc1, 0xc5, 0x21, 0x5e, 0x17, 0x2c, 0xa3, 0x32, 0x88, 0x2d, 0x0a, 0xfb, 0xed, 0x4c, 0xda, 0x9c, 0xe8, 0x26, 0x87, 0x5c, 0x62, 0x70, 0x2d, 0x37, 0x64, 0xc4, 0xa1, 0xe8, 0x59, 0x2a, 0xec, 0x00, 0x17, 0x46, 0x37, 0xb2, 0xac, 0xe9, 0x14, 0xbf, 0x93, 0xf9, 0x59, 0x9a, 0x97, 0x87, 0xee, 0xa6, 0x18, 0xdc, 0x28, 0xd4, 0x36, 0x07, 0x5d, 0xba, 0xfb, 0x7a, 0xb1, 0xb5, 0x63, 0x93, 0x6e, 0x6c, 0x7a, 0x17, 0x84, 0x83, 0xcb, 0x05, 0xd6, 0x83, 0x6d, 0x5f, 0xbf, 0x74, 0xec, 0x55, 0x38, 0x3c, 0xe7, 0xc3, 0x10, 0xf7, 0x0b, 0xa3, 0x6e, 0x2e, 0x6e, 0xa6, 0xf8, 0x83, 0x92, 0x18, 0x2e, 0x0f, 0x5c, 0x16, 0x86, 0x43, 0x9c, 0x1a, 0xb9, 0xd0, 0xcb, 0x5c, 0x66, 0x68, 0x3d, 0x9c, 0x35, 0xe9, 0x2b, 0x2c, 0x24, 0x04, 0xef, 0xb5, 0xac, 0xe2, 0x9f, 0x33, 0x69, 0xc9, 0x56, 0xed, 0x56, 0xcc, 0x71, 0x8d, 0xc8, 0xa7, 0x17, 0x3d, 0x11, 0x66, 0xa8, 0xb1, 0x13, 0xc6, 0x04, 0x9f, 0x29, 0xcf, 0x65, 0x2f, 0x0b, 0xb9, 0x9c, 0x4d, 0x8e, 0x77, 0x79, 0xa0, 0xc2, 0xda, 0x1c, 0xd7, 0x88, 0x14, 0x7a, 0xbd, 0x48, 0x0e, 0x66, 0x18, 0x63, 0xa0, 0x7a, 0x72, 0xa0, 0x1e, 0x05, 0x3b, 0x9a, 0x27, 0xd3, 0xe2, 0x63, 0x74, 0x56, 0xb4, 0xcd, 0x71, 0x8d, 0x9c, 0xc6, 0x81, 0x69, 0xa9, 0x33, 0xd0, 0x88, 0x57, 0xd2, 0x2f, 0x83, 0x1d, 0xcd, 0x23, 0x69, 0xf1, 0x35, 0x3a, 0x2b, 0xda, 0xe6, 0xb8, 0x46, 0x4e, 0x8b, 0x3d, 0x47, 0x18, 0x68, 0x38, 0x64, 0x7c, 0x0e, 0x76, 0x34, 0x0f, 0xa7, 0xc5, 0xcf, 0xe8, 0xac, 0x68, 0xaf, 0xa4, 0x3c, 0xd7, 0xc8, 0x69, 0xb1, 0xe7, 0x30, 0x47, 0x3a, 0x4d, 0x0e, 0xe5, 0x59, 0x7b, 0xb4, 0x5e, 0xe1, 0x0a, 0xf9, 0x29, 0xdf, 0xa3, 0x19, 0x0a, 0x6d, 0x37, 0x18, 0x28, 0xee, 0xaa, 0xf3, 0x5a, 0xfb, 0x87, 0x30, 0xea, 0x2f, 0x89, 0x76, 0xac, 0x4d, 0x3c, 0x85, 0x4b, 0xb9, 0x70, 0x10, 0x6a, 0xc4, 0x9a, 0xb6, 0xe9, 0x69, 0x59, 0x66, 0xa0, 0xc2, 0x3d, 0x74, 0x24, 0xd3, 0x7e, 0x76, 0xfe, 0xe5, 0xd6, 0xfa, 0xd9, 0x71, 0x8d, 0xac, 0x74, 0xf1, 0x19, 0x66, 0xa0, 0xa5, 0x90, 0x71, 0x31, 0xd8, 0xd1, 0xfc, 0x91, 0x16, 0x47, 0xa3, 0xb3, 0xa2, 0xcd, 0xc1, 0x8b, 0x7c, 0xdf, 0x54, 0xdb, 0xfe, 0xc6, 0x9e, 0x4b, 0x0c, 0xf4, 0x24, 0xa4, 0x5c, 0x0b, 0x76, 0x34, 0x17, 0xd2, 0xe2, 0x54, 0x74, 0x56, 0xb4, 0xcd, 0xf9, 0xd4, 0x26, 0x3f, 0xf6, 0x9c, 0x63, 0xa0, 0x19, 0xe1, 0x77, 0x4a, 0xbe, 0x24, 0x7d, 0x3c, 0xd9, 0x51, 0xed, 0x74, 0xda, 0xc6, 0xbc, 0x32, 0xdb, 0x27, 0xb4, 0x6b, 0xc4, 0x1c, 0x7a, 0xd1, 0x13, 0x61, 0x86, 0x59, 0x06, 0xe2, 0xbb, 0xe9, 0xa9, 0x80, 0xf0, 0xa0, 0xc5, 0x77, 0xe5, 0x96, 0x53, 0x7f, 0xde, 0x27, 0x83, 0x97, 0xf8, 0x6e, 0xc5, 0x1c, 0xd7, 0x88, 0x7c, 0x7a, 0xd1, 0x13, 0x61, 0x86, 0xad, 0x6f, 0xb8, 0x71, 0x2d, 0xfc, 0xab, 0xbb, 0x1e, 0x6c, 0xfb, 0xfa, 0xa5, 0x63, 0x2f, 0x66, 0x28, 0x08, 0x2f, 0x49, 0xfd, 0x6a, 0xdc, 0xa9, 0x2e, 0xbd, 0xb7, 0x09, 0xaf, 0x91, 0x91, 0xd8, 0xc8, 0x32, 0xa6, 0x53, 0x7c, 0xd7, 0x5e, 0x61, 0xe9, 0xcf, 0x0b, 0xb7, 0x87, 0xe2, 0x45, 0x9c, 0x17, 0x72, 0xcb, 0xa8, 0x0c, 0x62, 0x8b, 0x02, 0xcf, 0x5e, 0x14, 0x73, 0xa2, 0x8f, 0x1c, 0x72, 0x89, 0xc1, 0xb5, 0x50, 0x93, 0xda, 0xe6, 0xd0, 0xb3, 0xad, 0x0c, 0x2a, 0xc2, 0xa7, 0x89, 0x93, 0x21, 0x36, 0x04, 0x9f, 0xaa, 0x6c, 0x7f, 0x62, 0xbb, 0xf6, 0x19, 0xa4, 0x5e, 0xad, 0x8f, 0xb7, 0xff, 0xe6, 0x43, 0x91, 0x81, 0x90, 0x21, 0x21, 0x5e, 0x29, 0xae, 0xca, 0xaa, 0x30, 0x25, 0x34, 0x05, 0xd6, 0xf1, 0x78, 0x60, 0x0d, 0x2c, 0xc4, 0x58, 0x37, 0x05, 0x38, 0x70, 0x9d, 0x83, 0xa6, 0x36, 0x3d, 0xba, 0x12, 0x6e, 0x5f, 0x7c, 0xa6, 0x5c, 0xd0, 0xf7, 0x9f, 0x2d, 0x3b, 0x21, 0xec, 0xca, 0x3f, 0x1b, 0xe2, 0xe4, 0xec, 0xbe, 0x5e, 0x1c, 0x09, 0xd4, 0xa0, 0x56, 0xcf, 0x84, 0x83, 0x6b, 0x5e, 0x58, 0x13, 0x7c, 0xb5, 0x3a, 0x69, 0x72, 0xe1, 0x6c, 0x3b, 0xf4, 0xe4, 0x2b, 0x15, 0x1f, 0xdb, 0xa5, 0xc1, 0x36, 0xce, 0x9a, 0xfc, 0x7c, 0xa9, 0xd4, 0x05, 0xde, 0x65, 0xca, 0xfe, 0xa5, 0xf7, 0x46, 0xfe, 0x39, 0x61, 0x46, 0xd8, 0xfa, 0x39, 0x90, 0xdd, 0x51, 0xfe, 0x02, 0x89, 0x7c, 0xcc, 0xd6, 0x15, 0x10, 0x0a, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXHierarchyIndentPattern[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xf9, 0x3c, 0x0f, 0xcd, 0x00, 0x00, 0x0a, 0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54, 0x53, 0xd9, 0x16, 0x87, 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20, 0x25, 0xf4, 0x1a, 0x7a, 0x09, 0x20, 0xd2, 0x3b, 0x48, 0x15, 0x04, 0x51, 0x89, 0x49, 0x80, 0x50, 0x02, 0x86, 0x84, 0x26, 0x76, 0x44, 0x05, 0x46, 0x14, 0x11, 0x29, 0x56, 0x64, 0x54, 0xc0, 0x01, 0x47, 0x87, 0x22, 0x63, 0x45, 0x14, 0x0b, 0x83, 0x82, 0x62, 0xd7, 0x09, 0xf2, 0x10, 0x50, 0xc6, 0xc1, 0x51, 0x44, 0x45, 0xe5, 0xdd, 0x8c, 0x6b, 0x09, 0xef, 0xad, 0x35, 0xf3, 0xde, 0x9a, 0xfd, 0xc7, 0x59, 0xdf, 0xd9, 0xe7, 0xb7, 0xd7, 0xd9, 0x67, 0xef, 0x7d, 0xd7, 0xba, 0x00, 0x50, 0xfc, 0x82, 0x04, 0xc2, 0x74, 0x58, 0x01, 0x80, 0x34, 0xa1, 0x58, 0x14, 0xee, 0xeb, 0xc1, 0x5c, 0x12, 0x13, 0xcb, 0xc4, 0xf7, 0x02, 0x18, 0x10, 0x01, 0x0e, 0x58, 0x01, 0xc0, 0xe1, 0x66, 0x66, 0x04, 0x47, 0xf8, 0x44, 0x02, 0xd4, 0xfc, 0xbd, 0x3d, 0x99, 0x99, 0xa8, 0x48, 0xc6, 0xb3, 0xf6, 0xee, 0x2e, 0x80, 0x64, 0xbb, 0xdb, 0x2c, 0xbf, 0x50, 0x26, 0x73, 0xd6, 0xff, 0x7f, 0x91, 0x22, 0x37, 0x43, 0x24, 0x06, 0x00, 0x0a, 0x45, 0xd5, 0x36, 0x3c, 0x7e, 0x26, 0x17, 0xe5, 0x02, 0x94, 0x53, 0xb3, 0xc5, 0x19, 0x32, 0xff, 0x04, 0xca, 0xf4, 0x95, 0x29, 0x32, 0x86, 0x31, 0x32, 0x16, 0xa1, 0x09, 0xa2, 0xac, 0x22, 0xe3, 0xc4, 0xaf, 0x6c, 0xf6, 0xa7, 0xe6, 0x2b, 0xbb, 0xc9, 0x98, 0x97, 0x26, 0xe4, 0xa1, 0x1a, 0x59, 0xce, 0x19, 0xbc, 0x34, 0x9e, 0x8c, 0xbb, 0x50, 0xde, 0x9a, 0x25, 0xe1, 0xa3, 0x8c, 0x04, 0xa1, 0x5c, 0x98, 0x25, 0xe0, 0x67, 0xa3, 0x7c, 0x07, 0x65, 0xbd, 0x54, 0x49, 0x9a, 0x00, 0xe5, 0xf7, 0x28, 0xd3, 0xd3, 0xf8, 0x9c, 0x4c, 0x00, 0x30, 0x14, 0x99, 0x5f, 0xcc, 0xe7, 0x26, 0xa1, 0x6c, 0x89, 0x32, 0x45, 0x14, 0x19, 0xee, 0x89, 0xf2, 0x02, 0x00, 0x08, 0x94, 0xc4, 0x39, 0xbc, 0x72, 0x0e, 0x8b, 0xf9, 0x39, 0x68, 0x9e, 0x00, 0x78, 0xa6, 0x67, 0xe4, 0x8a, 0x04, 0x89, 0x49, 0x62, 0xa6, 0x11, 0xd7, 0x98, 0x69, 0xe5, 0xe8, 0xc8, 0x66, 0xfa, 0xf1, 0xb3, 0x53, 0xf9, 0x62, 0x31, 0x2b, 0x94, 0xc3, 0x4d, 0xe1, 0x88, 0x78, 0x4c, 0xcf, 0xf4, 0xb4, 0x0c, 0x8e, 0x30, 0x17, 0x80, 0xaf, 0x6f, 0x96, 0x45, 0x01, 0x25, 0x59, 0x6d, 0x99, 0x68, 0x91, 0xed, 0xad, 0x1c, 0xed, 0xed, 0x59, 0xd6, 0xe6, 0x68, 0xf9, 0xbf, 0xd9, 0xdf, 0x1e, 0x7e, 0x53, 0xfd, 0x3d, 0xc8, 0x7a, 0xfb, 0x55, 0xf1, 0x26, 0xec, 0xcf, 0x9e, 0x41, 0x8c, 0x9e, 0x59, 0xdf, 0x6c, 0xec, 0xac, 0x2f, 0xbd, 0x16, 0x00, 0xf6, 0x24, 0x5a, 0x9b, 0x1d, 0xb3, 0xbe, 0x95, 0x55, 0x00, 0xb4, 0x6d, 0x06, 0x40, 0xe5, 0xe1, 0xac, 0x4f, 0xef, 0x20, 0x00, 0xf2, 0x05, 0x00, 0xb4, 0xde, 0x9c, 0xf3, 0x1e, 0x86, 0x6c, 0x5e, 0x92, 0xc4, 0xe2, 0x0c, 0x27, 0x0b, 0x8b, 0xec, 0xec, 0x6c, 0x73, 0x01, 0x9f, 0x6b, 0x2e, 0x2b, 0xe8, 0x37, 0xfb, 0x9f, 0x82, 0x6f, 0xca, 0xbf, 0x86, 0x39, 0xf7, 0x99, 0xcb, 0xee, 0xfb, 0x56, 0x3b, 0xa6, 0x17, 0x3f, 0x81, 0x23, 0x49, 0x15, 0x33, 0x65, 0x45, 0xe5, 0xa6, 0xa7, 0xa6, 0x4b, 0x44, 0xcc, 0xcc, 0x0c, 0x0e, 0x97, 0xcf, 0x64, 0xfd, 0xf7, 0x10, 0xff, 0xe3, 0xc0, 0x39, 0x69, 0xcd, 0xc9, 0xc3, 0x2c, 0x9c, 0x9f, 0xc0, 0x17, 0xf1, 0x85, 0xe8, 0x55, 0x51, 0xe8, 0x94, 0x09, 0x84, 0x89, 0x68, 0xbb, 0x85, 0x3c, 0x81, 0x58, 0x90, 0x2e, 0x64, 0x0a, 0x84, 0x7f, 0xd5, 0xe1, 0x7f, 0x18, 0x36, 0x27, 0x07, 0x19, 0x7e, 0x9d, 0x6b, 0x14, 0x68, 0x75, 0x5f, 0x00, 0x7d, 0x85, 0x39, 0x50, 0xb8, 0x49, 0x07, 0xc8, 0x6f, 0x3d, 0x00, 0x43, 0x23, 0x03, 0x24, 0x6e, 0x3f, 0x7a, 0x02, 0x7d, 0xeb, 0x5b, 0x10, 0x31, 0x0a, 0xc8, 0xbe, 0xbc, 0x68, 0xad, 0x91, 0xaf, 0x73, 0x8f, 0x32, 0x7a, 0xfe, 0xe7, 0xfa, 0x1f, 0x0b, 0x5c, 0x8a, 0x6e, 0xe1, 0x4c, 0x41, 0x22, 0x53, 0xe6, 0xf6, 0x0c, 0x8f, 0x64, 0x72, 0x25, 0xa2, 0x2c, 0x19, 0xa3, 0xdf, 0x84, 0x6c, 0xc1, 0x02, 0x12, 0x90, 0x07, 0x74, 0xa0, 0x0a, 0x34, 0x81, 0x2e, 0x30, 0x02, 0x2c, 0x60, 0x0d, 0x1c, 0x80, 0x33, 0x70, 0x03, 0xde, 0x20, 0x00, 0x84, 0x80, 0x48, 0x10, 0x03, 0x96, 0x03, 0x2e, 0x48, 0x02, 0x69, 0x40, 0x04, 0xb2, 0x41, 0x3e, 0xd8, 0x00, 0x0a, 0x41, 0x31, 0xd8, 0x01, 0x76, 0x83, 0x6a, 0x70, 0x00, 0xd4, 0x81, 0x7a, 0xd0, 0x04, 0x4e, 0x82, 0x36, 0x70, 0x06, 0x5c, 0x04, 0x57, 0xc0, 0x0d, 0x70, 0x0b, 0x0c, 0x80, 0x47, 0x40, 0x0a, 0x86, 0xc1, 0x4b, 0x30, 0x01, 0xde, 0x81, 0x69, 0x08, 0x82, 0xf0, 0x10, 0x15, 0xa2, 0x41, 0xaa, 0x90, 0x16, 0xa4, 0x0f, 0x99, 0x42, 0xd6, 0x10, 0x1b, 0x5a, 0x08, 0x79, 0x43, 0x41, 0x50, 0x38, 0x14, 0x03, 0xc5, 0x43, 0x89, 0x90, 0x10, 0x92, 0x40, 0xf9, 0xd0, 0x26, 0xa8, 0x18, 0x2a, 0x83, 0xaa, 0xa1, 0x43, 0x50, 0x3d, 0xf4, 0x23, 0x74, 0x1a, 0xba, 0x08, 0x5d, 0x83, 0xfa, 0xa0, 0x07, 0xd0, 0x20, 0x34, 0x06, 0xfd, 0x01, 0x7d, 0x84, 0x11, 0x98, 0x02, 0xd3, 0x61, 0x0d, 0xd8, 0x00, 0xb6, 0x80, 0xd9, 0xb0, 0x3b, 0x1c, 0x08, 0x47, 0xc2, 0xcb, 0xe0, 0x44, 0x78, 0x15, 0x9c, 0x07, 0x17, 0xc0, 0xdb, 0xe1, 0x4a, 0xb8, 0x16, 0x3e, 0x0e, 0xb7, 0xc2, 0x17, 0xe1, 0x1b, 0xf0, 0x00, 0x2c, 0x85, 0x5f, 0xc2, 0x93, 0x08, 0x40, 0xc8, 0x08, 0x03, 0xd1, 0x46, 0x58, 0x08, 0x1b, 0xf1, 0x44, 0x42, 0x90, 0x58, 0x24, 0x01, 0x11, 0x21, 0x6b, 0x91, 0x22, 0xa4, 0x02, 0xa9, 0x45, 0x9a, 0x90, 0x0e, 0xa4, 0x1b, 0xb9, 0x8d, 0x48, 0x91, 0x71, 0xe4, 0x03, 0x06, 0x87, 0xa1, 0x61, 0x98, 0x18, 0x16, 0xc6, 0x19, 0xe3, 0x87, 0x59, 0x8c, 0xe1, 0x62, 0x56, 0x61, 0xd6, 0x62, 0x4a, 0x30, 0xd5, 0x98, 0x63, 0x98, 0x56, 0x4c, 0x17, 0xe6, 0x36, 0x66, 0x10, 0x33, 0x81, 0xf9, 0x82, 0xa5, 0x62, 0xd5, 0xb1, 0xa6, 0x58, 0x27, 0xac, 0x3f, 0x76, 0x09, 0x36, 0x11, 0x9b, 0x8d, 0x2d, 0xc4, 0x56, 0x60, 0x8f, 0x60, 0x5b, 0xb0, 0x97, 0xb1, 0x03, 0xd8, 0x61, 0xec, 0x3b, 0x1c, 0x0e, 0xc7, 0xc0, 0x19, 0xe2, 0x1c, 0x70, 0x7e, 0xb8, 0x18, 0x5c, 0x32, 0x6e, 0x35, 0xae, 0x04, 0xb7, 0x0f, 0xd7, 0x8c, 0xbb, 0x80, 0xeb, 0xc3, 0x0d, 0xe1, 0x26, 0xf1, 0x78, 0xbc, 0x2a, 0xde, 0x14, 0xef, 0x82, 0x0f, 0xc1, 0x73, 0xf0, 0x62, 0x7c, 0x21, 0xbe, 0x0a, 0x7f, 0x1c, 0x7f, 0x1e, 0xdf, 0x8f, 0x1f, 0xc6, 0xbf, 0x27, 0x90, 0x09, 0x5a, 0x04, 0x6b, 0x82, 0x0f, 0x21, 0x96, 0x20, 0x24, 0x6c, 0x24, 0x54, 0x10, 0x1a, 0x08, 0xe7, 0x08, 0xfd, 0x84, 0x11, 0xc2, 0x34, 0x51, 0x81, 0xa8, 0x4f, 0x74, 0x22, 0x86, 0x10, 0x79, 0xc4, 0x5c, 0x62, 0x29, 0xb1, 0x8e, 0xd8, 0x41, 0xbc, 0x49, 0x1c, 0x26, 0x4e, 0x93, 0x14, 0x49, 0x86, 0x24, 0x17, 0x52, 0x24, 0x29, 0x99, 0xb4, 0x81, 0x54, 0x49, 0x6a, 0x22, 0x5d, 0x26, 0x3d, 0x26, 0xbd, 0x21, 0x93, 0xc9, 0x3a, 0x64, 0x47, 0x72, 0x18, 0x59, 0x40, 0x5e, 0x4f, 0xae, 0x24, 0x9f, 0x20, 0x5f, 0x25, 0x0f, 0x92, 0x3f, 0x50, 0x94, 0x28, 0x26, 0x14, 0x4f, 0x4a, 0x1c, 0x45, 0x42, 0xd9, 0x4e, 0x39, 0x4a, 0xb9, 0x40, 0x79, 0x40, 0x79, 0x43, 0xa5, 0x52, 0x0d, 0xa8, 0x6e, 0xd4, 0x58, 0xaa, 0x98, 0xba, 0x9d, 0x5a, 0x4f, 0xbd, 0x44, 0x7d, 0x4a, 0x7d, 0x2f, 0x47, 0x93, 0x33, 0x97, 0xf3, 0x97, 0xe3, 0xc9, 0xad, 0x93, 0xab, 0x91, 0x6b, 0x95, 0xeb, 0x97, 0x7b, 0x25, 0x4f, 0x94, 0xd7, 0x97, 0x77, 0x97, 0x5f, 0x2e, 0x9f, 0x27, 0x5f, 0x21, 0x7f, 0x4a, 0xfe, 0xa6, 0xfc, 0xb8, 0x02, 0x51, 0xc1, 0x40, 0xc1, 0x53, 0x81, 0xa3, 0xb0, 0x56, 0xa1, 0x46, 0xe1, 0xb4, 0xc2, 0x3d, 0x85, 0x49, 0x45, 0x9a, 0xa2, 0x95, 0x62, 0x88, 0x62, 0x9a, 0x62, 0x89, 0x62, 0x83, 0xe2, 0x35, 0xc5, 0x51, 0x25, 0xbc, 0x92, 0x81, 0x92, 0xb7, 0x12, 0x4f, 0xa9, 0x40, 0xe9, 0xb0, 0xd2, 0x25, 0xa5, 0x21, 0x1a, 0x42, 0xd3, 0xa5, 0x79, 0xd2, 0xb8, 0xb4, 0x4d, 0xb4, 0x3a, 0xda, 0x65, 0xda, 0x30, 0x1d, 0x47, 0x37, 0xa4, 0xfb, 0xd3, 0x93, 0xe9, 0xc5, 0xf4, 0x1f, 0xe8, 0xbd, 0xf4, 0x09, 0x65, 0x25, 0x65, 0x5b, 0xe5, 0x28, 0xe5, 0x1c, 0xe5, 0x1a, 0xe5, 0xb3, 0xca, 0x52, 0x06, 0xc2, 0x30, 0x60, 0xf8, 0x33, 0x52, 0x19, 0xa5, 0x8c, 0x93, 0x8c, 0xbb, 0x8c, 0x8f, 0xf3, 0x34, 0xe6, 0xb9, 0xcf, 0xe3, 0xcf, 0xdb, 0x36, 0xaf, 0x69, 0x5e, 0xff, 0xbc, 0x29, 0x95, 0xf9, 0x2a, 0x6e, 0x2a, 0x7c, 0x95, 0x22, 0x95, 0x66, 0x95, 0x01, 0x95, 0x8f, 0xaa, 0x4c, 0x55, 0x6f, 0xd5, 0x14, 0xd5, 0x9d, 0xaa, 0x6d, 0xaa, 0x4f, 0xd4, 0x30, 0x6a, 0x26, 0x6a, 0x61, 0x6a, 0xd9, 0x6a, 0xfb, 0xd5, 0x2e, 0xab, 0x8d, 0xcf, 0xa7, 0xcf, 0x77, 0x9e, 0xcf, 0x9d, 0x5f, 0x34, 0xff, 0xe4, 0xfc, 0x87, 0xea, 0xb0, 0xba, 0x89, 0x7a, 0xb8, 0xfa, 0x6a, 0xf5, 0xc3, 0xea, 0x3d, 0xea, 0x93, 0x1a, 0x9a, 0x1a, 0xbe, 0x1a, 0x19, 0x1a, 0x55, 0x1a, 0x97, 0x34, 0xc6, 0x35, 0x19, 0x9a, 0x6e, 0x9a, 0xc9, 0x9a, 0xe5, 0x9a, 0xe7, 0x34, 0xc7, 0xb4, 0x68, 0x5a, 0x0b, 0xb5, 0x04, 0x5a, 0xe5, 0x5a, 0xe7, 0xb5, 0x5e, 0x30, 0x95, 0x99, 0xee, 0xcc, 0x54, 0x66, 0x25, 0xb3, 0x8b, 0x39, 0xa1, 0xad, 0xae, 0xed, 0xa7, 0x2d, 0xd1, 0x3e, 0xa4, 0xdd, 0xab, 0x3d, 0xad, 0x63, 0xa8, 0xb3, 0x58, 0x67, 0xa3, 0x4e, 0xb3, 0xce, 0x13, 0x5d, 0x92, 0x2e, 0x5b, 0x37, 0x41, 0xb7, 0x5c, 0xb7, 0x53, 0x77, 0x42, 0x4f, 0x4b, 0x2f, 0x58, 0x2f, 0x5f, 0xaf, 0x51, 0xef, 0xa1, 0x3e, 0x51, 0x9f, 0xad, 0x9f, 0xa4, 0xbf, 0x47, 0xbf, 0x5b, 0x7f, 0xca, 0xc0, 0xd0, 0x20, 0xda, 0x60, 0x8b, 0x41, 0x9b, 0xc1, 0xa8, 0xa1, 0x8a, 0xa1, 0xbf, 0x61, 0x9e, 0x61, 0xa3, 0xe1, 0x63, 0x23, 0xaa, 0x91, 0xab, 0xd1, 0x2a, 0xa3, 0x5a, 0xa3, 0x3b, 0xc6, 0x38, 0x63, 0xb6, 0x71, 0x8a, 0xf1, 0x3e, 0xe3, 0x5b, 0x26, 0xb0, 0x89, 0x9d, 0x49, 0x92, 0x49, 0x8d, 0xc9, 0x4d, 0x53, 0xd8, 0xd4, 0xde, 0x54, 0x60, 0xba, 0xcf, 0xb4, 0xcf, 0x0c, 0x6b, 0xe6, 0x68, 0x26, 0x34, 0xab, 0x35, 0xbb, 0xc7, 0xa2, 0xb0, 0xdc, 0x59, 0x59, 0xac, 0x46, 0xd6, 0xa0, 0x39, 0xc3, 0x3c, 0xc8, 0x7c, 0xa3, 0x79, 0x9b, 0xf9, 0x2b, 0x0b, 0x3d, 0x8b, 0x58, 0x8b, 0x9d, 0x16, 0xdd, 0x16, 0x5f, 0x2c, 0xed, 0x2c, 0x53, 0x2d, 0xeb, 0x2c, 0x1f, 0x59, 0x29, 0x59, 0x05, 0x58, 0x6d, 0xb4, 0xea, 0xb0, 0xfa, 0xc3, 0xda, 0xc4, 0x9a, 0x6b, 0x5d, 0x63, 0x7d, 0xc7, 0x86, 0x6a, 0xe3, 0x63, 0xb3, 0xce, 0xa6, 0xdd, 0xe6, 0xb5, 0xad, 0xa9, 0x2d, 0xdf, 0x76, 0xbf, 0xed, 0x7d, 0x3b, 0x9a, 0x5d, 0xb0, 0xdd, 0x16, 0xbb, 0x4e, 0xbb, 0xcf, 0xf6, 0x0e, 0xf6, 0x22, 0xfb, 0x26, 0xfb, 0x31, 0x07, 0x3d, 0x87, 0x78, 0x87, 0xbd, 0x0e, 0xf7, 0xd8, 0x74, 0x76, 0x28, 0xbb, 0x84, 0x7d, 0xd5, 0x11, 0xeb, 0xe8, 0xe1, 0xb8, 0xce, 0xf1, 0x8c, 0xe3, 0x07, 0x27, 0x7b, 0x27, 0xb1, 0xd3, 0x49, 0xa7, 0xdf, 0x9d, 0x59, 0xce, 0x29, 0xce, 0x0d, 0xce, 0xa3, 0x0b, 0x0c, 0x17, 0xf0, 0x17, 0xd4, 0x2d, 0x18, 0x72, 0xd1, 0x71, 0xe1, 0xb8, 0x1c, 0x72, 0x91, 0x2e, 0x64, 0x2e, 0x8c, 0x5f, 0x78, 0x70, 0xa1, 0xd4, 0x55, 0xdb, 0x95, 0xe3, 0x5a, 0xeb, 0xfa, 0xcc, 0x4d, 0xd7, 0x8d, 0xe7, 0x76, 0xc4, 0x6d, 0xc4, 0xdd, 0xd8, 0x3d, 0xd9, 0xfd, 0xb8, 0xfb, 0x2b, 0x0f, 0x4b, 0x0f, 0x91, 0x47, 0x8b, 0xc7, 0x94, 0xa7, 0x93, 0xe7, 0x1a, 0xcf, 0x0b, 0x5e, 0x88, 0x97, 0xaf, 0x57, 0x91, 0x57, 0xaf, 0xb7, 0x92, 0xf7, 0x62, 0xef, 0x6a, 0xef, 0xa7, 0x3e, 0x3a, 0x3e, 0x89, 0x3e, 0x8d, 0x3e, 0x13, 0xbe, 0x76, 0xbe, 0xab, 0x7d, 0x2f, 0xf8, 0x61, 0xfd, 0x02, 0xfd, 0x76, 0xfa, 0xdd, 0xf3, 0xd7, 0xf0, 0xe7, 0xfa, 0xd7, 0xfb, 0x4f, 0x04, 0x38, 0x04, 0xac, 0x09, 0xe8, 0x0a, 0xa4, 0x04, 0x46, 0x04, 0x56, 0x07, 0x3e, 0x0b, 0x32, 0x09, 0x12, 0x05, 0x75, 0x04, 0xc3, 0xc1, 0x01, 0xc1, 0xbb, 0x82, 0x1f, 0x2f, 0xd2, 0x5f, 0x24, 0x5c, 0xd4, 0x16, 0x02, 0x42, 0xfc, 0x43, 0x76, 0x85, 0x3c, 0x09, 0x35, 0x0c, 0x5d, 0x15, 0xfa, 0x73, 0x18, 0x2e, 0x2c, 0x34, 0xac, 0x26, 0xec, 0x79, 0xb8, 0x55, 0x78, 0x7e, 0x78, 0x77, 0x04, 0x2d, 0x62, 0x45, 0x44, 0x43, 0xc4, 0xbb, 0x48, 0x8f, 0xc8, 0xd2, 0xc8, 0x47, 0x8b, 0x8d, 0x16, 0x4b, 0x16, 0x77, 0x46, 0xc9, 0x47, 0xc5, 0x45, 0xd5, 0x47, 0x4d, 0x45, 0x7b, 0x45, 0x97, 0x45, 0x4b, 0x97, 0x58, 0x2c, 0x59, 0xb3, 0xe4, 0x46, 0x8c, 0x5a, 0x8c, 0x20, 0xa6, 0x3d, 0x16, 0x1f, 0x1b, 0x15, 0x7b, 0x24, 0x76, 0x72, 0xa9, 0xf7, 0xd2, 0xdd, 0x4b, 0x87, 0xe3, 0xec, 0xe2, 0x0a, 0xe3, 0xee, 0x2e, 0x33, 0x5c, 0x96, 0xb3, 0xec, 0xda, 0x72, 0xb5, 0xe5, 0xa9, 0xcb, 0xcf, 0xae, 0x90, 0x5f, 0xc1, 0x59, 0x71, 0x2a, 0x1e, 0x1b, 0x1f, 0x1d, 0xdf, 0x10, 0xff, 0x89, 0x13, 0xc2, 0xa9, 0xe5, 0x4c, 0xae, 0xf4, 0x5f, 0xb9, 0x77, 0xe5, 0x04, 0xd7, 0x93, 0xbb, 0x87, 0xfb, 0x92, 0xe7, 0xc6, 0x2b, 0xe7, 0x8d, 0xf1, 0x5d, 0xf8, 0x65, 0xfc, 0x91, 0x04, 0x97, 0x84, 0xb2, 0x84, 0xd1, 0x44, 0x97, 0xc4, 0x5d, 0x89, 0x63, 0x49, 0xae, 0x49, 0x15, 0x49, 0xe3, 0x02, 0x4f, 0x41, 0xb5, 0xe0, 0x75, 0xb2, 0x5f, 0xf2, 0x81, 0xe4, 0xa9, 0x94, 0x90, 0x94, 0xa3, 0x29, 0x33, 0xa9, 0xd1, 0xa9, 0xcd, 0x69, 0x84, 0xb4, 0xf8, 0xb4, 0xd3, 0x42, 0x25, 0x61, 0x8a, 0xb0, 0x2b, 0x5d, 0x33, 0x3d, 0x27, 0xbd, 0x2f, 0xc3, 0x34, 0xa3, 0x30, 0x43, 0xba, 0xca, 0x69, 0xd5, 0xee, 0x55, 0x13, 0xa2, 0x40, 0xd1, 0x91, 0x4c, 0x28, 0x73, 0x59, 0x66, 0xbb, 0x98, 0x8e, 0xfe, 0x4c, 0xf5, 0x48, 0x8c, 0x24, 0x9b, 0x25, 0x83, 0x59, 0x0b, 0xb3, 0x6a, 0xb2, 0xde, 0x67, 0x47, 0x65, 0x9f, 0xca, 0x51, 0xcc, 0x11, 0xe6, 0xf4, 0xe4, 0x9a, 0xe4, 0x6e, 0xcb, 0x1d, 0xc9, 0xf3, 0xc9, 0xfb, 0x7e, 0x35, 0x66, 0x35, 0x77, 0x75, 0x67, 0xbe, 0x76, 0xfe, 0x86, 0xfc, 0xc1, 0x35, 0xee, 0x6b, 0x0e, 0xad, 0x85, 0xd6, 0xae, 0x5c, 0xdb, 0xb9, 0x4e, 0x77, 0x5d, 0xc1, 0xba, 0xe1, 0xf5, 0xbe, 0xeb, 0x8f, 0x6d, 0x20, 0x6d, 0x48, 0xd9, 0xf0, 0xcb, 0x46, 0xcb, 0x8d, 0x65, 0x1b, 0xdf, 0x6e, 0x8a, 0xde, 0xd4, 0x51, 0xa0, 0x51, 0xb0, 0xbe, 0x60, 0x68, 0xb3, 0xef, 0xe6, 0xc6, 0x42, 0xb9, 0x42, 0x51, 0xe1, 0xbd, 0x2d, 0xce, 0x5b, 0x0e, 0x6c, 0xc5, 0x6c, 0x15, 0x6c, 0xed, 0xdd, 0x66, 0xb3, 0xad, 0x6a, 0xdb, 0x97, 0x22, 0x5e, 0xd1, 0xf5, 0x62, 0xcb, 0xe2, 0x8a, 0xe2, 0x4f, 0x25, 0xdc, 0x92, 0xeb, 0xdf, 0x59, 0x7d, 0x57, 0xf9, 0xdd, 0xcc, 0xf6, 0x84, 0xed, 0xbd, 0xa5, 0xf6, 0xa5, 0xfb, 0x77, 0xe0, 0x76, 0x08, 0x77, 0xdc, 0xdd, 0xe9, 0xba, 0xf3, 0x58, 0x99, 0x62, 0x59, 0x5e, 0xd9, 0xd0, 0xae, 0xe0, 0x5d, 0xad, 0xe5, 0xcc, 0xf2, 0xa2, 0xf2, 0xb7, 0xbb, 0x57, 0xec, 0xbe, 0x56, 0x61, 0x5b, 0x71, 0x60, 0x0f, 0x69, 0x8f, 0x64, 0x8f, 0xb4, 0x32, 0xa8, 0xb2, 0xbd, 0x4a, 0xaf, 0x6a, 0x47, 0xd5, 0xa7, 0xea, 0xa4, 0xea, 0x81, 0x1a, 0x8f, 0x9a, 0xe6, 0xbd, 0xea, 0x7b, 0xb7, 0xed, 0x9d, 0xda, 0xc7, 0xdb, 0xd7, 0xbf, 0xdf, 0x6d, 0x7f, 0xd3, 0x01, 0x8d, 0x03, 0xc5, 0x07, 0x3e, 0x1e, 0x14, 0x1c, 0xbc, 0x7f, 0xc8, 0xf7, 0x50, 0x6b, 0xad, 0x41, 0x6d, 0xc5, 0x61, 0xdc, 0xe1, 0xac, 0xc3, 0xcf, 0xeb, 0xa2, 0xea, 0xba, 0xbf, 0x67, 0x7f, 0x5f, 0x7f, 0x44, 0xed, 0x48, 0xf1, 0x91, 0xcf, 0x47, 0x85, 0x47, 0xa5, 0xc7, 0xc2, 0x8f, 0x75, 0xd5, 0x3b, 0xd4, 0xd7, 0x37, 0xa8, 0x37, 0x94, 0x36, 0xc2, 0x8d, 0x92, 0xc6, 0xb1, 0xe3, 0x71, 0xc7, 0x6f, 0xfd, 0xe0, 0xf5, 0x43, 0x7b, 0x13, 0xab, 0xe9, 0x50, 0x33, 0xa3, 0xb9, 0xf8, 0x04, 0x38, 0x21, 0x39, 0xf1, 0xe2, 0xc7, 0xf8, 0x1f, 0xef, 0x9e, 0x0c, 0x3c, 0xd9, 0x79, 0x8a, 0x7d, 0xaa, 0xe9, 0x27, 0xfd, 0x9f, 0xf6, 0xb6, 0xd0, 0x5a, 0x8a, 0x5a, 0xa1, 0xd6, 0xdc, 0xd6, 0x89, 0xb6, 0xa4, 0x36, 0x69, 0x7b, 0x4c, 0x7b, 0xdf, 0xe9, 0x80, 0xd3, 0x9d, 0x1d, 0xce, 0x1d, 0x2d, 0x3f, 0x9b, 0xff, 0x7c, 0xf4, 0x8c, 0xf6, 0x99, 0x9a, 0xb3, 0xca, 0x67, 0x4b, 0xcf, 0x91, 0xce, 0x15, 0x9c, 0x9b, 0x39, 0x9f, 0x77, 0x7e, 0xf2, 0x42, 0xc6, 0x85, 0xf1, 0x8b, 0x89, 0x17, 0x87, 0x3a, 0x57, 0x74, 0x3e, 0xba, 0xb4, 0xe4, 0xd2, 0x9d, 0xae, 0xb0, 0xae, 0xde, 0xcb, 0x81, 0x97, 0xaf, 0x5e, 0xf1, 0xb9, 0x72, 0xa9, 0xdb, 0xbd, 0xfb, 0xfc, 0x55, 0x97, 0xab, 0x67, 0xae, 0x39, 0x5d, 0x3b, 0x7d, 0x9d, 0x7d, 0xbd, 0xed, 0x86, 0xfd, 0x8d, 0xd6, 0x1e, 0xbb, 0x9e, 0x96, 0x5f, 0xec, 0x7e, 0x69, 0xe9, 0xb5, 0xef, 0x6d, 0xbd, 0xe9, 0x70, 0xb3, 0xfd, 0x96, 0xe3, 0xad, 0x8e, 0xbe, 0x05, 0x7d, 0xe7, 0xfa, 0x5d, 0xfb, 0x2f, 0xde, 0xf6, 0xba, 0x7d, 0xe5, 0x8e, 0xff, 0x9d, 0x1b, 0x03, 0x8b, 0x06, 0xfa, 0xee, 0x2e, 0xbe, 0x7b, 0xff, 0x5e, 0xdc, 0x3d, 0xe9, 0x7d, 0xde, 0xfd, 0xd1, 0x07, 0xa9, 0x0f, 0x5e, 0x3f, 0xcc, 0x7a, 0x38, 0xfd, 0x68, 0xfd, 0x63, 0xec, 0xe3, 0xa2, 0x27, 0x0a, 0x4f, 0x2a, 0x9e, 0xaa, 0x3f, 0xad, 0xfd, 0xd5, 0xf8, 0xd7, 0x66, 0xa9, 0xbd, 0xf4, 0xec, 0xa0, 0xd7, 0x60, 0xcf, 0xb3, 0x88, 0x67, 0x8f, 0x86, 0xb8, 0x43, 0x2f, 0xff, 0x95, 0xf9, 0xaf, 0x4f, 0xc3, 0x05, 0xcf, 0xa9, 0xcf, 0x2b, 0x46, 0xb4, 0x46, 0xea, 0x47, 0xad, 0x47, 0xcf, 0x8c, 0xf9, 0x8c, 0xdd, 0x7a, 0xb1, 0xf4, 0xc5, 0xf0, 0xcb, 0x8c, 0x97, 0xd3, 0xe3, 0x85, 0xbf, 0x29, 0xfe, 0xb6, 0xf7, 0x95, 0xd1, 0xab, 0x9f, 0x7e, 0x77, 0xfb, 0xbd, 0x67, 0x62, 0xc9, 0xc4, 0xf0, 0x6b, 0xd1, 0xeb, 0x99, 0x3f, 0x4a, 0xde, 0xa8, 0xbe, 0x39, 0xfa, 0xd6, 0xf6, 0x6d, 0xe7, 0x64, 0xe8, 0xe4, 0xd3, 0x77, 0x69, 0xef, 0xa6, 0xa7, 0x8a, 0xde, 0xab, 0xbe, 0x3f, 0xf6, 0x81, 0xfd, 0xa1, 0xfb, 0x63, 0xf4, 0xc7, 0x91, 0xe9, 0xec, 0x4f, 0xf8, 0x4f, 0x95, 0x9f, 0x8d, 0x3f, 0x77, 0x7c, 0x09, 0xfc, 0xf2, 0x78, 0x26, 0x6d, 0x66, 0xe6, 0xdf, 0xf7, 0x84, 0xf3, 0xfb, 0x32, 0x3a, 0x59, 0x7e, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa4, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x35, 0x2d, 0x30, 0x32, 0x54, 0x31, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x35, 0x35, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc0, 0x10, 0xf8, 0x70, 0x00, 0x00, 0x00, 0x10, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1d, 0x63, 0x60, 0x60, 0x60, 0xf8, 0x0f, 0xc4, 0x70, 0x00, 0x00, 0x0d, 0x04, 0x01, 0x00, 0x65, 0x59, 0x09, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXHierarchyIndentPattern2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xe3, 0x00, 0xef, 0x43, 0x00, 0x00, 0x0a, 0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54, 0x53, 0xd9, 0x16, 0x87, 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20, 0x25, 0xf4, 0x1a, 0x7a, 0x09, 0x20, 0xd2, 0x3b, 0x48, 0x15, 0x04, 0x51, 0x89, 0x49, 0x80, 0x50, 0x02, 0x86, 0x84, 0x26, 0x76, 0x44, 0x05, 0x46, 0x14, 0x11, 0x29, 0x56, 0x64, 0x54, 0xc0, 0x01, 0x47, 0x87, 0x22, 0x63, 0x45, 0x14, 0x0b, 0x83, 0x82, 0x62, 0xd7, 0x09, 0xf2, 0x10, 0x50, 0xc6, 0xc1, 0x51, 0x44, 0x45, 0xe5, 0xdd, 0x8c, 0x6b, 0x09, 0xef, 0xad, 0x35, 0xf3, 0xde, 0x9a, 0xfd, 0xc7, 0x59, 0xdf, 0xd9, 0xe7, 0xb7, 0xd7, 0xd9, 0x67, 0xef, 0x7d, 0xd7, 0xba, 0x00, 0x50, 0xfc, 0x82, 0x04, 0xc2, 0x74, 0x58, 0x01, 0x80, 0x34, 0xa1, 0x58, 0x14, 0xee, 0xeb, 0xc1, 0x5c, 0x12, 0x13, 0xcb, 0xc4, 0xf7, 0x02, 0x18, 0x10, 0x01, 0x0e, 0x58, 0x01, 0xc0, 0xe1, 0x66, 0x66, 0x04, 0x47, 0xf8, 0x44, 0x02, 0xd4, 0xfc, 0xbd, 0x3d, 0x99, 0x99, 0xa8, 0x48, 0xc6, 0xb3, 0xf6, 0xee, 0x2e, 0x80, 0x64, 0xbb, 0xdb, 0x2c, 0xbf, 0x50, 0x26, 0x73, 0xd6, 0xff, 0x7f, 0x91, 0x22, 0x37, 0x43, 0x24, 0x06, 0x00, 0x0a, 0x45, 0xd5, 0x36, 0x3c, 0x7e, 0x26, 0x17, 0xe5, 0x02, 0x94, 0x53, 0xb3, 0xc5, 0x19, 0x32, 0xff, 0x04, 0xca, 0xf4, 0x95, 0x29, 0x32, 0x86, 0x31, 0x32, 0x16, 0xa1, 0x09, 0xa2, 0xac, 0x22, 0xe3, 0xc4, 0xaf, 0x6c, 0xf6, 0xa7, 0xe6, 0x2b, 0xbb, 0xc9, 0x98, 0x97, 0x26, 0xe4, 0xa1, 0x1a, 0x59, 0xce, 0x19, 0xbc, 0x34, 0x9e, 0x8c, 0xbb, 0x50, 0xde, 0x9a, 0x25, 0xe1, 0xa3, 0x8c, 0x04, 0xa1, 0x5c, 0x98, 0x25, 0xe0, 0x67, 0xa3, 0x7c, 0x07, 0x65, 0xbd, 0x54, 0x49, 0x9a, 0x00, 0xe5, 0xf7, 0x28, 0xd3, 0xd3, 0xf8, 0x9c, 0x4c, 0x00, 0x30, 0x14, 0x99, 0x5f, 0xcc, 0xe7, 0x26, 0xa1, 0x6c, 0x89, 0x32, 0x45, 0x14, 0x19, 0xee, 0x89, 0xf2, 0x02, 0x00, 0x08, 0x94, 0xc4, 0x39, 0xbc, 0x72, 0x0e, 0x8b, 0xf9, 0x39, 0x68, 0x9e, 0x00, 0x78, 0xa6, 0x67, 0xe4, 0x8a, 0x04, 0x89, 0x49, 0x62, 0xa6, 0x11, 0xd7, 0x98, 0x69, 0xe5, 0xe8, 0xc8, 0x66, 0xfa, 0xf1, 0xb3, 0x53, 0xf9, 0x62, 0x31, 0x2b, 0x94, 0xc3, 0x4d, 0xe1, 0x88, 0x78, 0x4c, 0xcf, 0xf4, 0xb4, 0x0c, 0x8e, 0x30, 0x17, 0x80, 0xaf, 0x6f, 0x96, 0x45, 0x01, 0x25, 0x59, 0x6d, 0x99, 0x68, 0x91, 0xed, 0xad, 0x1c, 0xed, 0xed, 0x59, 0xd6, 0xe6, 0x68, 0xf9, 0xbf, 0xd9, 0xdf, 0x1e, 0x7e, 0x53, 0xfd, 0x3d, 0xc8, 0x7a, 0xfb, 0x55, 0xf1, 0x26, 0xec, 0xcf, 0x9e, 0x41, 0x8c, 0x9e, 0x59, 0xdf, 0x6c, 0xec, 0xac, 0x2f, 0xbd, 0x16, 0x00, 0xf6, 0x24, 0x5a, 0x9b, 0x1d, 0xb3, 0xbe, 0x95, 0x55, 0x00, 0xb4, 0x6d, 0x06, 0x40, 0xe5, 0xe1, 0xac, 0x4f, 0xef, 0x20, 0x00, 0xf2, 0x05, 0x00, 0xb4, 0xde, 0x9c, 0xf3, 0x1e, 0x86, 0x6c, 0x5e, 0x92, 0xc4, 0xe2, 0x0c, 0x27, 0x0b, 0x8b, 0xec, 0xec, 0x6c, 0x73, 0x01, 0x9f, 0x6b, 0x2e, 0x2b, 0xe8, 0x37, 0xfb, 0x9f, 0x82, 0x6f, 0xca, 0xbf, 0x86, 0x39, 0xf7, 0x99, 0xcb, 0xee, 0xfb, 0x56, 0x3b, 0xa6, 0x17, 0x3f, 0x81, 0x23, 0x49, 0x15, 0x33, 0x65, 0x45, 0xe5, 0xa6, 0xa7, 0xa6, 0x4b, 0x44, 0xcc, 0xcc, 0x0c, 0x0e, 0x97, 0xcf, 0x64, 0xfd, 0xf7, 0x10, 0xff, 0xe3, 0xc0, 0x39, 0x69, 0xcd, 0xc9, 0xc3, 0x2c, 0x9c, 0x9f, 0xc0, 0x17, 0xf1, 0x85, 0xe8, 0x55, 0x51, 0xe8, 0x94, 0x09, 0x84, 0x89, 0x68, 0xbb, 0x85, 0x3c, 0x81, 0x58, 0x90, 0x2e, 0x64, 0x0a, 0x84, 0x7f, 0xd5, 0xe1, 0x7f, 0x18, 0x36, 0x27, 0x07, 0x19, 0x7e, 0x9d, 0x6b, 0x14, 0x68, 0x75, 0x5f, 0x00, 0x7d, 0x85, 0x39, 0x50, 0xb8, 0x49, 0x07, 0xc8, 0x6f, 0x3d, 0x00, 0x43, 0x23, 0x03, 0x24, 0x6e, 0x3f, 0x7a, 0x02, 0x7d, 0xeb, 0x5b, 0x10, 0x31, 0x0a, 0xc8, 0xbe, 0xbc, 0x68, 0xad, 0x91, 0xaf, 0x73, 0x8f, 0x32, 0x7a, 0xfe, 0xe7, 0xfa, 0x1f, 0x0b, 0x5c, 0x8a, 0x6e, 0xe1, 0x4c, 0x41, 0x22, 0x53, 0xe6, 0xf6, 0x0c, 0x8f, 0x64, 0x72, 0x25, 0xa2, 0x2c, 0x19, 0xa3, 0xdf, 0x84, 0x6c, 0xc1, 0x02, 0x12, 0x90, 0x07, 0x74, 0xa0, 0x0a, 0x34, 0x81, 0x2e, 0x30, 0x02, 0x2c, 0x60, 0x0d, 0x1c, 0x80, 0x33, 0x70, 0x03, 0xde, 0x20, 0x00, 0x84, 0x80, 0x48, 0x10, 0x03, 0x96, 0x03, 0x2e, 0x48, 0x02, 0x69, 0x40, 0x04, 0xb2, 0x41, 0x3e, 0xd8, 0x00, 0x0a, 0x41, 0x31, 0xd8, 0x01, 0x76, 0x83, 0x6a, 0x70, 0x00, 0xd4, 0x81, 0x7a, 0xd0, 0x04, 0x4e, 0x82, 0x36, 0x70, 0x06, 0x5c, 0x04, 0x57, 0xc0, 0x0d, 0x70, 0x0b, 0x0c, 0x80, 0x47, 0x40, 0x0a, 0x86, 0xc1, 0x4b, 0x30, 0x01, 0xde, 0x81, 0x69, 0x08, 0x82, 0xf0, 0x10, 0x15, 0xa2, 0x41, 0xaa, 0x90, 0x16, 0xa4, 0x0f, 0x99, 0x42, 0xd6, 0x10, 0x1b, 0x5a, 0x08, 0x79, 0x43, 0x41, 0x50, 0x38, 0x14, 0x03, 0xc5, 0x43, 0x89, 0x90, 0x10, 0x92, 0x40, 0xf9, 0xd0, 0x26, 0xa8, 0x18, 0x2a, 0x83, 0xaa, 0xa1, 0x43, 0x50, 0x3d, 0xf4, 0x23, 0x74, 0x1a, 0xba, 0x08, 0x5d, 0x83, 0xfa, 0xa0, 0x07, 0xd0, 0x20, 0x34, 0x06, 0xfd, 0x01, 0x7d, 0x84, 0x11, 0x98, 0x02, 0xd3, 0x61, 0x0d, 0xd8, 0x00, 0xb6, 0x80, 0xd9, 0xb0, 0x3b, 0x1c, 0x08, 0x47, 0xc2, 0xcb, 0xe0, 0x44, 0x78, 0x15, 0x9c, 0x07, 0x17, 0xc0, 0xdb, 0xe1, 0x4a, 0xb8, 0x16, 0x3e, 0x0e, 0xb7, 0xc2, 0x17, 0xe1, 0x1b, 0xf0, 0x00, 0x2c, 0x85, 0x5f, 0xc2, 0x93, 0x08, 0x40, 0xc8, 0x08, 0x03, 0xd1, 0x46, 0x58, 0x08, 0x1b, 0xf1, 0x44, 0x42, 0x90, 0x58, 0x24, 0x01, 0x11, 0x21, 0x6b, 0x91, 0x22, 0xa4, 0x02, 0xa9, 0x45, 0x9a, 0x90, 0x0e, 0xa4, 0x1b, 0xb9, 0x8d, 0x48, 0x91, 0x71, 0xe4, 0x03, 0x06, 0x87, 0xa1, 0x61, 0x98, 0x18, 0x16, 0xc6, 0x19, 0xe3, 0x87, 0x59, 0x8c, 0xe1, 0x62, 0x56, 0x61, 0xd6, 0x62, 0x4a, 0x30, 0xd5, 0x98, 0x63, 0x98, 0x56, 0x4c, 0x17, 0xe6, 0x36, 0x66, 0x10, 0x33, 0x81, 0xf9, 0x82, 0xa5, 0x62, 0xd5, 0xb1, 0xa6, 0x58, 0x27, 0xac, 0x3f, 0x76, 0x09, 0x36, 0x11, 0x9b, 0x8d, 0x2d, 0xc4, 0x56, 0x60, 0x8f, 0x60, 0x5b, 0xb0, 0x97, 0xb1, 0x03, 0xd8, 0x61, 0xec, 0x3b, 0x1c, 0x0e, 0xc7, 0xc0, 0x19, 0xe2, 0x1c, 0x70, 0x7e, 0xb8, 0x18, 0x5c, 0x32, 0x6e, 0x35, 0xae, 0x04, 0xb7, 0x0f, 0xd7, 0x8c, 0xbb, 0x80, 0xeb, 0xc3, 0x0d, 0xe1, 0x26, 0xf1, 0x78, 0xbc, 0x2a, 0xde, 0x14, 0xef, 0x82, 0x0f, 0xc1, 0x73, 0xf0, 0x62, 0x7c, 0x21, 0xbe, 0x0a, 0x7f, 0x1c, 0x7f, 0x1e, 0xdf, 0x8f, 0x1f, 0xc6, 0xbf, 0x27, 0x90, 0x09, 0x5a, 0x04, 0x6b, 0x82, 0x0f, 0x21, 0x96, 0x20, 0x24, 0x6c, 0x24, 0x54, 0x10, 0x1a, 0x08, 0xe7, 0x08, 0xfd, 0x84, 0x11, 0xc2, 0x34, 0x51, 0x81, 0xa8, 0x4f, 0x74, 0x22, 0x86, 0x10, 0x79, 0xc4, 0x5c, 0x62, 0x29, 0xb1, 0x8e, 0xd8, 0x41, 0xbc, 0x49, 0x1c, 0x26, 0x4e, 0x93, 0x14, 0x49, 0x86, 0x24, 0x17, 0x52, 0x24, 0x29, 0x99, 0xb4, 0x81, 0x54, 0x49, 0x6a, 0x22, 0x5d, 0x26, 0x3d, 0x26, 0xbd, 0x21, 0x93, 0xc9, 0x3a, 0x64, 0x47, 0x72, 0x18, 0x59, 0x40, 0x5e, 0x4f, 0xae, 0x24, 0x9f, 0x20, 0x5f, 0x25, 0x0f, 0x92, 0x3f, 0x50, 0x94, 0x28, 0x26, 0x14, 0x4f, 0x4a, 0x1c, 0x45, 0x42, 0xd9, 0x4e, 0x39, 0x4a, 0xb9, 0x40, 0x79, 0x40, 0x79, 0x43, 0xa5, 0x52, 0x0d, 0xa8, 0x6e, 0xd4, 0x58, 0xaa, 0x98, 0xba, 0x9d, 0x5a, 0x4f, 0xbd, 0x44, 0x7d, 0x4a, 0x7d, 0x2f, 0x47, 0x93, 0x33, 0x97, 0xf3, 0x97, 0xe3, 0xc9, 0xad, 0x93, 0xab, 0x91, 0x6b, 0x95, 0xeb, 0x97, 0x7b, 0x25, 0x4f, 0x94, 0xd7, 0x97, 0x77, 0x97, 0x5f, 0x2e, 0x9f, 0x27, 0x5f, 0x21, 0x7f, 0x4a, 0xfe, 0xa6, 0xfc, 0xb8, 0x02, 0x51, 0xc1, 0x40, 0xc1, 0x53, 0x81, 0xa3, 0xb0, 0x56, 0xa1, 0x46, 0xe1, 0xb4, 0xc2, 0x3d, 0x85, 0x49, 0x45, 0x9a, 0xa2, 0x95, 0x62, 0x88, 0x62, 0x9a, 0x62, 0x89, 0x62, 0x83, 0xe2, 0x35, 0xc5, 0x51, 0x25, 0xbc, 0x92, 0x81, 0x92, 0xb7, 0x12, 0x4f, 0xa9, 0x40, 0xe9, 0xb0, 0xd2, 0x25, 0xa5, 0x21, 0x1a, 0x42, 0xd3, 0xa5, 0x79, 0xd2, 0xb8, 0xb4, 0x4d, 0xb4, 0x3a, 0xda, 0x65, 0xda, 0x30, 0x1d, 0x47, 0x37, 0xa4, 0xfb, 0xd3, 0x93, 0xe9, 0xc5, 0xf4, 0x1f, 0xe8, 0xbd, 0xf4, 0x09, 0x65, 0x25, 0x65, 0x5b, 0xe5, 0x28, 0xe5, 0x1c, 0xe5, 0x1a, 0xe5, 0xb3, 0xca, 0x52, 0x06, 0xc2, 0x30, 0x60, 0xf8, 0x33, 0x52, 0x19, 0xa5, 0x8c, 0x93, 0x8c, 0xbb, 0x8c, 0x8f, 0xf3, 0x34, 0xe6, 0xb9, 0xcf, 0xe3, 0xcf, 0xdb, 0x36, 0xaf, 0x69, 0x5e, 0xff, 0xbc, 0x29, 0x95, 0xf9, 0x2a, 0x6e, 0x2a, 0x7c, 0x95, 0x22, 0x95, 0x66, 0x95, 0x01, 0x95, 0x8f, 0xaa, 0x4c, 0x55, 0x6f, 0xd5, 0x14, 0xd5, 0x9d, 0xaa, 0x6d, 0xaa, 0x4f, 0xd4, 0x30, 0x6a, 0x26, 0x6a, 0x61, 0x6a, 0xd9, 0x6a, 0xfb, 0xd5, 0x2e, 0xab, 0x8d, 0xcf, 0xa7, 0xcf, 0x77, 0x9e, 0xcf, 0x9d, 0x5f, 0x34, 0xff, 0xe4, 0xfc, 0x87, 0xea, 0xb0, 0xba, 0x89, 0x7a, 0xb8, 0xfa, 0x6a, 0xf5, 0xc3, 0xea, 0x3d, 0xea, 0x93, 0x1a, 0x9a, 0x1a, 0xbe, 0x1a, 0x19, 0x1a, 0x55, 0x1a, 0x97, 0x34, 0xc6, 0x35, 0x19, 0x9a, 0x6e, 0x9a, 0xc9, 0x9a, 0xe5, 0x9a, 0xe7, 0x34, 0xc7, 0xb4, 0x68, 0x5a, 0x0b, 0xb5, 0x04, 0x5a, 0xe5, 0x5a, 0xe7, 0xb5, 0x5e, 0x30, 0x95, 0x99, 0xee, 0xcc, 0x54, 0x66, 0x25, 0xb3, 0x8b, 0x39, 0xa1, 0xad, 0xae, 0xed, 0xa7, 0x2d, 0xd1, 0x3e, 0xa4, 0xdd, 0xab, 0x3d, 0xad, 0x63, 0xa8, 0xb3, 0x58, 0x67, 0xa3, 0x4e, 0xb3, 0xce, 0x13, 0x5d, 0x92, 0x2e, 0x5b, 0x37, 0x41, 0xb7, 0x5c, 0xb7, 0x53, 0x77, 0x42, 0x4f, 0x4b, 0x2f, 0x58, 0x2f, 0x5f, 0xaf, 0x51, 0xef, 0xa1, 0x3e, 0x51, 0x9f, 0xad, 0x9f, 0xa4, 0xbf, 0x47, 0xbf, 0x5b, 0x7f, 0xca, 0xc0, 0xd0, 0x20, 0xda, 0x60, 0x8b, 0x41, 0x9b, 0xc1, 0xa8, 0xa1, 0x8a, 0xa1, 0xbf, 0x61, 0x9e, 0x61, 0xa3, 0xe1, 0x63, 0x23, 0xaa, 0x91, 0xab, 0xd1, 0x2a, 0xa3, 0x5a, 0xa3, 0x3b, 0xc6, 0x38, 0x63, 0xb6, 0x71, 0x8a, 0xf1, 0x3e, 0xe3, 0x5b, 0x26, 0xb0, 0x89, 0x9d, 0x49, 0x92, 0x49, 0x8d, 0xc9, 0x4d, 0x53, 0xd8, 0xd4, 0xde, 0x54, 0x60, 0xba, 0xcf, 0xb4, 0xcf, 0x0c, 0x6b, 0xe6, 0x68, 0x26, 0x34, 0xab, 0x35, 0xbb, 0xc7, 0xa2, 0xb0, 0xdc, 0x59, 0x59, 0xac, 0x46, 0xd6, 0xa0, 0x39, 0xc3, 0x3c, 0xc8, 0x7c, 0xa3, 0x79, 0x9b, 0xf9, 0x2b, 0x0b, 0x3d, 0x8b, 0x58, 0x8b, 0x9d, 0x16, 0xdd, 0x16, 0x5f, 0x2c, 0xed, 0x2c, 0x53, 0x2d, 0xeb, 0x2c, 0x1f, 0x59, 0x29, 0x59, 0x05, 0x58, 0x6d, 0xb4, 0xea, 0xb0, 0xfa, 0xc3, 0xda, 0xc4, 0x9a, 0x6b, 0x5d, 0x63, 0x7d, 0xc7, 0x86, 0x6a, 0xe3, 0x63, 0xb3, 0xce, 0xa6, 0xdd, 0xe6, 0xb5, 0xad, 0xa9, 0x2d, 0xdf, 0x76, 0xbf, 0xed, 0x7d, 0x3b, 0x9a, 0x5d, 0xb0, 0xdd, 0x16, 0xbb, 0x4e, 0xbb, 0xcf, 0xf6, 0x0e, 0xf6, 0x22, 0xfb, 0x26, 0xfb, 0x31, 0x07, 0x3d, 0x87, 0x78, 0x87, 0xbd, 0x0e, 0xf7, 0xd8, 0x74, 0x76, 0x28, 0xbb, 0x84, 0x7d, 0xd5, 0x11, 0xeb, 0xe8, 0xe1, 0xb8, 0xce, 0xf1, 0x8c, 0xe3, 0x07, 0x27, 0x7b, 0x27, 0xb1, 0xd3, 0x49, 0xa7, 0xdf, 0x9d, 0x59, 0xce, 0x29, 0xce, 0x0d, 0xce, 0xa3, 0x0b, 0x0c, 0x17, 0xf0, 0x17, 0xd4, 0x2d, 0x18, 0x72, 0xd1, 0x71, 0xe1, 0xb8, 0x1c, 0x72, 0x91, 0x2e, 0x64, 0x2e, 0x8c, 0x5f, 0x78, 0x70, 0xa1, 0xd4, 0x55, 0xdb, 0x95, 0xe3, 0x5a, 0xeb, 0xfa, 0xcc, 0x4d, 0xd7, 0x8d, 0xe7, 0x76, 0xc4, 0x6d, 0xc4, 0xdd, 0xd8, 0x3d, 0xd9, 0xfd, 0xb8, 0xfb, 0x2b, 0x0f, 0x4b, 0x0f, 0x91, 0x47, 0x8b, 0xc7, 0x94, 0xa7, 0x93, 0xe7, 0x1a, 0xcf, 0x0b, 0x5e, 0x88, 0x97, 0xaf, 0x57, 0x91, 0x57, 0xaf, 0xb7, 0x92, 0xf7, 0x62, 0xef, 0x6a, 0xef, 0xa7, 0x3e, 0x3a, 0x3e, 0x89, 0x3e, 0x8d, 0x3e, 0x13, 0xbe, 0x76, 0xbe, 0xab, 0x7d, 0x2f, 0xf8, 0x61, 0xfd, 0x02, 0xfd, 0x76, 0xfa, 0xdd, 0xf3, 0xd7, 0xf0, 0xe7, 0xfa, 0xd7, 0xfb, 0x4f, 0x04, 0x38, 0x04, 0xac, 0x09, 0xe8, 0x0a, 0xa4, 0x04, 0x46, 0x04, 0x56, 0x07, 0x3e, 0x0b, 0x32, 0x09, 0x12, 0x05, 0x75, 0x04, 0xc3, 0xc1, 0x01, 0xc1, 0xbb, 0x82, 0x1f, 0x2f, 0xd2, 0x5f, 0x24, 0x5c, 0xd4, 0x16, 0x02, 0x42, 0xfc, 0x43, 0x76, 0x85, 0x3c, 0x09, 0x35, 0x0c, 0x5d, 0x15, 0xfa, 0x73, 0x18, 0x2e, 0x2c, 0x34, 0xac, 0x26, 0xec, 0x79, 0xb8, 0x55, 0x78, 0x7e, 0x78, 0x77, 0x04, 0x2d, 0x62, 0x45, 0x44, 0x43, 0xc4, 0xbb, 0x48, 0x8f, 0xc8, 0xd2, 0xc8, 0x47, 0x8b, 0x8d, 0x16, 0x4b, 0x16, 0x77, 0x46, 0xc9, 0x47, 0xc5, 0x45, 0xd5, 0x47, 0x4d, 0x45, 0x7b, 0x45, 0x97, 0x45, 0x4b, 0x97, 0x58, 0x2c, 0x59, 0xb3, 0xe4, 0x46, 0x8c, 0x5a, 0x8c, 0x20, 0xa6, 0x3d, 0x16, 0x1f, 0x1b, 0x15, 0x7b, 0x24, 0x76, 0x72, 0xa9, 0xf7, 0xd2, 0xdd, 0x4b, 0x87, 0xe3, 0xec, 0xe2, 0x0a, 0xe3, 0xee, 0x2e, 0x33, 0x5c, 0x96, 0xb3, 0xec, 0xda, 0x72, 0xb5, 0xe5, 0xa9, 0xcb, 0xcf, 0xae, 0x90, 0x5f, 0xc1, 0x59, 0x71, 0x2a, 0x1e, 0x1b, 0x1f, 0x1d, 0xdf, 0x10, 0xff, 0x89, 0x13, 0xc2, 0xa9, 0xe5, 0x4c, 0xae, 0xf4, 0x5f, 0xb9, 0x77, 0xe5, 0x04, 0xd7, 0x93, 0xbb, 0x87, 0xfb, 0x92, 0xe7, 0xc6, 0x2b, 0xe7, 0x8d, 0xf1, 0x5d, 0xf8, 0x65, 0xfc, 0x91, 0x04, 0x97, 0x84, 0xb2, 0x84, 0xd1, 0x44, 0x97, 0xc4, 0x5d, 0x89, 0x63, 0x49, 0xae, 0x49, 0x15, 0x49, 0xe3, 0x02, 0x4f, 0x41, 0xb5, 0xe0, 0x75, 0xb2, 0x5f, 0xf2, 0x81, 0xe4, 0xa9, 0x94, 0x90, 0x94, 0xa3, 0x29, 0x33, 0xa9, 0xd1, 0xa9, 0xcd, 0x69, 0x84, 0xb4, 0xf8, 0xb4, 0xd3, 0x42, 0x25, 0x61, 0x8a, 0xb0, 0x2b, 0x5d, 0x33, 0x3d, 0x27, 0xbd, 0x2f, 0xc3, 0x34, 0xa3, 0x30, 0x43, 0xba, 0xca, 0x69, 0xd5, 0xee, 0x55, 0x13, 0xa2, 0x40, 0xd1, 0x91, 0x4c, 0x28, 0x73, 0x59, 0x66, 0xbb, 0x98, 0x8e, 0xfe, 0x4c, 0xf5, 0x48, 0x8c, 0x24, 0x9b, 0x25, 0x83, 0x59, 0x0b, 0xb3, 0x6a, 0xb2, 0xde, 0x67, 0x47, 0x65, 0x9f, 0xca, 0x51, 0xcc, 0x11, 0xe6, 0xf4, 0xe4, 0x9a, 0xe4, 0x6e, 0xcb, 0x1d, 0xc9, 0xf3, 0xc9, 0xfb, 0x7e, 0x35, 0x66, 0x35, 0x77, 0x75, 0x67, 0xbe, 0x76, 0xfe, 0x86, 0xfc, 0xc1, 0x35, 0xee, 0x6b, 0x0e, 0xad, 0x85, 0xd6, 0xae, 0x5c, 0xdb, 0xb9, 0x4e, 0x77, 0x5d, 0xc1, 0xba, 0xe1, 0xf5, 0xbe, 0xeb, 0x8f, 0x6d, 0x20, 0x6d, 0x48, 0xd9, 0xf0, 0xcb, 0x46, 0xcb, 0x8d, 0x65, 0x1b, 0xdf, 0x6e, 0x8a, 0xde, 0xd4, 0x51, 0xa0, 0x51, 0xb0, 0xbe, 0x60, 0x68, 0xb3, 0xef, 0xe6, 0xc6, 0x42, 0xb9, 0x42, 0x51, 0xe1, 0xbd, 0x2d, 0xce, 0x5b, 0x0e, 0x6c, 0xc5, 0x6c, 0x15, 0x6c, 0xed, 0xdd, 0x66, 0xb3, 0xad, 0x6a, 0xdb, 0x97, 0x22, 0x5e, 0xd1, 0xf5, 0x62, 0xcb, 0xe2, 0x8a, 0xe2, 0x4f, 0x25, 0xdc, 0x92, 0xeb, 0xdf, 0x59, 0x7d, 0x57, 0xf9, 0xdd, 0xcc, 0xf6, 0x84, 0xed, 0xbd, 0xa5, 0xf6, 0xa5, 0xfb, 0x77, 0xe0, 0x76, 0x08, 0x77, 0xdc, 0xdd, 0xe9, 0xba, 0xf3, 0x58, 0x99, 0x62, 0x59, 0x5e, 0xd9, 0xd0, 0xae, 0xe0, 0x5d, 0xad, 0xe5, 0xcc, 0xf2, 0xa2, 0xf2, 0xb7, 0xbb, 0x57, 0xec, 0xbe, 0x56, 0x61, 0x5b, 0x71, 0x60, 0x0f, 0x69, 0x8f, 0x64, 0x8f, 0xb4, 0x32, 0xa8, 0xb2, 0xbd, 0x4a, 0xaf, 0x6a, 0x47, 0xd5, 0xa7, 0xea, 0xa4, 0xea, 0x81, 0x1a, 0x8f, 0x9a, 0xe6, 0xbd, 0xea, 0x7b, 0xb7, 0xed, 0x9d, 0xda, 0xc7, 0xdb, 0xd7, 0xbf, 0xdf, 0x6d, 0x7f, 0xd3, 0x01, 0x8d, 0x03, 0xc5, 0x07, 0x3e, 0x1e, 0x14, 0x1c, 0xbc, 0x7f, 0xc8, 0xf7, 0x50, 0x6b, 0xad, 0x41, 0x6d, 0xc5, 0x61, 0xdc, 0xe1, 0xac, 0xc3, 0xcf, 0xeb, 0xa2, 0xea, 0xba, 0xbf, 0x67, 0x7f, 0x5f, 0x7f, 0x44, 0xed, 0x48, 0xf1, 0x91, 0xcf, 0x47, 0x85, 0x47, 0xa5, 0xc7, 0xc2, 0x8f, 0x75, 0xd5, 0x3b, 0xd4, 0xd7, 0x37, 0xa8, 0x37, 0x94, 0x36, 0xc2, 0x8d, 0x92, 0xc6, 0xb1, 0xe3, 0x71, 0xc7, 0x6f, 0xfd, 0xe0, 0xf5, 0x43, 0x7b, 0x13, 0xab, 0xe9, 0x50, 0x33, 0xa3, 0xb9, 0xf8, 0x04, 0x38, 0x21, 0x39, 0xf1, 0xe2, 0xc7, 0xf8, 0x1f, 0xef, 0x9e, 0x0c, 0x3c, 0xd9, 0x79, 0x8a, 0x7d, 0xaa, 0xe9, 0x27, 0xfd, 0x9f, 0xf6, 0xb6, 0xd0, 0x5a, 0x8a, 0x5a, 0xa1, 0xd6, 0xdc, 0xd6, 0x89, 0xb6, 0xa4, 0x36, 0x69, 0x7b, 0x4c, 0x7b, 0xdf, 0xe9, 0x80, 0xd3, 0x9d, 0x1d, 0xce, 0x1d, 0x2d, 0x3f, 0x9b, 0xff, 0x7c, 0xf4, 0x8c, 0xf6, 0x99, 0x9a, 0xb3, 0xca, 0x67, 0x4b, 0xcf, 0x91, 0xce, 0x15, 0x9c, 0x9b, 0x39, 0x9f, 0x77, 0x7e, 0xf2, 0x42, 0xc6, 0x85, 0xf1, 0x8b, 0x89, 0x17, 0x87, 0x3a, 0x57, 0x74, 0x3e, 0xba, 0xb4, 0xe4, 0xd2, 0x9d, 0xae, 0xb0, 0xae, 0xde, 0xcb, 0x81, 0x97, 0xaf, 0x5e, 0xf1, 0xb9, 0x72, 0xa9, 0xdb, 0xbd, 0xfb, 0xfc, 0x55, 0x97, 0xab, 0x67, 0xae, 0x39, 0x5d, 0x3b, 0x7d, 0x9d, 0x7d, 0xbd, 0xed, 0x86, 0xfd, 0x8d, 0xd6, 0x1e, 0xbb, 0x9e, 0x96, 0x5f, 0xec, 0x7e, 0x69, 0xe9, 0xb5, 0xef, 0x6d, 0xbd, 0xe9, 0x70, 0xb3, 0xfd, 0x96, 0xe3, 0xad, 0x8e, 0xbe, 0x05, 0x7d, 0xe7, 0xfa, 0x5d, 0xfb, 0x2f, 0xde, 0xf6, 0xba, 0x7d, 0xe5, 0x8e, 0xff, 0x9d, 0x1b, 0x03, 0x8b, 0x06, 0xfa, 0xee, 0x2e, 0xbe, 0x7b, 0xff, 0x5e, 0xdc, 0x3d, 0xe9, 0x7d, 0xde, 0xfd, 0xd1, 0x07, 0xa9, 0x0f, 0x5e, 0x3f, 0xcc, 0x7a, 0x38, 0xfd, 0x68, 0xfd, 0x63, 0xec, 0xe3, 0xa2, 0x27, 0x0a, 0x4f, 0x2a, 0x9e, 0xaa, 0x3f, 0xad, 0xfd, 0xd5, 0xf8, 0xd7, 0x66, 0xa9, 0xbd, 0xf4, 0xec, 0xa0, 0xd7, 0x60, 0xcf, 0xb3, 0x88, 0x67, 0x8f, 0x86, 0xb8, 0x43, 0x2f, 0xff, 0x95, 0xf9, 0xaf, 0x4f, 0xc3, 0x05, 0xcf, 0xa9, 0xcf, 0x2b, 0x46, 0xb4, 0x46, 0xea, 0x47, 0xad, 0x47, 0xcf, 0x8c, 0xf9, 0x8c, 0xdd, 0x7a, 0xb1, 0xf4, 0xc5, 0xf0, 0xcb, 0x8c, 0x97, 0xd3, 0xe3, 0x85, 0xbf, 0x29, 0xfe, 0xb6, 0xf7, 0x95, 0xd1, 0xab, 0x9f, 0x7e, 0x77, 0xfb, 0xbd, 0x67, 0x62, 0xc9, 0xc4, 0xf0, 0x6b, 0xd1, 0xeb, 0x99, 0x3f, 0x4a, 0xde, 0xa8, 0xbe, 0x39, 0xfa, 0xd6, 0xf6, 0x6d, 0xe7, 0x64, 0xe8, 0xe4, 0xd3, 0x77, 0x69, 0xef, 0xa6, 0xa7, 0x8a, 0xde, 0xab, 0xbe, 0x3f, 0xf6, 0x81, 0xfd, 0xa1, 0xfb, 0x63, 0xf4, 0xc7, 0x91, 0xe9, 0xec, 0x4f, 0xf8, 0x4f, 0x95, 0x9f, 0x8d, 0x3f, 0x77, 0x7c, 0x09, 0xfc, 0xf2, 0x78, 0x26, 0x6d, 0x66, 0xe6, 0xdf, 0xf7, 0x84, 0xf3, 0xfb, 0x32, 0x3a, 0x59, 0x7e, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa4, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x35, 0x2d, 0x30, 0x32, 0x54, 0x31, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x30, 0x36, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x38, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x90, 0x7a, 0xe1, 0x8d, 0x00, 0x00, 0x00, 0x12, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1d, 0x63, 0x60, 0x60, 0x60, 0xf8, 0x0f, 0xc5, 0x40, 0x0a, 0x13, 0x00, 0x00, 0x35, 0xeb, 0x01, 0xff, 0x0f, 0x5e, 0xbc, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXListIcon[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x06, 0x00, 0x00, 0x00, 0xe4, 0x98, 0xef, 0x55, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x00, 0x65, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0x63, 0x60, 0x60, 0x60, 0x68, 0x05, 0xe2, 0x9f, 0x40, 0xfc, 0x9f, 0x42, 0x0c, 0x32, 0xa3, 0x95, 0x11, 0x48, 0x7c, 0x06, 0x62, 0x1e, 0x20, 0xa6, 0x06, 0xf8, 0xc2, 0x0c, 0x34, 0x05, 0x64, 0x98, 0x39, 0x10, 0x83, 0xd8, 0x94, 0x80, 0x5f, 0x40, 0xcd, 0xfd, 0x94, 0x18, 0x30, 0x84, 0xf5, 0x36, 0x03, 0xdd, 0xfe, 0x0d, 0x88, 0xff, 0x52, 0x88, 0x41, 0x66, 0x34, 0xd3, 0x24, 0x96, 0xf9, 0x81, 0x26, 0x53, 0x23, 0x96, 0x7f, 0x03, 0xcd, 0x99, 0x04, 0x72, 0x21, 0x08, 0x80, 0x68, 0x18, 0x1b, 0x2c, 0x40, 0x06, 0x01, 0xcb, 0x18, 0x64, 0x68, 0xa5, 0xb7, 0x96, 0x11, 0x16, 0xcb, 0x00, 0xa6, 0x38, 0x45, 0xd2, 0xe0, 0x92, 0x71, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXListIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x5e, 0xdd, 0x5c, 0xdd, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x00, 0x94, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x96, 0xc1, 0x09, 0x80, 0x30, 0x14, 0x43, 0xbf, 0x0a, 0x6e, 0xe0, 0xc1, 0x5d, 0x1c, 0xb0, 0x13, 0x38, 0xa2, 0x8e, 0xa1, 0x89, 0x87, 0xd2, 0x7a, 0xfc, 0x5e, 0x22, 0x44, 0x08, 0xf4, 0x0b, 0xc2, 0x23, 0x8d, 0x4d, 0x23, 0x22, 0x66, 0xa8, 0x40, 0x07, 0x74, 0x89, 0x88, 0x2c, 0x64, 0x22, 0xdb, 0xb3, 0x50, 0x01, 0x7b, 0x73, 0x94, 0x01, 0x80, 0xa4, 0x5d, 0x49, 0x2a, 0xf8, 0x9c, 0xa3, 0x20, 0x54, 0x87, 0x34, 0x61, 0x5a, 0xa0, 0xad, 0x7b, 0xab, 0x33, 0xec, 0x44, 0x61, 0x10, 0xa5, 0x7f, 0x12, 0x1d, 0xbf, 0x4c, 0x62, 0x07, 0xec, 0x40, 0xce, 0x01, 0xf9, 0x63, 0x86, 0x67, 0xe0, 0xbb, 0x03, 0x55, 0x66, 0x77, 0x71, 0x2e, 0x74, 0xcd, 0x57, 0xee, 0xe2, 0x64, 0xbe, 0x79, 0x05, 0xac, 0x17, 0xd6, 0xc6, 0x50, 0x2f, 0xed, 0x80, 0x1d, 0xf8, 0xa5, 0x03, 0xee, 0x62, 0x6c, 0x5b, 0xb6, 0xdb, 0xdd, 0xc5, 0x9f, 0x33, 0xef, 0x2e, 0x4e, 0xe6, 0xaf, 0x76, 0xf1, 0x0d, 0xa7, 0xae, 0x59, 0xeb, 0x22, 0xc6, 0xba, 0x58, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXMoveIcon[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x17, 0xa5, 0x96, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x01, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0xb5, 0x95, 0x31, 0x4e, 0x03, 0x41, 0x0c, 0x45, 0x87, 0x40, 0xfa, 0x88, 0x13, 0xa4, 0xa1, 0xe2, 0x0e, 0x88, 0x94, 0xd4, 0x1c, 0x21, 0x1d, 0x07, 0x80, 0x33, 0x40, 0x49, 0x41, 0xc7, 0x11, 0xe8, 0x22, 0xa1, 0x54, 0x41, 0x94, 0xf4, 0x14, 0x11, 0x12, 0xe4, 0x04, 0x5c, 0x00, 0x09, 0x78, 0x4f, 0x9a, 0x41, 0x93, 0xdd, 0xcd, 0x32, 0xcb, 0x86, 0x2f, 0x7d, 0xd9, 0xe3, 0xb1, 0x7f, 0x2c, 0xaf, 0x47, 0x09, 0xa1, 0x0c, 0xfb, 0xa4, 0xcd, 0xa0, 0x76, 0x2b, 0x18, 0xa2, 0xb2, 0x80, 0x5f, 0xd1, 0x7a, 0xee, 0x8d, 0x5b, 0x14, 0x14, 0x4c, 0xf4, 0xdc, 0x0b, 0xe7, 0x54, 0x27, 0xb1, 0xdc, 0x1a, 0xdf, 0x88, 0xdd, 0x8d, 0x37, 0x21, 0x1c, 0x70, 0x77, 0x06, 0x5f, 0xa1, 0x79, 0x23, 0xb8, 0x82, 0x4f, 0x70, 0x1c, 0xed, 0x3b, 0xf6, 0xcf, 0xb8, 0xa1, 0xd2, 0x4e, 0xb5, 0xbf, 0x62, 0xd0, 0x90, 0x61, 0x87, 0x5d, 0x50, 0xcb, 0xaf, 0x8a, 0x3a, 0xab, 0xeb, 0x2e, 0x8a, 0x31, 0x7f, 0x6d, 0xc6, 0x49, 0xd4, 0x35, 0xf1, 0xab, 0x5e, 0xc2, 0x14, 0xc3, 0x2d, 0x82, 0xf9, 0xd6, 0x59, 0xaf, 0x4e, 0xd8, 0x81, 0x2e, 0xf4, 0x1d, 0x3c, 0x86, 0x62, 0x05, 0xef, 0x75, 0x32, 0x1c, 0xe1, 0x1f, 0xc2, 0x67, 0xf8, 0x98, 0xc5, 0x75, 0x4f, 0xe0, 0x58, 0x07, 0x3c, 0xc0, 0x53, 0x1d, 0x5f, 0x4a, 0xbe, 0x2e, 0x7d, 0xfd, 0xd9, 0xbf, 0x75, 0x6a, 0xb7, 0x69, 0xa6, 0x76, 0x39, 0x37, 0x50, 0x41, 0xdb, 0x4a, 0x99, 0x6f, 0xdd, 0xcf, 0x4c, 0xf7, 0x62, 0xf1, 0x07, 0x76, 0x0a, 0x97, 0x70, 0x12, 0x63, 0xa5, 0xe6, 0x93, 0xc4, 0x0b, 0x78, 0xd5, 0x56, 0x50, 0xdb, 0x3b, 0x92, 0xdb, 0x3a, 0xad, 0xe5, 0x37, 0xad, 0xcf, 0x4b, 0xdb, 0x2f, 0x36, 0xdc, 0x75, 0xca, 0xb7, 0x03, 0x57, 0xcb, 0x99, 0xbd, 0x41, 0xe7, 0xa6, 0xf5, 0x6c, 0xbc, 0xd6, 0x21, 0xb1, 0x22, 0xf8, 0x52, 0x14, 0xab, 0x72, 0xed, 0x05, 0x15, 0x29, 0x55, 0x92, 0xfc, 0xaa, 0xb9, 0xa8, 0xe7, 0xde, 0x18, 0xa2, 0xb0, 0x80, 0x0a, 0x6b, 0x3d, 0x6f, 0x05, 0x9d, 0xfe, 0xa3, 0xbe, 0x01, 0xe4, 0xf1, 0x5c, 0xce, 0x72, 0x04, 0x22, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXMoveIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xc5, 0xc3, 0xc9, 0x5b, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x02, 0x26, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xdd, 0x99, 0x3b, 0x4e, 0x03, 0x31, 0x14, 0x45, 0x13, 0x84, 0x44, 0x56, 0x00, 0x0b, 0xa0, 0xa5, 0x46, 0x84, 0x0e, 0xaa, 0x6c, 0x01, 0x04, 0x3b, 0x48, 0x07, 0x0b, 0x08, 0x3d, 0xbb, 0xe0, 0xbb, 0x8b, 0x74, 0x04, 0x7a, 0x7a, 0xd2, 0x42, 0x47, 0x47, 0x81, 0x04, 0xf7, 0x84, 0x38, 0x7a, 0x71, 0x66, 0x3c, 0x33, 0x61, 0x26, 0x36, 0x5c, 0xe9, 0xc6, 0x9f, 0x67, 0xbf, 0x77, 0xe5, 0xdf, 0xd8, 0x4a, 0xab, 0x55, 0x3f, 0xfa, 0x72, 0x09, 0x93, 0x46, 0x4f, 0xea, 0x3e, 0xa7, 0x24, 0x9f, 0x24, 0x76, 0xa4, 0xea, 0x5d, 0xfc, 0x9a, 0x92, 0x3c, 0x75, 0x49, 0x61, 0x53, 0x6a, 0xc6, 0xa2, 0x13, 0xe9, 0x52, 0xea, 0xb0, 0x25, 0x81, 0x8e, 0x54, 0x8c, 0x44, 0x27, 0xce, 0x4f, 0xb1, 0xd1, 0x26, 0x3a, 0xee, 0xa4, 0xc0, 0x17, 0xe7, 0x97, 0x69, 0x13, 0x15, 0x03, 0x45, 0xf7, 0x45, 0xe5, 0x95, 0x69, 0x1b, 0x05, 0xc7, 0x8a, 0x9a, 0x27, 0x2a, 0xaf, 0x9e, 0x3e, 0x2b, 0xc5, 0xbe, 0xa2, 0x7d, 0x88, 0x79, 0x82, 0xf2, 0xea, 0xe9, 0x43, 0xdf, 0xca, 0x68, 0x57, 0xee, 0xf1, 0xd3, 0xe1, 0x54, 0x49, 0xd6, 0x6e, 0xbe, 0xf4, 0xfc, 0x9d, 0x7b, 0x65, 0x8a, 0x6f, 0xe2, 0x55, 0x46, 0x7d, 0xb0, 0x6a, 0x59, 0xa1, 0x79, 0x4e, 0x19, 0x49, 0x8b, 0xda, 0xfc, 0xaf, 0x59, 0xaf, 0x29, 0xe7, 0xff, 0x95, 0xd0, 0xae, 0x46, 0x9a, 0x35, 0xd9, 0x14, 0xf0, 0x4d, 0x8c, 0x20, 0x8a, 0x46, 0x94, 0xe3, 0x64, 0x28, 0x66, 0x6d, 0x9c, 0xa0, 0xe3, 0x0a, 0x46, 0x7c, 0x13, 0x23, 0x78, 0x74, 0x85, 0x84, 0x0e, 0xd4, 0xf9, 0x46, 0xdc, 0x10, 0x9b, 0x06, 0x31, 0x88, 0x35, 0xa8, 0x12, 0x88, 0xef, 0xf2, 0xad, 0x68, 0xcf, 0xc2, 0xb3, 0x92, 0x0e, 0x6c, 0x1f, 0xf2, 0x65, 0x80, 0x6f, 0xdb, 0x8f, 0xd8, 0x0b, 0x77, 0x03, 0x7f, 0x44, 0xdd, 0x34, 0x1c, 0x95, 0x89, 0xd0, 0x50, 0x1b, 0x62, 0x0f, 0xc5, 0xb9, 0xe5, 0x66, 0x85, 0x72, 0x77, 0x7c, 0x12, 0xf7, 0xc4, 0xd8, 0x40, 0x03, 0x5a, 0x16, 0xee, 0xb3, 0x3d, 0x55, 0xda, 0x4b, 0xaf, 0x9d, 0x8a, 0x98, 0x79, 0x34, 0xa1, 0x6d, 0x82, 0xbe, 0x7e, 0x79, 0x3e, 0xc4, 0x14, 0x14, 0x8a, 0x8d, 0xb6, 0xbe, 0x9d, 0xfa, 0x89, 0xea, 0xd4, 0x7f, 0xfe, 0xc4, 0xd4, 0xbb, 0x41, 0x64, 0xe1, 0x8e, 0xc5, 0xac, 0x69, 0x58, 0xe5, 0xf1, 0xe4, 0xe2, 0xa3, 0x65, 0xb6, 0x99, 0xec, 0xd4, 0x3f, 0xcb, 0xb0, 0x2b, 0x3e, 0x8a, 0xb1, 0x81, 0x06, 0xb4, 0xa0, 0x69, 0x02, 0x2b, 0x94, 0x0a, 0xee, 0x8a, 0x07, 0xe2, 0x3d, 0x85, 0x48, 0x20, 0x36, 0x1a, 0xd0, 0x32, 0x83, 0x2f, 0x14, 0x03, 0xb7, 0x70, 0x0e, 0xdd, 0x0b, 0x0a, 0x2b, 0x06, 0x31, 0x89, 0x8d, 0x86, 0x4a, 0xe0, 0xa2, 0x40, 0xa7, 0xa6, 0xd7, 0x28, 0x31, 0x82, 0x97, 0x92, 0xf5, 0x02, 0xd9, 0x7c, 0x77, 0xc7, 0xe2, 0x76, 0x41, 0xbb, 0xdf, 0x98, 0x99, 0xe2, 0x43, 0xf1, 0x21, 0xe4, 0xa4, 0x1d, 0x32, 0x2e, 0x61, 0x63, 0xc7, 0x5a, 0xd4, 0xe6, 0x3f, 0x6b, 0x8d, 0xda, 0x40, 0xc9, 0xe4, 0xff, 0x8c, 0xd0, 0xa2, 0x35, 0x9a, 0x37, 0xa2, 0x27, 0x32, 0x6c, 0xe5, 0x19, 0x4d, 0x7d, 0xd6, 0x26, 0x7c, 0x95, 0xfd, 0xda, 0xb4, 0x69, 0x34, 0xdb, 0x95, 0x77, 0x76, 0xaa, 0xfb, 0x8a, 0x94, 0x4d, 0xe9, 0x43, 0xdf, 0x95, 0x82, 0xe3, 0xa4, 0xac, 0x40, 0xd7, 0x2e, 0x78, 0x04, 0x35, 0xa9, 0x7e, 0x50, 0x41, 0x2c, 0x6d, 0xa3, 0xc2, 0x7f, 0x5f, 0xb9, 0xd1, 0xb3, 0x29, 0x6d, 0xa2, 0xa3, 0x23, 0x05, 0x23, 0xd1, 0x0a, 0xb3, 0x79, 0x6c, 0xb4, 0x49, 0x02, 0x3c, 0xc4, 0x5e, 0x44, 0x2b, 0x90, 0x3c, 0x75, 0x73, 0x8f, 0x34, 0x95, 0xa3, 0x83, 0xbb, 0xa3, 0x7d, 0x77, 0x25, 0xf9, 0x67, 0x83, 0x1b, 0xa5, 0x9e, 0x32, 0xc9, 0xff, 0x7d, 0xe3, 0xc4, 0xf2, 0x58, 0x84, 0xb5, 0xe2, 0x1b, 0xb0, 0x4b, 0x43, 0x5f, 0xe1, 0x68, 0x89, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXSelectIcon[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x11, 0x08, 0x06, 0x00, 0x00, 0x00, 0xed, 0xc8, 0x9d, 0x9f, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x00, 0xf4, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x95, 0x92, 0xc1, 0x0a, 0x01, 0x61, 0x14, 0x85, 0x27, 0x45, 0x64, 0xa3, 0x94, 0x2c, 0xac, 0xa4, 0x44, 0x51, 0x16, 0xd6, 0xf6, 0xca, 0xc6, 0x23, 0x78, 0x02, 0x25, 0x2f, 0x61, 0xc9, 0xc6, 0xde, 0x0b, 0xd8, 0x51, 0xbc, 0x82, 0xc8, 0x4e, 0xa1, 0xa4, 0xac, 0x94, 0x6c, 0x88, 0x14, 0xdf, 0xd5, 0xdc, 0xfa, 0x1b, 0x33, 0x98, 0x53, 0xdf, 0xdc, 0xeb, 0xfe, 0xe7, 0x5c, 0x63, 0x8c, 0x65, 0x59, 0x56, 0x17, 0x72, 0xe0, 0x4b, 0x01, 0xdb, 0xbd, 0xa4, 0xf6, 0x20, 0xee, 0x27, 0x5d, 0xc5, 0xfc, 0xb4, 0x39, 0x51, 0x9b, 0x10, 0x84, 0x9f, 0x8a, 0xe0, 0xb8, 0x82, 0x86, 0xa5, 0xae, 0xa0, 0x06, 0x3f, 0x35, 0xc6, 0x61, 0x06, 0xb5, 0x9f, 0x32, 0x2f, 0x7c, 0x4b, 0xcb, 0xed, 0xa9, 0xd9, 0x59, 0x1f, 0x9c, 0xf5, 0x21, 0xe1, 0xb6, 0x20, 0xfb, 0x25, 0xa8, 0x8b, 0xce, 0x78, 0xda, 0x10, 0x72, 0x2e, 0xd8, 0xfe, 0x11, 0x96, 0x25, 0x1b, 0xa8, 0xeb, 0xdf, 0x21, 0x4b, 0x46, 0x72, 0xf9, 0x43, 0x49, 0x3c, 0x61, 0xd3, 0x27, 0x4f, 0x51, 0x6f, 0xcb, 0xab, 0xae, 0xf1, 0x14, 0xcd, 0x90, 0xf4, 0x51, 0xb8, 0x81, 0x57, 0x68, 0xc6, 0x59, 0x0c, 0x5c, 0x35, 0x61, 0xea, 0x15, 0xbc, 0x70, 0x56, 0x76, 0x4d, 0x31, 0x6c, 0x39, 0x82, 0xf2, 0x26, 0xed, 0x8d, 0xd9, 0x81, 0x3e, 0x05, 0x1f, 0xca, 0x33, 0xd1, 0x6f, 0x5c, 0xd0, 0xa7, 0x21, 0x03, 0x47, 0x63, 0x3e, 0xa7, 0x97, 0x9f, 0xf5, 0xa1, 0x1d, 0x93, 0x01, 0xc8, 0xab, 0xa8, 0xaa, 0xd0, 0xdc, 0x41, 0x97, 0x0e, 0xf5, 0xc0, 0xac, 0x25, 0xf3, 0x83, 0xd1, 0x37, 0xe8, 0x35, 0x28, 0xd5, 0x97, 0x3a, 0xb8, 0xdf, 0xe1, 0x17, 0xaf, 0x54, 0x62, 0xf7, 0x88, 0x7e, 0xaa, 0x27, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXSelectIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x22, 0x08, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x7d, 0xb9, 0x49, 0x00, 0x00, 0x0c, 0x45, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0xad, 0x57, 0x77, 0x58, 0x53, 0xd7, 0x1b, 0xfe, 0xee, 0x48, 0x02, 0x21, 0x09, 0x23, 0x10, 0x01, 0x19, 0x61, 0x2f, 0x51, 0xf6, 0x94, 0xbd, 0x05, 0x05, 0x99, 0x42, 0x1d, 0x84, 0x24, 0x90, 0x30, 0x62, 0x08, 0x04, 0x15, 0xf7, 0x28, 0xad, 0x60, 0x1d, 0xa8, 0x38, 0x70, 0x54, 0xb4, 0x2a, 0xe2, 0xaa, 0x03, 0x90, 0x3a, 0x10, 0x71, 0x5b, 0x14, 0xb7, 0x75, 0x14, 0xb5, 0x28, 0x28, 0xb5, 0x38, 0x70, 0xa1, 0xf2, 0x3b, 0x37, 0x0c, 0xfb, 0xf4, 0x69, 0xff, 0xfb, 0xdd, 0xe7, 0x39, 0xe7, 0xbe, 0x79, 0xbf, 0xef, 0x7c, 0xf7, 0xfd, 0xbe, 0x7b, 0xee, 0xc9, 0x39, 0x00, 0x9a, 0xb6, 0x02, 0xb9, 0x3c, 0x17, 0xd7, 0x02, 0xc8, 0x93, 0x15, 0x2a, 0xe2, 0x23, 0x82, 0xf9, 0x13, 0x52, 0xd3, 0xf8, 0x8c, 0x07, 0x80, 0x83, 0x01, 0x70, 0xc0, 0x0d, 0x48, 0x81, 0xb0, 0x40, 0x1e, 0x14, 0x17, 0x17, 0x03, 0xff, 0x79, 0xbd, 0xbd, 0x09, 0x18, 0x65, 0xbc, 0xe6, 0x48, 0xc5, 0xfa, 0x4f, 0xb7, 0x7f, 0x37, 0x68, 0x8b, 0xc4, 0x05, 0x42, 0x00, 0x2c, 0x0e, 0x99, 0x33, 0x44, 0x05, 0xc2, 0x3c, 0x84, 0x0f, 0x01, 0x90, 0x1c, 0xa1, 0x5c, 0x51, 0x08, 0x40, 0x6b, 0x46, 0xbc, 0xc5, 0xb4, 0x42, 0x39, 0x85, 0x3b, 0x10, 0xd6, 0x55, 0x20, 0x81, 0x08, 0x7f, 0xa2, 0x70, 0x96, 0x0a, 0xd3, 0x91, 0x7a, 0xd0, 0xcd, 0xe8, 0xc7, 0x96, 0x2a, 0x9f, 0xc4, 0xf8, 0x10, 0x00, 0xba, 0x17, 0x80, 0x1a, 0x4b, 0x20, 0x50, 0x64, 0x01, 0x70, 0x42, 0x11, 0xcf, 0x2f, 0x12, 0x66, 0xa1, 0x38, 0x1c, 0x11, 0xc2, 0x4e, 0x32, 0x91, 0x54, 0x86, 0xf0, 0x2a, 0x84, 0xfd, 0x85, 0x12, 0x01, 0xe2, 0x38, 0xd7, 0x11, 0x1e, 0x91, 0x97, 0x37, 0x15, 0x61, 0x4d, 0x04, 0xc1, 0x36, 0xe3, 0x6f, 0x71, 0xb2, 0xfe, 0x86, 0x05, 0x82, 0x8c, 0xa1, 0x98, 0x02, 0x41, 0xd6, 0x10, 0xee, 0xcf, 0x85, 0x1a, 0x0a, 0x6a, 0xa1, 0xd2, 0x02, 0x79, 0xae, 0x60, 0x86, 0xea, 0xc7, 0xff, 0xb3, 0xcb, 0xcb, 0x55, 0xa2, 0x7a, 0xa9, 0x2e, 0x33, 0xd4, 0xb3, 0x24, 0x8a, 0xc8, 0x78, 0x74, 0xd7, 0x45, 0x75, 0xdb, 0x90, 0x33, 0x35, 0x9a, 0xc2, 0x2c, 0x84, 0xf7, 0xcb, 0x32, 0xc6, 0xc5, 0x22, 0xac, 0x83, 0xf0, 0x51, 0x29, 0x95, 0x71, 0x3f, 0x6e, 0x91, 0x28, 0x23, 0x93, 0x10, 0xa6, 0xfc, 0xdb, 0x84, 0x05, 0x21, 0xa8, 0x96, 0xc0, 0x43, 0xf8, 0x8d, 0x48, 0x10, 0x1a, 0x8d, 0xb0, 0x11, 0x00, 0xce, 0x54, 0xe6, 0x24, 0x05, 0x0d, 0x60, 0x6b, 0x81, 0x02, 0x21, 0x95, 0x3f, 0x1e, 0x2c, 0x2d, 0x8c, 0x4a, 0x1c, 0xc0, 0xc9, 0x8a, 0xa9, 0xf1, 0x03, 0xf1, 0xf1, 0x6c, 0x59, 0xee, 0x38, 0x6a, 0x7e, 0xa0, 0x38, 0xf8, 0x2c, 0x89, 0x38, 0x6a, 0x10, 0x97, 0x8b, 0x0b, 0xc2, 0x12, 0x10, 0x8f, 0x34, 0xe0, 0xd9, 0x99, 0xd2, 0xf0, 0x28, 0x84, 0xd1, 0xbb, 0xc2, 0x77, 0x16, 0x4b, 0x12, 0x53, 0x10, 0x46, 0x3a, 0xf1, 0xfa, 0x22, 0x69, 0xf2, 0x38, 0x84, 0x39, 0x08, 0x37, 0x17, 0xe4, 0x24, 0x50, 0x1a, 0xa8, 0x38, 0x57, 0x8b, 0x25, 0x21, 0x14, 0xaf, 0xf2, 0x51, 0x28, 0xe3, 0x29, 0xcd, 0x96, 0x88, 0xef, 0xc8, 0x54, 0x84, 0x53, 0x39, 0x22, 0x1f, 0x82, 0x95, 0x57, 0x80, 0x90, 0x2a, 0x3e, 0x61, 0x2e, 0x14, 0xa8, 0x9e, 0xa5, 0x8f, 0x78, 0xb7, 0x42, 0x49, 0x62, 0x24, 0xe2, 0xd1, 0x58, 0x22, 0x46, 0x24, 0x0e, 0x0d, 0x43, 0x18, 0x3d, 0x97, 0x98, 0x20, 0x96, 0x25, 0x0d, 0xe8, 0x21, 0x24, 0xf2, 0xc2, 0x60, 0x2a, 0x0e, 0xe5, 0x5f, 0x2c, 0xcf, 0x55, 0xcd, 0x6f, 0xa4, 0x93, 0x28, 0x17, 0xe7, 0x46, 0x50, 0xbc, 0x39, 0xc2, 0xdb, 0x0a, 0x8a, 0x12, 0x06, 0xc7, 0x9e, 0x29, 0x54, 0x24, 0x52, 0x3c, 0xaa, 0x1b, 0x71, 0x33, 0x5b, 0x30, 0x86, 0x9a, 0xaf, 0x48, 0x33, 0xf1, 0x4c, 0x5e, 0x18, 0x47, 0xd5, 0x84, 0xd2, 0xf3, 0x1e, 0x62, 0x20, 0x04, 0x42, 0x81, 0x0f, 0x4a, 0xd4, 0x32, 0x60, 0x2a, 0x64, 0x83, 0xb4, 0xa5, 0xab, 0xae, 0x0b, 0xfd, 0xea, 0xb7, 0x84, 0x83, 0x00, 0x14, 0x90, 0x05, 0x62, 0x70, 0x1c, 0x60, 0x06, 0x47, 0xa4, 0xa8, 0x2c, 0x32, 0xd4, 0x27, 0x40, 0x31, 0xfc, 0x09, 0x32, 0xe4, 0x53, 0x30, 0x34, 0x2e, 0x58, 0x65, 0x15, 0x43, 0x11, 0xe2, 0x3f, 0x0f, 0xb1, 0xfd, 0x63, 0x1d, 0x21, 0x53, 0x65, 0x2d, 0x52, 0x8d, 0xc8, 0x81, 0x27, 0xe8, 0x09, 0x79, 0xa4, 0x21, 0xe9, 0x4f, 0xfa, 0x92, 0x31, 0xa8, 0x0f, 0x44, 0xcd, 0x85, 0xf4, 0x22, 0xbd, 0x07, 0xc7, 0xf1, 0x35, 0x07, 0x75, 0xd2, 0xc3, 0xe8, 0xa1, 0xf4, 0x48, 0x7a, 0x38, 0xdd, 0x6e, 0x90, 0x01, 0x21, 0x52, 0x9d, 0x8b, 0x9a, 0x02, 0xa4, 0xff, 0xc2, 0x45, 0x23, 0x9b, 0x18, 0x65, 0xa7, 0x40, 0xbd, 0x6c, 0x30, 0x87, 0xaf, 0xf1, 0x68, 0x4f, 0x68, 0xad, 0xb4, 0x47, 0xb4, 0x1b, 0xb4, 0x36, 0xda, 0x1d, 0x48, 0x86, 0x3f, 0x54, 0x51, 0x06, 0x32, 0x9d, 0x22, 0x5d, 0xa0, 0x18, 0x54, 0x30, 0x14, 0x79, 0x2c, 0xb4, 0xa1, 0x68, 0xfd, 0x55, 0x11, 0xa3, 0x8a, 0xc9, 0xa0, 0x73, 0xd0, 0x87, 0xb4, 0x46, 0xaa, 0xdd, 0xc9, 0x60, 0xd2, 0x0f, 0xe9, 0x47, 0xda, 0x49, 0x1e, 0x69, 0x08, 0x8e, 0xa4, 0x1b, 0xca, 0x24, 0x88, 0x0c, 0x40, 0xb9, 0xb9, 0x23, 0x76, 0xb0, 0x7a, 0x94, 0x6a, 0xe5, 0x90, 0xb6, 0xaf, 0xb5, 0x1c, 0xac, 0xfb, 0xa0, 0x1f, 0xa5, 0x9a, 0xff, 0xb7, 0x1c, 0x07, 0x78, 0x8e, 0x3d, 0xc7, 0x7d, 0x40, 0x45, 0xc6, 0x60, 0x56, 0xe8, 0x4d, 0x0e, 0x56, 0xe2, 0x9f, 0x51, 0xbe, 0x5a, 0xa4, 0x20, 0x42, 0x5e, 0xd1, 0xff, 0xf4, 0x24, 0xbe, 0x27, 0x0e, 0x12, 0x67, 0x89, 0x93, 0xc4, 0x79, 0xe2, 0x28, 0x51, 0x07, 0x7c, 0xe2, 0x04, 0x51, 0x4f, 0x5c, 0x22, 0x8e, 0x51, 0x78, 0x40, 0x73, 0xb8, 0xaa, 0x3a, 0x59, 0x43, 0x4f, 0x8b, 0x57, 0x55, 0x34, 0x07, 0xe5, 0x20, 0x1d, 0xf4, 0x71, 0xaa, 0x71, 0xea, 0x74, 0xfa, 0x34, 0xf8, 0x6b, 0x28, 0x57, 0x01, 0x62, 0x28, 0x05, 0xd4, 0x3b, 0x40, 0xf3, 0xbf, 0x50, 0x3c, 0xbd, 0x10, 0xcd, 0x3f, 0x08, 0x99, 0x2a, 0x9f, 0xa1, 0x90, 0x66, 0x49, 0x0a, 0xf9, 0x41, 0x68, 0x15, 0x16, 0xf3, 0xa3, 0x64, 0xc2, 0x91, 0x23, 0xf8, 0x2e, 0x4e, 0xce, 0x6e, 0x00, 0xd4, 0x9a, 0x4e, 0xf9, 0x00, 0xbc, 0xe6, 0xa9, 0xd6, 0x6a, 0x8c, 0x77, 0xe1, 0x2b, 0x97, 0xdf, 0x08, 0xe0, 0x5d, 0x8a, 0xd6, 0x00, 0x6a, 0x39, 0xe5, 0x53, 0x5e, 0x00, 0x02, 0x0b, 0x80, 0x23, 0x4f, 0x00, 0xb8, 0x6f, 0xbf, 0x72, 0x16, 0xaf, 0xd0, 0x27, 0xb5, 0x1c, 0xe0, 0xd8, 0x15, 0xa1, 0x52, 0x51, 0xd4, 0xef, 0x47, 0x52, 0x37, 0x1a, 0x30, 0xd1, 0x82, 0xa9, 0x8b, 0xfe, 0x31, 0x4c, 0xc0, 0x02, 0x6c, 0x51, 0x4e, 0x2e, 0xe0, 0x01, 0xbe, 0x10, 0x08, 0x61, 0x30, 0x06, 0x62, 0x21, 0x11, 0x52, 0x61, 0x32, 0xaa, 0xba, 0x04, 0xf2, 0x90, 0xea, 0x69, 0x30, 0x0b, 0xe6, 0x43, 0x09, 0x94, 0xc1, 0x72, 0x58, 0x0d, 0xeb, 0x61, 0x33, 0x6c, 0x85, 0x9d, 0xb0, 0x07, 0x0e, 0x40, 0x1d, 0x1c, 0x85, 0x93, 0x70, 0x06, 0x2e, 0xc2, 0x15, 0xb8, 0x01, 0x77, 0xd1, 0xdc, 0x68, 0x87, 0xe7, 0xd0, 0x0d, 0x6f, 0xa1, 0x17, 0xc3, 0x30, 0x06, 0xc6, 0xc6, 0xb8, 0x98, 0x01, 0x66, 0x8a, 0x59, 0x61, 0x0e, 0x98, 0x0b, 0xe6, 0x85, 0xf9, 0x63, 0x61, 0x58, 0x0c, 0x16, 0x8f, 0xa5, 0x62, 0xe9, 0x58, 0x16, 0x26, 0xc3, 0x94, 0xd8, 0x2c, 0x6c, 0x21, 0x56, 0x86, 0x95, 0x63, 0xeb, 0xb1, 0x2d, 0x58, 0x35, 0xf6, 0x33, 0x76, 0x04, 0x3b, 0x89, 0x9d, 0xc7, 0x5a, 0xb1, 0x3b, 0xd8, 0x43, 0xac, 0x13, 0x7b, 0x85, 0x7d, 0xc4, 0x09, 0x9c, 0x85, 0xeb, 0xe2, 0xc6, 0xb8, 0x35, 0x3e, 0x0a, 0xf7, 0xc2, 0x83, 0xf0, 0x68, 0x3c, 0x11, 0x9f, 0x84, 0x67, 0xe1, 0xf9, 0x78, 0x31, 0xbe, 0x08, 0x5f, 0x8a, 0xaf, 0xc5, 0xab, 0xf0, 0xdd, 0x78, 0x2d, 0x7e, 0x12, 0xbf, 0x88, 0xdf, 0xc0, 0xdb, 0xf0, 0xe7, 0x78, 0x0f, 0x01, 0x84, 0x06, 0xc1, 0x23, 0xcc, 0x08, 0x47, 0xc2, 0x8b, 0x08, 0x21, 0x62, 0x89, 0x34, 0x22, 0x93, 0x50, 0x10, 0x73, 0x88, 0x52, 0xa2, 0x82, 0xa8, 0x22, 0xf6, 0x12, 0x0d, 0xe8, 0x5d, 0x5f, 0x23, 0xda, 0x88, 0x2e, 0xe2, 0x03, 0x49, 0x27, 0xb9, 0x24, 0x9f, 0x74, 0x44, 0xf3, 0x33, 0x92, 0x4c, 0x22, 0x85, 0x64, 0x3e, 0x39, 0x87, 0x5c, 0x42, 0xae, 0x27, 0x77, 0x92, 0xb5, 0x64, 0x33, 0x79, 0x8d, 0x7c, 0x48, 0x76, 0x93, 0x5f, 0x68, 0x6c, 0x9a, 0x11, 0xcd, 0x81, 0xe6, 0x43, 0x8b, 0xa2, 0x4d, 0xa0, 0x65, 0xd1, 0xa6, 0xd1, 0x4a, 0x68, 0x15, 0xb4, 0xed, 0xb4, 0xc3, 0xb4, 0xd3, 0xe8, 0xdb, 0x69, 0xa7, 0xbd, 0xa5, 0xd3, 0xe9, 0x3c, 0xba, 0x0d, 0xdd, 0x13, 0x7d, 0x9b, 0xa9, 0xf4, 0x6c, 0xfa, 0x4c, 0xfa, 0x12, 0xfa, 0x46, 0xfa, 0x3e, 0x7a, 0x23, 0xbd, 0x95, 0xfe, 0x98, 0xde, 0xc3, 0x60, 0x30, 0x0c, 0x18, 0x0e, 0x0c, 0x3f, 0x46, 0x2c, 0x43, 0xc0, 0x28, 0x64, 0x94, 0x30, 0xd6, 0x31, 0x76, 0x33, 0x4e, 0x30, 0xae, 0x32, 0xda, 0x19, 0xef, 0xd5, 0x34, 0xd4, 0x4c, 0xd5, 0x5c, 0xd4, 0xc2, 0xd5, 0xd2, 0xd4, 0x64, 0x6a, 0x0b, 0xd4, 0x2a, 0xd4, 0x76, 0xa9, 0x1d, 0x57, 0xbb, 0xaa, 0xf6, 0x54, 0xad, 0x57, 0x5d, 0x4b, 0xdd, 0x4a, 0xdd, 0x47, 0x3d, 0x56, 0x5d, 0xa4, 0x3e, 0x43, 0x7d, 0x99, 0xfa, 0x36, 0xf5, 0x06, 0xf5, 0xcb, 0xea, 0xed, 0xea, 0xbd, 0x4c, 0x6d, 0xa6, 0x0d, 0xd3, 0x8f, 0x99, 0xc8, 0xcc, 0x66, 0xce, 0x67, 0xae, 0x65, 0xee, 0x65, 0x9e, 0x66, 0xde, 0x63, 0xbe, 0xd6, 0xd0, 0xd0, 0x30, 0xd7, 0xf0, 0xd6, 0x18, 0xaf, 0x21, 0xd5, 0x98, 0xa7, 0xb1, 0x56, 0x63, 0xbf, 0xc6, 0x39, 0x8d, 0x87, 0x1a, 0x1f, 0x58, 0x3a, 0x2c, 0x7b, 0x56, 0x08, 0x6b, 0x22, 0x4b, 0xc9, 0x5a, 0xca, 0xda, 0xc1, 0x6a, 0x64, 0xdd, 0x61, 0xbd, 0x66, 0xb3, 0xd9, 0xd6, 0xec, 0x40, 0x76, 0x1a, 0xbb, 0x90, 0xbd, 0x94, 0x5d, 0xcd, 0x3e, 0xc5, 0x7e, 0xc0, 0x7e, 0xcf, 0xe1, 0x72, 0x46, 0x72, 0xa2, 0x38, 0x22, 0xce, 0x5c, 0x4e, 0x25, 0xa7, 0x96, 0x73, 0x95, 0xf3, 0x42, 0x53, 0x5d, 0xd3, 0x4a, 0x33, 0x48, 0x73, 0xb2, 0x66, 0xb1, 0x66, 0x85, 0xe6, 0x41, 0xcd, 0xcb, 0x9a, 0x5d, 0x5a, 0xea, 0x5a, 0xd6, 0x5a, 0x21, 0x5a, 0x02, 0xad, 0x39, 0x5a, 0x95, 0x5a, 0x47, 0xb4, 0x6e, 0x69, 0xf5, 0x68, 0x73, 0xb5, 0x9d, 0xb5, 0x63, 0xb5, 0xf3, 0xb4, 0x97, 0x68, 0xef, 0xd2, 0x3e, 0xaf, 0xdd, 0xa1, 0xc3, 0xd0, 0xb1, 0xd6, 0x09, 0xd3, 0x11, 0xe9, 0x2c, 0xd2, 0xd9, 0xaa, 0x73, 0x4a, 0xe7, 0x31, 0x97, 0xe0, 0x5a, 0x70, 0x43, 0xb8, 0x42, 0xee, 0x42, 0xee, 0x36, 0xee, 0x69, 0x6e, 0xbb, 0x2e, 0x5d, 0xd7, 0x46, 0x37, 0x4a, 0x37, 0x5b, 0xb7, 0x4c, 0x77, 0x8f, 0x6e, 0x8b, 0x6e, 0xb7, 0x9e, 0x8e, 0x9e, 0x9b, 0x5e, 0xb2, 0xde, 0x74, 0xbd, 0x4a, 0xbd, 0x63, 0x7a, 0x6d, 0x3c, 0x82, 0x67, 0xcd, 0x8b, 0xe2, 0xe5, 0xf2, 0x96, 0xf1, 0x0e, 0xf0, 0x6e, 0xf2, 0x3e, 0x0e, 0x33, 0x1e, 0x16, 0x34, 0x4c, 0x3c, 0x6c, 0xf1, 0xb0, 0xbd, 0xc3, 0xae, 0x0e, 0x7b, 0xa7, 0x3f, 0x5c, 0x3f, 0x50, 0x5f, 0xac, 0x5f, 0xaa, 0xbf, 0x4f, 0xff, 0x86, 0xfe, 0x47, 0x03, 0xbe, 0x41, 0x98, 0x41, 0x8e, 0xc1, 0x0a, 0x83, 0x3a, 0x83, 0xfb, 0x86, 0xa4, 0xa1, 0xbd, 0xe1, 0x78, 0xc3, 0x69, 0x86, 0x9b, 0x0c, 0x4f, 0x1b, 0x76, 0x0d, 0xd7, 0x1d, 0xee, 0x3b, 0x5c, 0x38, 0xbc, 0x74, 0xf8, 0x81, 0xe1, 0xbf, 0x19, 0xe1, 0x46, 0xf6, 0x46, 0xf1, 0x46, 0x33, 0x8d, 0xb6, 0x1a, 0x5d, 0x32, 0xea, 0x31, 0x36, 0x31, 0x8e, 0x30, 0x96, 0x1b, 0xaf, 0x33, 0x3e, 0x65, 0xdc, 0x65, 0xc2, 0x33, 0x09, 0x34, 0xc9, 0x36, 0x59, 0x65, 0x72, 0xdc, 0xa4, 0xd3, 0x94, 0x6b, 0xea, 0x6f, 0x2a, 0x35, 0x5d, 0x65, 0x7a, 0xc2, 0xf4, 0x19, 0x5f, 0x8f, 0x1f, 0xc4, 0xcf, 0xe5, 0xaf, 0xe5, 0x37, 0xf3, 0xbb, 0xcd, 0x8c, 0xcc, 0x22, 0xcd, 0x94, 0x66, 0x5b, 0xcc, 0x5a, 0xcc, 0x7a, 0xcd, 0x6d, 0xcc, 0x93, 0xcc, 0x17, 0x98, 0xef, 0x33, 0xbf, 0x6f, 0xc1, 0xb4, 0xf0, 0xb2, 0xc8, 0xb4, 0x58, 0x65, 0xd1, 0x64, 0xd1, 0x6d, 0x69, 0x6a, 0x39, 0xd6, 0x72, 0x96, 0x65, 0x8d, 0xe5, 0x6f, 0x56, 0xea, 0x56, 0x5e, 0x56, 0x12, 0xab, 0x35, 0x56, 0x67, 0xad, 0xde, 0x59, 0xdb, 0x58, 0xa7, 0x58, 0x7f, 0x67, 0x5d, 0x67, 0xdd, 0x61, 0xa3, 0x6f, 0x13, 0x65, 0x53, 0x6c, 0x53, 0x63, 0x73, 0xcf, 0x96, 0x6d, 0x1b, 0x60, 0x9b, 0x6f, 0x5b, 0x65, 0x7b, 0xdd, 0x8e, 0x6e, 0xe7, 0x65, 0x97, 0x63, 0xb7, 0xd1, 0xee, 0x8a, 0x3d, 0x6e, 0xef, 0x6e, 0x2f, 0xb1, 0xaf, 0xb4, 0xbf, 0xec, 0x80, 0x3b, 0x78, 0x38, 0x48, 0x1d, 0x36, 0x3a, 0xb4, 0x8e, 0xa0, 0x8d, 0xf0, 0x1e, 0x21, 0x1b, 0x51, 0x35, 0xe2, 0x96, 0x23, 0xcb, 0x31, 0xc8, 0xb1, 0xc8, 0xb1, 0xc6, 0xf1, 0xe1, 0x48, 0xde, 0xc8, 0x98, 0x91, 0x0b, 0x46, 0xd6, 0x8d, 0x7c, 0x31, 0xca, 0x72, 0x54, 0xda, 0xa8, 0x15, 0xa3, 0xce, 0x8e, 0xfa, 0xe2, 0xe4, 0xee, 0x94, 0xeb, 0xb4, 0xcd, 0xe9, 0xae, 0xb3, 0x8e, 0xf3, 0x18, 0xe7, 0x05, 0xce, 0x0d, 0xce, 0xaf, 0x5c, 0xec, 0x5d, 0x84, 0x2e, 0x95, 0x2e, 0xd7, 0x5d, 0xd9, 0xae, 0xe1, 0xae, 0x73, 0x5d, 0xeb, 0x5d, 0x5f, 0xba, 0x39, 0xb8, 0x89, 0xdd, 0x36, 0xb9, 0xdd, 0x76, 0xe7, 0xba, 0x8f, 0x75, 0xff, 0xce, 0xbd, 0xc9, 0xfd, 0xb3, 0x87, 0xa7, 0x87, 0xc2, 0x63, 0xaf, 0x47, 0xa7, 0xa7, 0xa5, 0x67, 0xba, 0xe7, 0x06, 0xcf, 0x5b, 0x5e, 0xba, 0x5e, 0x71, 0x5e, 0x4b, 0xbc, 0xce, 0x79, 0xd3, 0xbc, 0x83, 0xbd, 0xe7, 0x7a, 0x1f, 0xf5, 0xfe, 0xe0, 0xe3, 0xe1, 0x53, 0xe8, 0x73, 0xc0, 0xe7, 0x2f, 0x5f, 0x47, 0xdf, 0x1c, 0xdf, 0x5d, 0xbe, 0x1d, 0xa3, 0x6d, 0x46, 0x8b, 0x47, 0x6f, 0x1b, 0xfd, 0xd8, 0xcf, 0xdc, 0x4f, 0xe0, 0xb7, 0xc5, 0xaf, 0xcd, 0x9f, 0xef, 0x9f, 0xee, 0xff, 0xa3, 0x7f, 0x5b, 0x80, 0x59, 0x80, 0x20, 0xa0, 0x2a, 0xe0, 0x51, 0xa0, 0x45, 0xa0, 0x28, 0x70, 0x7b, 0xe0, 0xd3, 0x20, 0xbb, 0xa0, 0xec, 0xa0, 0xdd, 0x41, 0x2f, 0x82, 0x9d, 0x82, 0x15, 0xc1, 0x87, 0x83, 0xdf, 0x85, 0xf8, 0x84, 0xcc, 0x0e, 0x69, 0x0c, 0x25, 0x42, 0x23, 0x42, 0x4b, 0x43, 0x5b, 0xc2, 0x74, 0xc2, 0x92, 0xc2, 0xd6, 0x87, 0x3d, 0x08, 0x37, 0x0f, 0xcf, 0x0a, 0xaf, 0x09, 0xef, 0x8e, 0x70, 0x8f, 0x98, 0x19, 0xd1, 0x18, 0x49, 0x8b, 0x8c, 0x8e, 0x5c, 0x11, 0x79, 0x2b, 0xca, 0x38, 0x4a, 0x18, 0x55, 0x1d, 0xd5, 0x3d, 0xc6, 0x73, 0xcc, 0xec, 0x31, 0xcd, 0xd1, 0xac, 0xe8, 0x84, 0xe8, 0xf5, 0xd1, 0x8f, 0x62, 0xec, 0x63, 0x14, 0x31, 0x0d, 0x63, 0xf1, 0xb1, 0x63, 0xc6, 0xae, 0x1c, 0x7b, 0x6f, 0x9c, 0xd5, 0x38, 0xd9, 0xb8, 0xba, 0x58, 0x88, 0x8d, 0x8a, 0x5d, 0x19, 0x7b, 0x3f, 0xce, 0x26, 0x2e, 0x3f, 0xee, 0x97, 0xf1, 0xf4, 0xf1, 0x71, 0xe3, 0x2b, 0xc7, 0x3f, 0x89, 0x77, 0x8e, 0x9f, 0x15, 0x7f, 0x36, 0x81, 0x9b, 0x30, 0x25, 0x61, 0x57, 0xc2, 0xdb, 0xc4, 0xe0, 0xc4, 0x65, 0x89, 0x77, 0x93, 0x6c, 0x93, 0x94, 0x49, 0x4d, 0xc9, 0x9a, 0xc9, 0x13, 0x93, 0xab, 0x93, 0xdf, 0xa5, 0x84, 0xa6, 0x94, 0xa7, 0xb4, 0x4d, 0x18, 0x35, 0x61, 0xf6, 0x84, 0x8b, 0xa9, 0x86, 0xa9, 0xd2, 0xd4, 0xfa, 0x34, 0x46, 0x5a, 0x72, 0xda, 0xf6, 0xb4, 0x9e, 0x6f, 0xc2, 0xbe, 0x59, 0xfd, 0x4d, 0xfb, 0x44, 0xf7, 0x89, 0x25, 0x13, 0x6f, 0x4e, 0xb2, 0x99, 0x34, 0x7d, 0xd2, 0xf9, 0xc9, 0x86, 0x93, 0x73, 0x27, 0x1f, 0x9b, 0xa2, 0x39, 0x45, 0x30, 0xe5, 0x60, 0x3a, 0x2d, 0x3d, 0x25, 0x7d, 0x57, 0xfa, 0x27, 0x41, 0xac, 0xa0, 0x4a, 0xd0, 0x93, 0x11, 0x95, 0xb1, 0x21, 0xa3, 0x5b, 0x18, 0x22, 0x5c, 0x23, 0x7c, 0x2e, 0x0a, 0x14, 0xad, 0x12, 0x75, 0x8a, 0xfd, 0xc4, 0xe5, 0xe2, 0xa7, 0x99, 0x7e, 0x99, 0xe5, 0x99, 0x1d, 0x59, 0x7e, 0x59, 0x2b, 0xb3, 0x3a, 0x25, 0x01, 0x92, 0x0a, 0x49, 0x97, 0x34, 0x44, 0xba, 0x5e, 0xfa, 0x32, 0x3b, 0x32, 0x7b, 0x73, 0xf6, 0xbb, 0x9c, 0xd8, 0x9c, 0x1d, 0x39, 0x7d, 0xb9, 0x29, 0xb9, 0xfb, 0xf2, 0xd4, 0xf2, 0xd2, 0xf3, 0x8e, 0xc8, 0x74, 0x64, 0x39, 0xb2, 0xe6, 0xa9, 0x26, 0x53, 0xa7, 0x4f, 0x6d, 0x95, 0x3b, 0xc8, 0x4b, 0xe4, 0x6d, 0xf9, 0x3e, 0xf9, 0xab, 0xf3, 0xbb, 0x15, 0xd1, 0x8a, 0xed, 0x05, 0x58, 0xc1, 0xa4, 0x82, 0xfa, 0x42, 0x5d, 0xb4, 0x79, 0xbe, 0xa4, 0xb4, 0x55, 0x7e, 0xab, 0x7c, 0x58, 0xe4, 0x5f, 0x54, 0x59, 0xf4, 0x7e, 0x5a, 0xf2, 0xb4, 0x83, 0xd3, 0xb5, 0xa7, 0xcb, 0xa6, 0x5f, 0x9a, 0x61, 0x3f, 0x63, 0xf1, 0x8c, 0xa7, 0xc5, 0xe1, 0xc5, 0x3f, 0xcd, 0x24, 0x67, 0x0a, 0x67, 0x36, 0xcd, 0x32, 0x9b, 0x35, 0x7f, 0xd6, 0xc3, 0xd9, 0x41, 0xb3, 0xb7, 0xcc, 0xc1, 0xe6, 0x64, 0xcc, 0x69, 0x9a, 0x6b, 0x31, 0x77, 0xd1, 0xdc, 0xf6, 0x79, 0x11, 0xf3, 0x76, 0xce, 0x67, 0xce, 0xcf, 0x99, 0xff, 0xeb, 0x02, 0xa7, 0x05, 0xe5, 0x0b, 0xde, 0x2c, 0x4c, 0x59, 0xd8, 0xb0, 0xc8, 0x78, 0xd1, 0xbc, 0x45, 0x8f, 0xbf, 0x8d, 0xf8, 0xb6, 0xa6, 0x84, 0x53, 0xa2, 0x28, 0xb9, 0xf5, 0x9d, 0xef, 0x77, 0x9b, 0xbf, 0x27, 0xbf, 0x97, 0x7e, 0xdf, 0xb2, 0xd8, 0x75, 0xf1, 0xba, 0xc5, 0x5f, 0x4a, 0x45, 0xa5, 0x17, 0xca, 0x9c, 0xca, 0x2a, 0xca, 0x3e, 0x2d, 0x11, 0x2e, 0xb9, 0xf0, 0x83, 0xf3, 0x0f, 0x6b, 0x7f, 0xe8, 0x5b, 0x9a, 0xb9, 0xb4, 0x65, 0x99, 0xc7, 0xb2, 0x4d, 0xcb, 0xe9, 0xcb, 0x65, 0xcb, 0x6f, 0xae, 0x08, 0x58, 0xb1, 0xb3, 0x5c, 0xbb, 0xbc, 0xb8, 0xfc, 0xf1, 0xca, 0xb1, 0x2b, 0x6b, 0x57, 0xf1, 0x57, 0x95, 0xae, 0x7a, 0xb3, 0x7a, 0xca, 0xea, 0xf3, 0x15, 0x6e, 0x15, 0x9b, 0xd7, 0x30, 0xd7, 0x28, 0xd7, 0xb4, 0xad, 0x8d, 0x59, 0x5b, 0xbf, 0xce, 0x72, 0xdd, 0xf2, 0x75, 0x9f, 0xd6, 0x4b, 0xd6, 0xdf, 0xa8, 0x0c, 0xae, 0xdc, 0xb7, 0xc1, 0x68, 0xc3, 0xe2, 0x0d, 0xef, 0x36, 0x8a, 0x36, 0x5e, 0xdd, 0x14, 0xb8, 0x69, 0xef, 0x66, 0xe3, 0xcd, 0x65, 0x9b, 0x3f, 0xfe, 0x28, 0xfd, 0xf1, 0xf6, 0x96, 0x88, 0x2d, 0xb5, 0x55, 0xd6, 0x55, 0x15, 0x5b, 0xe9, 0x5b, 0x8b, 0xb6, 0x3e, 0xd9, 0x96, 0xbc, 0xed, 0xec, 0x4f, 0x5e, 0x3f, 0x55, 0x6f, 0x37, 0xdc, 0x5e, 0xb6, 0xfd, 0xf3, 0x0e, 0xd9, 0x8e, 0xb6, 0x9d, 0xf1, 0x3b, 0x9b, 0xab, 0x3d, 0xab, 0xab, 0x77, 0x19, 0xed, 0x5a, 0x56, 0x83, 0xd7, 0x28, 0x6b, 0x3a, 0x77, 0x4f, 0xdc, 0x7d, 0x65, 0x4f, 0xe8, 0x9e, 0xfa, 0xbd, 0x8e, 0x7b, 0xb7, 0xec, 0xe3, 0xed, 0x2b, 0xdb, 0x0f, 0xfb, 0x95, 0xfb, 0x9f, 0xfd, 0x9c, 0xfe, 0xf3, 0xcd, 0x03, 0xd1, 0x07, 0x9a, 0x0e, 0x7a, 0x1d, 0xdc, 0x7b, 0xc8, 0xea, 0xd0, 0x86, 0xc3, 0xdc, 0xc3, 0xa5, 0xb5, 0x58, 0xed, 0x8c, 0xda, 0xee, 0x3a, 0x49, 0x5d, 0x5b, 0x7d, 0x6a, 0x7d, 0xeb, 0x91, 0x31, 0x47, 0x9a, 0x1a, 0x7c, 0x1b, 0x0e, 0xff, 0x32, 0xf2, 0x97, 0x1d, 0x47, 0xcd, 0x8e, 0x56, 0x1e, 0xd3, 0x3b, 0xb6, 0xec, 0x38, 0xf3, 0xf8, 0xa2, 0xe3, 0x7d, 0x27, 0x8a, 0x4f, 0xf4, 0x34, 0xca, 0x1b, 0xbb, 0x4e, 0x66, 0x9d, 0x7c, 0xdc, 0x34, 0xa5, 0xe9, 0xee, 0xa9, 0x09, 0xa7, 0xae, 0x37, 0x8f, 0x6f, 0x6e, 0x39, 0x1d, 0x7d, 0xfa, 0xdc, 0x99, 0xf0, 0x33, 0xa7, 0xce, 0x06, 0x9d, 0x3d, 0x71, 0xce, 0xef, 0xdc, 0xd1, 0xf3, 0x3e, 0xe7, 0x8f, 0x5c, 0xf0, 0xba, 0x50, 0x77, 0xd1, 0xe3, 0x62, 0xed, 0x25, 0xf7, 0x4b, 0x87, 0x7f, 0x75, 0xff, 0xf5, 0x70, 0x8b, 0x47, 0x4b, 0xed, 0x65, 0xcf, 0xcb, 0xf5, 0x57, 0xbc, 0xaf, 0x34, 0xb4, 0x8e, 0x6e, 0x3d, 0x7e, 0x35, 0xe0, 0xea, 0xc9, 0x6b, 0xa1, 0xd7, 0xce, 0x5c, 0x8f, 0xba, 0x7e, 0xf1, 0xc6, 0xb8, 0x1b, 0xad, 0x37, 0x93, 0x6e, 0xde, 0xbe, 0x35, 0xf1, 0x56, 0xdb, 0x6d, 0xd1, 0xed, 0x8e, 0x3b, 0xb9, 0x77, 0x5e, 0xfe, 0x56, 0xf4, 0x5b, 0xef, 0xdd, 0x79, 0xf7, 0x68, 0xf7, 0x4a, 0xef, 0x6b, 0xdd, 0xaf, 0x78, 0x60, 0xf4, 0xa0, 0xea, 0x77, 0xbb, 0xdf, 0xf7, 0xb5, 0x79, 0xb4, 0x1d, 0x7b, 0x18, 0xfa, 0xf0, 0xd2, 0xa3, 0x84, 0x47, 0x77, 0x1f, 0x0b, 0x1f, 0x3f, 0xff, 0xa3, 0xe0, 0x8f, 0x4f, 0xed, 0x8b, 0x9e, 0xb0, 0x9f, 0x54, 0x3c, 0x35, 0x7d, 0x5a, 0xdd, 0xe1, 0xd2, 0x71, 0xb4, 0x33, 0xbc, 0xf3, 0xca, 0xb3, 0x6f, 0x9e, 0xb5, 0x3f, 0x97, 0x3f, 0xef, 0xed, 0x2a, 0xf9, 0x53, 0xfb, 0xcf, 0x0d, 0x2f, 0x6c, 0x5f, 0x1c, 0xfa, 0x2b, 0xf0, 0xaf, 0x4b, 0xdd, 0x13, 0xba, 0xdb, 0x5f, 0x2a, 0x5e, 0xf6, 0xbd, 0x5a, 0xf2, 0xda, 0xe0, 0xf5, 0x8e, 0x37, 0x6e, 0x6f, 0x9a, 0x7a, 0xe2, 0x7a, 0x1e, 0xbc, 0xcd, 0x7b, 0xdb, 0xfb, 0xae, 0xf4, 0xbd, 0xc1, 0xfb, 0x9d, 0x1f, 0xbc, 0x3e, 0x9c, 0xfd, 0x98, 0xf2, 0xf1, 0x69, 0xef, 0xb4, 0x4f, 0x8c, 0x4f, 0x6b, 0x3f, 0xdb, 0x7d, 0x6e, 0xf8, 0x12, 0xfd, 0xe5, 0x5e, 0x5f, 0x5e, 0x5f, 0x9f, 0x5c, 0xa0, 0x10, 0xa8, 0xf6, 0x02, 0x04, 0xea, 0xf1, 0xcc, 0x4c, 0x80, 0x57, 0x3b, 0x00, 0xd8, 0xa9, 0x68, 0xef, 0x70, 0x05, 0x80, 0xc9, 0xe9, 0x3f, 0x73, 0xa9, 0x3c, 0xb0, 0xfe, 0x73, 0x22, 0xc2, 0xd8, 0x40, 0xa3, 0xe8, 0x7f, 0xe0, 0xfe, 0x73, 0x19, 0x65, 0x40, 0x7b, 0x08, 0xd8, 0x11, 0x08, 0x90, 0x34, 0x0f, 0x20, 0xa6, 0x11, 0x60, 0x13, 0x6a, 0x56, 0x08, 0xb3, 0xd0, 0x9d, 0xda, 0x7e, 0x27, 0x06, 0x02, 0xee, 0xea, 0x3a, 0xd4, 0x10, 0x43, 0x5d, 0x05, 0x99, 0xae, 0x2e, 0x2a, 0x80, 0xb1, 0x14, 0x68, 0x6b, 0xf2, 0xbe, 0xaf, 0xef, 0xb5, 0x31, 0x00, 0xa3, 0x01, 0xe0, 0xb3, 0xa2, 0xaf, 0xaf, 0x77, 0x63, 0x5f, 0xdf, 0xe7, 0x6d, 0x68, 0xaf, 0x7e, 0x07, 0xa0, 0x31, 0xbf, 0xff, 0xac, 0x47, 0x79, 0x53, 0x67, 0xc8, 0x1f, 0xd1, 0x7e, 0x1e, 0xe0, 0x7c, 0xcb, 0x92, 0x79, 0xd4, 0xfd, 0xef, 0xd7, 0xff, 0x00, 0x53, 0x9d, 0x6a, 0xc0, 0x3e, 0x1f, 0x78, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01, 0x49, 0x52, 0x24, 0xf0, 0x00, 0x00, 0x01, 0x9c, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x39, 0x30, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc1, 0xe2, 0xd2, 0xc6, 0x00, 0x00, 0x02, 0x01, 0x49, 0x44, 0x41, 0x54, 0x48, 0x0d, 0xbd, 0x96, 0xcf, 0x2b, 0x05, 0x51, 0x14, 0xc7, 0x1f, 0x3d, 0xf2, 0x33, 0x0b, 0x85, 0x52, 0xb6, 0x42, 0xc4, 0x42, 0xd6, 0x96, 0x8a, 0x12, 0x0b, 0xca, 0x1f, 0x41, 0x42, 0xb1, 0x61, 0x85, 0x35, 0x29, 0x85, 0x94, 0x8d, 0x62, 0x69, 0x23, 0x24, 0x29, 0x65, 0x4b, 0x51, 0x16, 0x44, 0x84, 0x2c, 0x94, 0x84, 0xfc, 0xf6, 0x39, 0xf5, 0x4e, 0x6e, 0xd3, 0x1b, 0xef, 0xde, 0x37, 0x33, 0x4e, 0x7d, 0x3b, 0x77, 0xe6, 0x9e, 0x73, 0x3e, 0x77, 0xee, 0xcc, 0xdc, 0x7b, 0x63, 0xb1, 0x58, 0x6c, 0x0a, 0x55, 0xa1, 0x7f, 0xb1, 0xcc, 0x04, 0xe5, 0x10, 0x3f, 0x8d, 0x8a, 0xff, 0x83, 0xda, 0x02, 0xe4, 0x3b, 0xa1, 0x7b, 0x7c, 0x1f, 0xca, 0x42, 0x91, 0x59, 0x2e, 0x95, 0x5f, 0x90, 0x42, 0xc5, 0x9f, 0xa0, 0x36, 0x14, 0x99, 0xad, 0x53, 0xd9, 0x04, 0x6a, 0x7b, 0x8b, 0xfb, 0xb5, 0x51, 0x50, 0x7b, 0x7d, 0x80, 0x02, 0xfe, 0x40, 0xb3, 0xa8, 0x04, 0x85, 0x66, 0x95, 0x54, 0xd2, 0xa7, 0xf2, 0xf3, 0x0f, 0xc4, 0x0c, 0xa2, 0xec, 0xb0, 0xa8, 0x67, 0x16, 0x50, 0x19, 0xcc, 0x29, 0xea, 0x08, 0x03, 0x3a, 0x63, 0x09, 0xd4, 0x19, 0xd8, 0x21, 0xbe, 0x21, 0x08, 0x58, 0xbe, 0x4a, 0x2d, 0x66, 0xeb, 0x3f, 0xc9, 0x59, 0x40, 0x65, 0xe9, 0x80, 0xf3, 0x49, 0x7a, 0x45, 0xb6, 0x30, 0x33, 0xee, 0x91, 0xbc, 0x11, 0x94, 0x83, 0x9c, 0x6c, 0x93, 0x68, 0xb3, 0x90, 0x6b, 0xfb, 0x9c, 0xfc, 0x2e, 0x17, 0x62, 0x7f, 0x40, 0xa0, 0x0e, 0x70, 0x8f, 0x3a, 0x8d, 0x36, 0xe0, 0xea, 0x90, 0x80, 0x02, 0xfe, 0x42, 0x4b, 0xa8, 0x1c, 0xfd, 0x69, 0x17, 0xf4, 0xea, 0x48, 0xc3, 0xf0, 0x4f, 0xd4, 0x1b, 0x45, 0x79, 0x7e, 0x54, 0x59, 0x55, 0xc2, 0x00, 0x79, 0x6b, 0x5c, 0x52, 0xb7, 0x47, 0xb7, 0x27, 0x13, 0x2e, 0xeb, 0x6a, 0x14, 0x56, 0x44, 0xd1, 0xe7, 0x64, 0x85, 0x0b, 0xb9, 0xf9, 0x86, 0xbc, 0x23, 0x0c, 0x72, 0x7d, 0x4c, 0x3d, 0x59, 0x3e, 0x7d, 0x6d, 0x9b, 0x9e, 0x20, 0x00, 0x33, 0x77, 0x95, 0x5a, 0x05, 0xbe, 0xa4, 0x44, 0xc7, 0x50, 0x08, 0x40, 0xd9, 0x65, 0x64, 0xb1, 0xb7, 0x32, 0xd9, 0x03, 0xcd, 0x51, 0xba, 0xb6, 0xef, 0xc8, 0x6f, 0xb6, 0x22, 0x19, 0x41, 0x57, 0x69, 0x42, 0xe5, 0xf4, 0x50, 0x63, 0xd4, 0xb1, 0x6e, 0xce, 0xa7, 0x09, 0x94, 0xd9, 0x90, 0x6f, 0xc0, 0xf9, 0x5c, 0xd4, 0x19, 0x00, 0x28, 0xd0, 0x39, 0xe4, 0x64, 0xf2, 0xdf, 0xbc, 0x23, 0xd7, 0xf7, 0x67, 0xc6, 0xcb, 0xda, 0xec, 0x64, 0xbb, 0x44, 0x9b, 0x05, 0xbc, 0xed, 0x0d, 0xfa, 0xff, 0xda, 0xb8, 0x65, 0xbf, 0x6c, 0x75, 0x21, 0x0e, 0xfb, 0x00, 0x65, 0x61, 0x1e, 0x47, 0xb2, 0x52, 0x89, 0xd6, 0x90, 0x77, 0x30, 0x7a, 0x2d, 0x7b, 0x65, 0x1d, 0xb2, 0xb2, 0x7a, 0xa2, 0x34, 0x51, 0xbd, 0x1c, 0xa6, 0xda, 0x3d, 0xd9, 0xf2, 0x63, 0x1f, 0x24, 0x89, 0xd5, 0x1c, 0xd9, 0x10, 0x4a, 0x3d, 0x39, 0x49, 0x2f, 0x33, 0xb8, 0x7b, 0x8d, 0x34, 0xf1, 0x88, 0xb6, 0xdf, 0x12, 0x55, 0x41, 0xdf, 0xad, 0x11, 0xab, 0x39, 0xea, 0xf7, 0xe9, 0xb3, 0x3a, 0x11, 0x2c, 0x26, 0x8a, 0xac, 0xe0, 0x53, 0x2d, 0x51, 0x4d, 0xc4, 0xc8, 0x7f, 0xa8, 0x10, 0xaf, 0x9f, 0xa0, 0x2f, 0xa5, 0xc9, 0x91, 0x70, 0x20, 0x65, 0xd4, 0x6f, 0x40, 0x37, 0x4d, 0x2f, 0x48, 0xaf, 0x6f, 0x7e, 0xc3, 0xc2, 0x6d, 0x8d, 0xf9, 0x40, 0x65, 0xca, 0x23, 0x31, 0x79, 0xf7, 0xcb, 0x48, 0x9f, 0x4c, 0xbd, 0xd5, 0x94, 0xa6, 0x3b, 0xa2, 0x38, 0x89, 0x93, 0x48, 0x9e, 0x4a, 0xa6, 0x52, 0x60, 0xf1, 0x1f, 0x65, 0x5c, 0x9e, 0x8b, 0x0f, 0xbf, 0xa0, 0x23, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXJSONIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x32, 0x3a, 0x32, 0x33, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x03, 0x64, 0xa2, 0xe8, 0x00, 0x00, 0x06, 0x37, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x7b, 0x48, 0x57, 0x57, 0x1c, 0x3f, 0xc7, 0x47, 0x3e, 0xf2, 0x31, 0xc9, 0x50, 0xdb, 0x56, 0x13, 0x73, 0x59, 0x3e, 0x57, 0x46, 0x66, 0xe2, 0x28, 0x1b, 0x51, 0x6a, 0x2a, 0xb1, 0xcd, 0x6a, 0x43, 0xaa, 0x8d, 0x06, 0xe5, 0xa0, 0xac, 0x86, 0x8c, 0xcd, 0xbf, 0x4c, 0xb3, 0x65, 0x81, 0xb4, 0xd2, 0xa6, 0x11, 0xe8, 0x60, 0xb4, 0x2d, 0x96, 0x2e, 0xb6, 0x08, 0x35, 0x62, 0x15, 0x3e, 0x96, 0xda, 0x16, 0xe1, 0x7c, 0xe2, 0x62, 0x51, 0x12, 0xe5, 0x2f, 0xcd, 0xf7, 0xdd, 0xe7, 0xfe, 0xce, 0xe5, 0x78, 0xfb, 0xa9, 0xf7, 0xfe, 0x7e, 0xbf, 0x7b, 0xf6, 0x08, 0x7e, 0x87, 0xb8, 0x7c, 0xcf, 0xf7, 0x7c, 0xce, 0xf7, 0x7d, 0xbe, 0xe7, 0xf4, 0x93, 0x4a, 0x92, 0x44, 0x5e, 0xe4, 0xe1, 0xf4, 0x22, 0x1b, 0x2f, 0xdb, 0xee, 0x70, 0xe0, 0xbf, 0xce, 0xa0, 0x23, 0x03, 0x8e, 0x0c, 0x18, 0x8c, 0x80, 0xa3, 0x84, 0x0c, 0x06, 0xd0, 0xf0, 0x76, 0x17, 0xc3, 0x12, 0x14, 0x01, 0xb5, 0xbf, 0x93, 0xeb, 0x7f, 0x48, 0xa3, 0xe3, 0xf2, 0x34, 0x29, 0x9c, 0xbe, 0xb9, 0xd4, 0x52, 0xf0, 0xe7, 0xdf, 0x2a, 0x37, 0x66, 0xd0, 0x4b, 0xf4, 0x9d, 0x38, 0x32, 0xcf, 0xcb, 0x12, 0x60, 0xdf, 0x5c, 0x8c, 0x03, 0x39, 0x55, 0x52, 0x45, 0xfd, 0xd4, 0x8d, 0xee, 0xe5, 0x3e, 0x83, 0x03, 0x25, 0x3f, 0x73, 0x80, 0xf4, 0xc5, 0x8f, 0xf4, 0xa7, 0x4f, 0x68, 0x68, 0xa0, 0x7d, 0x36, 0x3f, 0xb7, 0x4b, 0xc0, 0x19, 0x68, 0xe8, 0x24, 0x6a, 0xeb, 0x9f, 0x13, 0x3f, 0xcb, 0xe4, 0xd1, 0x53, 0x29, 0xf7, 0x1b, 0xee, 0xcf, 0x2c, 0x20, 0xeb, 0xd8, 0x02, 0x32, 0x00, 0x07, 0xf8, 0x28, 0xc8, 0x74, 0x7a, 0x2b, 0x82, 0xcc, 0xf3, 0xe6, 0x8c, 0x29, 0xe2, 0xd7, 0xc3, 0x4e, 0x4f, 0x86, 0xc8, 0xc7, 0xe7, 0xa4, 0xdb, 0x7d, 0xb2, 0xe9, 0x0d, 0x1d, 0x53, 0x4b, 0x46, 0x28, 0x01, 0x0e, 0x98, 0x9e, 0x29, 0xb1, 0xf4, 0xf5, 0xa4, 0x1f, 0x25, 0xcd, 0x6a, 0x4c, 0xf0, 0x7c, 0x79, 0x69, 0x6b, 0x3c, 0xbd, 0x6d, 0x8e, 0xbd, 0x69, 0x18, 0xbb, 0xe8, 0xac, 0x68, 0xab, 0x17, 0x04, 0x94, 0x10, 0xd7, 0xe5, 0x31, 0x87, 0x93, 0xb3, 0x12, 0xee, 0xae, 0xb3, 0x2e, 0xd9, 0xb7, 0x20, 0xd2, 0x01, 0xfb, 0x2c, 0x30, 0xb8, 0xcb, 0xe1, 0x00, 0x21, 0x8f, 0x06, 0x95, 0x20, 0xba, 0x3a, 0xeb, 0x47, 0x53, 0x8d, 0x79, 0x3c, 0xa4, 0x8f, 0xd7, 0x45, 0x18, 0xcd, 0xc0, 0xfd, 0x27, 0xa4, 0xe6, 0x96, 0xa2, 0x65, 0x49, 0x90, 0xae, 0x3a, 0xb2, 0x64, 0xc1, 0x14, 0xa6, 0xac, 0x76, 0x8a, 0xb6, 0x9b, 0x32, 0xe4, 0x40, 0xf1, 0x25, 0xb2, 0xea, 0x33, 0xe9, 0xfe, 0x63, 0xb9, 0x0b, 0x79, 0xcc, 0xa1, 0x39, 0xc9, 0xfa, 0x5d, 0x25, 0x36, 0x98, 0x6c, 0x8c, 0x56, 0x60, 0x05, 0x3f, 0x4c, 0xae, 0xcb, 0x97, 0x7a, 0xfb, 0xed, 0x36, 0x5e, 0xde, 0x68, 0xc8, 0x81, 0xe6, 0x6e, 0x69, 0xc0, 0xdc, 0x43, 0xfd, 0xbd, 0x69, 0xd9, 0x07, 0x34, 0x6e, 0xb1, 0xbe, 0x29, 0x94, 0x92, 0xb2, 0x0f, 0xe9, 0xa6, 0x18, 0xc5, 0x87, 0x5b, 0x3d, 0xd2, 0xa3, 0xa7, 0xfa, 0xbb, 0x34, 0x10, 0x86, 0x1c, 0x48, 0x8f, 0xa5, 0xe1, 0xaf, 0xc8, 0xa6, 0xf4, 0x9b, 0xa4, 0xf7, 0xbf, 0x9c, 0xfc, 0xae, 0x41, 0x43, 0x91, 0xb2, 0x34, 0x3c, 0x46, 0x36, 0x16, 0x4a, 0x97, 0x5a, 0xe4, 0xa4, 0xb9, 0xb9, 0xd2, 0xf7, 0x12, 0xe8, 0x02, 0x3f, 0xfd, 0x5d, 0x1a, 0x08, 0x43, 0x0e, 0xbc, 0xbd, 0x8a, 0xd4, 0x7e, 0x4a, 0x23, 0x5f, 0x55, 0xc2, 0x79, 0xa6, 0x4e, 0xb9, 0xd1, 0x34, 0xf4, 0x5d, 0x6f, 0x27, 0xbf, 0xfd, 0xa9, 0xc0, 0x4a, 0x77, 0xd1, 0x92, 0x2c, 0x1a, 0xe0, 0xab, 0x01, 0xd7, 0x5f, 0x32, 0xe4, 0x00, 0xc4, 0xcf, 0x71, 0x21, 0x49, 0x11, 0x8a, 0x1a, 0x6b, 0xaa, 0x59, 0x8d, 0xd9, 0x14, 0xa3, 0x6f, 0x9f, 0x2e, 0xc2, 0xa8, 0x03, 0xb2, 0x0f, 0x56, 0x74, 0xcf, 0x19, 0xed, 0x50, 0xb7, 0xd4, 0x19, 0x01, 0xd6, 0x30, 0x05, 0x38, 0x60, 0x8d, 0x9a, 0x7f, 0x0e, 0xe3, 0x70, 0x40, 0x15, 0x5b, 0xd3, 0x33, 0x32, 0xa9, 0x77, 0x8c, 0x85, 0xdc, 0xbe, 0x2a, 0x9d, 0x44, 0xc0, 0x73, 0x7a, 0xbe, 0x0f, 0xba, 0x90, 0x6c, 0xf8, 0xe0, 0x88, 0x94, 0x7d, 0x8e, 0xac, 0x5b, 0x86, 0xde, 0x4a, 0xc2, 0x54, 0x37, 0x2e, 0xd3, 0xf7, 0x7d, 0x23, 0x19, 0x78, 0x46, 0xca, 0x6a, 0x15, 0x17, 0xcd, 0xbb, 0xd4, 0x96, 0xd8, 0x49, 0x0b, 0x70, 0x20, 0x71, 0x29, 0x71, 0x71, 0xa6, 0xe3, 0x13, 0xb2, 0x65, 0x5f, 0xff, 0x22, 0xe1, 0x5f, 0x6e, 0x9a, 0xd3, 0x74, 0x07, 0x76, 0x95, 0x4d, 0xaa, 0x6d, 0x4c, 0x0a, 0x57, 0xcf, 0xec, 0xa7, 0x05, 0x9c, 0x81, 0xd7, 0x03, 0x49, 0xd1, 0x56, 0x8a, 0x5b, 0xc9, 0x7a, 0x2b, 0xde, 0x78, 0x8d, 0x1e, 0x7e, 0xd7, 0x06, 0xbc, 0x86, 0x64, 0x2a, 0xea, 0xe7, 0xf5, 0xbf, 0x1e, 0x93, 0xe6, 0x6e, 0xc2, 0x7e, 0x95, 0x58, 0xf6, 0xf2, 0x0c, 0x25, 0x74, 0xa1, 0x49, 0x31, 0x03, 0x37, 0xd7, 0xea, 0xc5, 0x04, 0x6f, 0x0a, 0x21, 0x43, 0x98, 0x03, 0x42, 0xac, 0xb1, 0x43, 0x88, 0x80, 0x12, 0xb2, 0x43, 0xab, 0xc0, 0x2d, 0x0e, 0x07, 0x04, 0x06, 0xd3, 0x2e, 0x51, 0x8e, 0x0c, 0xd8, 0x15, 0x36, 0x81, 0x9b, 0x6c, 0xcb, 0xc0, 0x57, 0xe6, 0x21, 0x50, 0xbd, 0x71, 0x51, 0x36, 0xb4, 0xd1, 0x91, 0x91, 0x11, 0x4f, 0x4f, 0x4f, 0x67, 0x67, 0xe7, 0xa1, 0xa1, 0x21, 0x17, 0x17, 0x01, 0x57, 0xb8, 0x71, 0xeb, 0x21, 0xc1, 0x36, 0x3b, 0x7c, 0x7d, 0x7d, 0x3d, 0x3c, 0x3c, 0xfe, 0x3f, 0xd6, 0xc3, 0x01, 0x1b, 0x32, 0x00, 0xf4, 0xe4, 0xa4, 0xfc, 0x9e, 0x71, 0x72, 0xd2, 0x2f, 0x3c, 0x20, 0xad, 0x81, 0x41, 0x9a, 0xc1, 0xa1, 0x6f, 0xca, 0xb5, 0x6b, 0xd7, 0xd6, 0xae, 0x5d, 0xbb, 0xca, 0x3c, 0x56, 0x9b, 0xc7, 0xb1, 0x63, 0xc7, 0x2c, 0xb4, 0x56, 0x57, 0x57, 0x67, 0x65, 0x65, 0x05, 0x04, 0x04, 0xa0, 0xc6, 0x56, 0xae, 0x5c, 0x19, 0x15, 0x15, 0xb5, 0x79, 0xf3, 0x66, 0x35, 0xe6, 0xde, 0xbd, 0x7b, 0x3b, 0x76, 0xec, 0x08, 0x0b, 0x0b, 0xf3, 0xf2, 0xf2, 0x8a, 0x89, 0x89, 0x39, 0x74, 0xe8, 0xd0, 0xe0, 0xa0, 0xf2, 0x7b, 0xd8, 0xd9, 0xb3, 0x67, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xea, 0xeb, 0xeb, 0x33, 0x33, 0x33, 0xfd, 0xfc, 0xfc, 0x16, 0x2e, 0x5c, 0x58, 0x5a, 0x5a, 0xaa, 0xde, 0xae, 0x45, 0xe3, 0x2d, 0xa4, 0x3d, 0xf2, 0xf3, 0xf3, 0x2d, 0xf6, 0x6f, 0xdb, 0xb6, 0x4d, 0xbd, 0xe5, 0xca, 0x95, 0x2b, 0x0c, 0xb0, 0x61, 0xc3, 0x86, 0xf5, 0xeb, 0xd7, 0x53, 0xf3, 0x2b, 0x07, 0xb6, 0x72, 0x4c, 0x73, 0x73, 0xb3, 0x8f, 0x8f, 0x8f, 0x85, 0x90, 0xe0, 0xe0, 0xe0, 0xfe, 0xfe, 0x7e, 0x60, 0x52, 0x52, 0x52, 0xd8, 0x12, 0x4c, 0xe7, 0x18, 0x08, 0xb9, 0x73, 0xe7, 0x0e, 0x97, 0xa0, 0x41, 0x10, 0x8d, 0x35, 0xb6, 0x84, 0x23, 0x7b, 0xf9, 0xf2, 0xe5, 0x0b, 0xe6, 0xb1, 0x65, 0xcb, 0x16, 0xe8, 0xb0, 0x70, 0xe0, 0xe0, 0xc1, 0x83, 0x60, 0x86, 0x87, 0x87, 0x33, 0x7c, 0x77, 0x77, 0xf7, 0xce, 0x9d, 0x3b, 0x91, 0x10, 0x36, 0x1d, 0x1b, 0x1b, 0x8b, 0x88, 0x90, 0xff, 0xdb, 0x1f, 0x14, 0x14, 0x74, 0xf2, 0xe4, 0xc9, 0x8e, 0x8e, 0x8e, 0xbc, 0xbc, 0x3c, 0x1c, 0x24, 0x2e, 0xe7, 0xc1, 0x83, 0x07, 0xc8, 0x2b, 0xa6, 0xee, 0xee, 0xee, 0xe5, 0xe5, 0xe5, 0xc8, 0x83, 0xbf, 0xbf, 0x3f, 0xa6, 0x47, 0x8f, 0x1e, 0x65, 0x12, 0xb4, 0xbf, 0xfa, 0x0e, 0xa8, 0xf7, 0xe7, 0xe6, 0xe6, 0x72, 0xc5, 0x9c, 0x7f, 0xfe, 0xfc, 0x79, 0x30, 0x31, 0x50, 0x39, 0xd9, 0xd9, 0xd9, 0x15, 0x15, 0x15, 0x5d, 0x5d, 0x5d, 0x7c, 0xb5, 0xad, 0xad, 0x8d, 0xad, 0x16, 0x17, 0x17, 0x73, 0xe6, 0xf6, 0xed, 0xdb, 0xc1, 0x84, 0xc5, 0xe3, 0xe3, 0xe3, 0x60, 0x66, 0x64, 0x64, 0x60, 0x9a, 0x9c, 0x9c, 0xcc, 0x00, 0xa9, 0xa9, 0xa9, 0x98, 0xee, 0xdb, 0xb7, 0x8f, 0xe3, 0x35, 0x08, 0xfd, 0x33, 0xc0, 0xd4, 0x6b, 0x7c, 0xd3, 0xd3, 0xd3, 0x13, 0x12, 0x12, 0x00, 0x80, 0xad, 0x25, 0x25, 0x25, 0x08, 0x7f, 0x48, 0x48, 0xc8, 0x9e, 0x3d, 0x7b, 0xd8, 0x96, 0xbb, 0x77, 0xef, 0x32, 0x22, 0x2d, 0x2d, 0x8d, 0x0b, 0x61, 0xf4, 0xf0, 0xf0, 0x70, 0x4f, 0x4f, 0x0f, 0x67, 0xae, 0x58, 0xb1, 0x82, 0xd1, 0x8b, 0x16, 0x2d, 0x02, 0x81, 0x55, 0xbe, 0xa4, 0x41, 0x08, 0x70, 0x00, 0x5d, 0x15, 0x35, 0xd6, 0xda, 0xda, 0x8a, 0xa3, 0x99, 0x98, 0x98, 0xe8, 0xea, 0xea, 0x8a, 0x80, 0x9d, 0x3a, 0x75, 0x0a, 0xb5, 0x04, 0xc5, 0xa8, 0x1c, 0xa6, 0xbe, 0xb1, 0xb1, 0x91, 0xdb, 0xc1, 0x68, 0x14, 0x7a, 0x60, 0xe0, 0xd4, 0x1f, 0xfa, 0x78, 0xd7, 0x62, 0xa7, 0x88, 0x83, 0xb5, 0x09, 0x01, 0x0e, 0xa0, 0x36, 0xd0, 0x37, 0x70, 0x54, 0x8e, 0x1c, 0x39, 0x72, 0xf5, 0xea, 0xd5, 0xce, 0xce, 0x4e, 0xd4, 0x06, 0x7c, 0xa8, 0xab, 0xab, 0x83, 0x6e, 0xd4, 0x95, 0xb7, 0xb7, 0xfc, 0x37, 0x33, 0x24, 0xa7, 0xaf, 0xaf, 0x0f, 0x44, 0x4b, 0x4b, 0x4b, 0x55, 0x55, 0x15, 0x08, 0xb4, 0xa3, 0xb9, 0x73, 0xe7, 0x82, 0x00, 0x18, 0x5f, 0xd6, 0xa3, 0x39, 0xc1, 0x98, 0x98, 0xea, 0x0c, 0xe0, 0xac, 0x1f, 0x33, 0x9e, 0x81, 0xbd, 0x7b, 0xf7, 0x42, 0x87, 0x9b, 0x9b, 0x1b, 0xaa, 0xb6, 0xb2, 0xb2, 0xf2, 0xc0, 0x81, 0x03, 0x98, 0x22, 0x9c, 0xa8, 0x28, 0x26, 0xf9, 0xf4, 0xe9, 0xd3, 0xcc, 0x08, 0xe4, 0x2a, 0x3a, 0x3a, 0x9a, 0xd1, 0xb8, 0xd1, 0x6f, 0xdc, 0xb8, 0x01, 0xc0, 0xfe, 0xfd, 0xfb, 0x39, 0x07, 0x87, 0xb8, 0xa8, 0xa8, 0x88, 0xa5, 0x02, 0x79, 0x28, 0x2c, 0x2c, 0xd4, 0xb5, 0xcd, 0xb6, 0x9b, 0x78, 0xc6, 0xba, 0x44, 0x8b, 0x84, 0x32, 0x18, 0x77, 0xfc, 0xf8, 0x71, 0x66, 0x0a, 0xda, 0x48, 0x41, 0x41, 0x41, 0x64, 0x64, 0x24, 0x9b, 0xee, 0xde, 0xbd, 0x1b, 0x18, 0x38, 0xdf, 0xdb, 0xdb, 0x8b, 0x4a, 0x03, 0x13, 0xe5, 0x7e, 0xe2, 0xc4, 0x09, 0xf4, 0x7e, 0xd0, 0xf0, 0x04, 0x63, 0x62, 0x62, 0x02, 0xb5, 0x07, 0x39, 0xb0, 0x1e, 0xa2, 0x46, 0x47, 0x47, 0xf1, 0xb5, 0xaa, 0x96, 0x74, 0x5d, 0x54, 0x03, 0x58, 0xbb, 0xc8, 0xc9, 0xc9, 0x51, 0x33, 0x4d, 0x26, 0x13, 0x9a, 0x23, 0xfa, 0x49, 0x7b, 0x7b, 0xfb, 0xcd, 0x9b, 0x37, 0xf1, 0xc5, 0xab, 0x49, 0x0d, 0xe0, 0xf4, 0xc3, 0x87, 0x0f, 0x91, 0x96, 0x81, 0x81, 0x01, 0xce, 0x31, 0x4e, 0xe8, 0x67, 0xe0, 0xe2, 0xc5, 0x8b, 0x4d, 0x4d, 0x4d, 0xb8, 0x65, 0x1b, 0x1a, 0x1a, 0x6a, 0x6a, 0x6a, 0x10, 0xb3, 0x35, 0x6b, 0xd6, 0xb0, 0xd0, 0xb2, 0x2f, 0x2e, 0x57, 0x0c, 0xd0, 0xa1, 0xa1, 0xa1, 0x6a, 0xfe, 0x74, 0x1a, 0x99, 0xc1, 0x98, 0xce, 0x37, 0xc4, 0xd1, 0x8d, 0x81, 0xc5, 0xa3, 0x80, 0xdf, 0x50, 0xba, 0x1b, 0xff, 0x1d, 0x80, 0xfe, 0x63, 0x0e, 0x37, 0x25, 0xfa, 0x09, 0x1a, 0x36, 0xae, 0xfa, 0xd8, 0xd8, 0xd8, 0xe5, 0xcb, 0x97, 0x1b, 0x0a, 0x98, 0xe8, 0xcd, 0xfa, 0x0e, 0x88, 0xd6, 0x28, 0x58, 0x9e, 0x80, 0x7b, 0x40, 0xb0, 0x45, 0x36, 0x8a, 0x73, 0x38, 0x60, 0x63, 0xc0, 0x84, 0xc3, 0x1d, 0x19, 0x10, 0x1e, 0x52, 0x1b, 0x05, 0x3a, 0x32, 0x60, 0x63, 0xc0, 0x84, 0xc3, 0x5f, 0xf8, 0x0c, 0xfc, 0x0d, 0x80, 0x98, 0xbd, 0xed, 0xf7, 0x50, 0xda, 0x08, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXTextPlainIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x32, 0x3a, 0x34, 0x33, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x04, 0xa5, 0xd6, 0xff, 0x00, 0x00, 0x05, 0x7b, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x5b, 0x48, 0x23, 0x57, 0x18, 0xce, 0x24, 0x31, 0xf1, 0x52, 0xad, 0x31, 0x78, 0xdf, 0xd6, 0x2a, 0xb6, 0x52, 0xad, 0x28, 0x8a, 0xe8, 0x82, 0x62, 0xe9, 0x45, 0xa5, 0x45, 0xf0, 0x82, 0x58, 0x41, 0xb4, 0xed, 0x83, 0x0f, 0xe2, 0x83, 0x6f, 0x8a, 0x20, 0xb8, 0x3e, 0x28, 0x05, 0x45, 0x7d, 0x12, 0x84, 0x82, 0x8a, 0x88, 0x22, 0x0a, 0xbe, 0x54, 0xb4, 0xc2, 0x3e, 0xe9, 0x82, 0x37, 0x50, 0x1a, 0x45, 0x2a, 0x5e, 0x8a, 0xdd, 0x20, 0x58, 0x35, 0xb1, 0x8a, 0x49, 0x4c, 0xd2, 0x2f, 0x7b, 0xe2, 0x38, 0x3b, 0xc6, 0x89, 0x33, 0x39, 0xac, 0x2b, 0x9d, 0xf3, 0x30, 0xfc, 0xe7, 0xfc, 0xdf, 0x7f, 0xff, 0xcf, 0x3f, 0x93, 0x30, 0x4e, 0xa7, 0x53, 0xf1, 0x94, 0x97, 0xf2, 0x29, 0x3b, 0xef, 0xf2, 0x5d, 0x0e, 0xe0, 0xb1, 0x2b, 0x28, 0x57, 0x40, 0xae, 0x80, 0x8f, 0x19, 0x90, 0x5b, 0xc8, 0xc7, 0x04, 0xfa, 0x2c, 0x2e, 0x57, 0xc0, 0xe7, 0x14, 0xfa, 0xa8, 0x40, 0xae, 0x80, 0x8f, 0x09, 0xf4, 0x59, 0x5c, 0xed, 0xb3, 0x06, 0x97, 0x02, 0xa7, 0x43, 0xf1, 0x7a, 0xc3, 0x61, 0x32, 0x3a, 0x9d, 0x0e, 0x2f, 0x9f, 0x86, 0x8c, 0x92, 0xf9, 0x30, 0x86, 0x89, 0x49, 0x55, 0x32, 0x94, 0x6a, 0x4f, 0x27, 0x80, 0xfd, 0x57, 0xf6, 0xdf, 0x5e, 0x58, 0x1e, 0x9e, 0x8b, 0xef, 0x5e, 0x68, 0xe3, 0x9f, 0xab, 0x1e, 0x8e, 0x17, 0x40, 0xd2, 0xc9, 0x83, 0xf9, 0xc8, 0x4b, 0xe2, 0x79, 0x1e, 0x98, 0x8d, 0xe2, 0xf0, 0x3c, 0x71, 0xee, 0x96, 0x4e, 0x05, 0x6c, 0x57, 0x6e, 0x9d, 0xfe, 0x21, 0x4c, 0xa0, 0x8e, 0xc1, 0xc6, 0xf2, 0xaf, 0xf3, 0xe2, 0x1f, 0xb7, 0x97, 0x41, 0x7a, 0xa5, 0xf6, 0x03, 0x17, 0xe0, 0xf2, 0xd4, 0x79, 0x65, 0x76, 0x1d, 0x5e, 0x8b, 0xa8, 0x96, 0x4b, 0x50, 0x60, 0xd1, 0x09, 0xc0, 0x6e, 0x71, 0xfb, 0xfa, 0xc5, 0xf7, 0xea, 0xec, 0x9f, 0xfc, 0x60, 0x6f, 0x73, 0xc6, 0xfe, 0xb2, 0xc7, 0xed, 0x66, 0xf6, 0x8f, 0x7e, 0x9f, 0x17, 0xba, 0x1a, 0xe6, 0xd5, 0xaf, 0xb6, 0xb5, 0x71, 0x1b, 0x88, 0xeb, 0x1b, 0xbc, 0x80, 0x67, 0x0f, 0x64, 0xd1, 0x69, 0xa1, 0x6b, 0xab, 0xdb, 0x9c, 0x4a, 0xe3, 0x4a, 0xff, 0x7d, 0x4b, 0xe5, 0x0a, 0xcd, 0xb5, 0xec, 0x37, 0x78, 0xb2, 0xf5, 0xe5, 0x49, 0x29, 0x80, 0x9b, 0x96, 0x60, 0x5d, 0xf4, 0xe8, 0x93, 0x5a, 0xeb, 0x0e, 0x8f, 0x0d, 0xd8, 0x23, 0x4c, 0xd4, 0x21, 0x9d, 0x00, 0x74, 0x1f, 0xb9, 0x3d, 0x0b, 0x89, 0x12, 0xaa, 0x80, 0x3e, 0xc1, 0x6d, 0x2e, 0xf4, 0x99, 0x10, 0x4c, 0x54, 0x00, 0x74, 0xee, 0x40, 0xd2, 0x37, 0x6a, 0xcb, 0x85, 0x42, 0xa9, 0x52, 0x7c, 0x22, 0x38, 0x1c, 0x9f, 0xa5, 0x29, 0x9f, 0xff, 0xac, 0xb9, 0xb6, 0x3a, 0x93, 0xbe, 0xa6, 0x63, 0x17, 0xa1, 0xd2, 0x51, 0xa4, 0x0d, 0x56, 0x64, 0x55, 0x7b, 0x57, 0xa5, 0xd2, 0x28, 0x32, 0x7e, 0xf0, 0x0e, 0x13, 0x55, 0x01, 0x3a, 0x2d, 0x24, 0xca, 0x24, 0x5d, 0xb0, 0x1c, 0x00, 0xdd, 0x7c, 0x8a, 0xd7, 0xf6, 0xe4, 0x2b, 0x40, 0xf9, 0x4a, 0x59, 0xce, 0x15, 0x27, 0x7f, 0x39, 0x90, 0x47, 0xd3, 0x6b, 0xd7, 0x93, 0x2c, 0xd3, 0xdf, 0x0e, 0xa3, 0x81, 0xc1, 0xe0, 0xd4, 0x7d, 0xac, 0xc4, 0x75, 0xa7, 0xbb, 0x18, 0x8a, 0xff, 0x8d, 0xfe, 0xf9, 0xd2, 0xfe, 0xfb, 0x2f, 0x56, 0x81, 0x2f, 0x6a, 0x7c, 0x4b, 0x7f, 0xdb, 0xac, 0xf9, 0xf4, 0x4b, 0x3a, 0xdf, 0xa1, 0x24, 0x11, 0x34, 0x5b, 0xc8, 0x68, 0x70, 0x08, 0x78, 0x0f, 0x7b, 0xe0, 0x1a, 0xff, 0xb8, 0xad, 0x0c, 0x95, 0x52, 0xd0, 0x0c, 0xe0, 0xb3, 0xaf, 0x54, 0xfa, 0x78, 0x21, 0x85, 0xe0, 0x02, 0x43, 0xc5, 0x6f, 0x56, 0x09, 0xcd, 0x16, 0x62, 0x95, 0xbe, 0x4b, 0x42, 0x28, 0x61, 0xef, 0xd2, 0x0f, 0xc9, 0xb6, 0xe4, 0x00, 0x24, 0xa7, 0x8e, 0x92, 0xa0, 0x5c, 0x01, 0x4a, 0x89, 0x94, 0xac, 0xe6, 0xff, 0x5d, 0x81, 0xeb, 0x37, 0xcb, 0xe1, 0x90, 0xfe, 0x6e, 0x5a, 0x5d, 0x5d, 0x6d, 0x6f, 0x6f, 0x3f, 0x3a, 0x3a, 0x92, 0x5c, 0x01, 0x05, 0x3e, 0x25, 0x24, 0xac, 0x9d, 0x9d, 0x9d, 0xb0, 0xb0, 0x30, 0x62, 0x35, 0x34, 0x34, 0x54, 0x82, 0x06, 0x22, 0x52, 0x55, 0x55, 0x05, 0x25, 0xc3, 0xc3, 0xc3, 0x92, 0x35, 0x48, 0x6c, 0xa1, 0xe0, 0xe0, 0xe0, 0xa4, 0xa4, 0xa4, 0x98, 0x98, 0x18, 0x98, 0xbf, 0xb8, 0xb8, 0x90, 0x9c, 0x3f, 0xe8, 0x51, 0xa9, 0x54, 0x91, 0x91, 0x91, 0x92, 0x35, 0x48, 0xac, 0x00, 0x49, 0xd8, 0xca, 0xca, 0x0a, 0x0c, 0xfb, 0xf9, 0xf9, 0x09, 0xe7, 0x0f, 0x3d, 0x26, 0x00, 0xb0, 0x5a, 0xad, 0x02, 0x5c, 0xaf, 0x2c, 0x0f, 0x15, 0x68, 0x6d, 0x6d, 0xcd, 0xce, 0xce, 0x2e, 0x28, 0x28, 0x58, 0x5a, 0x5a, 0xca, 0xc9, 0xc9, 0x09, 0x0c, 0x0c, 0x4c, 0x4d, 0x4d, 0xed, 0xea, 0xea, 0x12, 0xd5, 0xeb, 0x5b, 0x5b, 0x5b, 0xb5, 0xb5, 0xb5, 0x59, 0x59, 0x59, 0xc8, 0x31, 0x34, 0xa4, 0xa7, 0xa7, 0x4f, 0x4f, 0x4f, 0x73, 0xd3, 0x3c, 0x37, 0x37, 0x97, 0x9f, 0x9f, 0x0f, 0x43, 0xb9, 0xb9, 0xb9, 0xbd, 0xbd, 0xbd, 0x5c, 0xd6, 0xe9, 0xe9, 0x69, 0x49, 0x49, 0x09, 0x58, 0xf5, 0xf5, 0xf5, 0x93, 0x93, 0x93, 0xb0, 0x1e, 0x14, 0x14, 0x54, 0x54, 0x54, 0x64, 0x34, 0x1a, 0xb9, 0x30, 0x37, 0x7d, 0x37, 0xc4, 0xf8, 0xf8, 0x78, 0xc2, 0x83, 0x18, 0x57, 0xa0, 0xba, 0xba, 0x9a, 0x07, 0x16, 0xa8, 0x00, 0x22, 0x87, 0x2c, 0xc3, 0x30, 0x88, 0x21, 0x22, 0x22, 0x02, 0xb4, 0x56, 0xab, 0xdd, 0xdf, 0xdf, 0x67, 0x35, 0x34, 0x37, 0x37, 0xb3, 0xca, 0x11, 0x2a, 0x7b, 0x0e, 0x82, 0xa8, 0x05, 0x17, 0xc1, 0xab, 0xd5, 0xb7, 0xbf, 0x58, 0x2a, 0x2b, 0x2b, 0xb9, 0x30, 0x42, 0x7b, 0x68, 0xa1, 0xdd, 0xdd, 0x5d, 0xd2, 0x94, 0x3a, 0x9d, 0x6e, 0x60, 0x60, 0x60, 0x63, 0x63, 0xa3, 0xb4, 0xb4, 0x94, 0x18, 0x9b, 0x9f, 0x9f, 0xe7, 0xaa, 0x10, 0x08, 0x60, 0x6a, 0x6a, 0xaa, 0xbb, 0xbb, 0xfb, 0xf0, 0xf0, 0x10, 0x78, 0x8b, 0xc5, 0x42, 0x62, 0xe0, 0x5e, 0xd6, 0xf3, 0xf3, 0xf3, 0x99, 0x99, 0x19, 0xa2, 0x99, 0x17, 0x00, 0x44, 0x46, 0x46, 0x46, 0x88, 0xc5, 0xc2, 0xc2, 0x42, 0x58, 0xa9, 0xab, 0xab, 0xc3, 0x16, 0x09, 0xe5, 0x5a, 0x27, 0xb4, 0x87, 0x00, 0xc0, 0x48, 0x48, 0x48, 0x80, 0x00, 0x2a, 0x48, 0x40, 0xc7, 0xc7, 0xc7, 0xb8, 0x6a, 0x38, 0x69, 0x6a, 0x6a, 0xe2, 0xaa, 0x10, 0x08, 0x00, 0x30, 0x44, 0xdb, 0xd1, 0xd1, 0xd1, 0xd8, 0xd8, 0xd8, 0xd6, 0xd6, 0x96, 0x96, 0x96, 0x06, 0xf1, 0xce, 0xce, 0x4e, 0xae, 0x38, 0x68, 0x28, 0xc4, 0xf9, 0xdd, 0x00, 0xd6, 0xd7, 0xd7, 0x71, 0x8e, 0xb5, 0xbc, 0xbc, 0x0c, 0x18, 0xa6, 0x2d, 0xd9, 0x9a, 0x4c, 0x26, 0x9e, 0x86, 0xdb, 0x02, 0x11, 0x04, 0xf7, 0x89, 0x1e, 0x25, 0x5b, 0xbd, 0x5e, 0x9f, 0x92, 0x92, 0x82, 0x52, 0x20, 0xa3, 0x5c, 0xc0, 0x7d, 0xb4, 0xcd, 0x66, 0x2b, 0x2e, 0x2e, 0x9e, 0x9d, 0x9d, 0x05, 0x40, 0xa3, 0xd1, 0xa0, 0x91, 0x50, 0x04, 0xd0, 0x76, 0xbb, 0xfd, 0x3e, 0x91, 0xfb, 0xce, 0x33, 0x33, 0x33, 0xc1, 0x8a, 0x8b, 0x8b, 0x23, 0x80, 0xab, 0xab, 0xab, 0x90, 0x90, 0x10, 0x2e, 0xd8, 0xc3, 0x25, 0x66, 0xd9, 0x0b, 0x0b, 0x0b, 0x84, 0xc6, 0xad, 0xda, 0xdc, 0xdc, 0x04, 0xcd, 0x5e, 0x0f, 0x16, 0xe3, 0x91, 0x40, 0x03, 0x10, 0xef, 0x27, 0x26, 0x26, 0x90, 0xb3, 0xcb, 0xcb, 0xcb, 0xb2, 0xb2, 0x32, 0x8f, 0x48, 0xaf, 0x87, 0x08, 0x1e, 0x18, 0xf2, 0xf4, 0x08, 0x16, 0x0a, 0x60, 0x74, 0x74, 0x74, 0x6c, 0x6c, 0x6c, 0x6f, 0x6f, 0xaf, 0xa1, 0xa1, 0x01, 0xef, 0x5c, 0xc8, 0xa3, 0x23, 0x59, 0x2d, 0x38, 0x61, 0x33, 0xca, 0xa5, 0x01, 0xc0, 0x08, 0xc2, 0x33, 0x3c, 0x3c, 0x1c, 0x2d, 0xee, 0xef, 0xef, 0x8f, 0x41, 0x79, 0x72, 0x72, 0x82, 0x13, 0x54, 0x9f, 0x15, 0x07, 0x0d, 0x29, 0x32, 0xd9, 0xb8, 0x34, 0x01, 0xb0, 0x48, 0x42, 0xb0, 0x03, 0x90, 0x3d, 0x67, 0xf5, 0x08, 0xdd, 0x81, 0x5b, 0xd0, 0x1b, 0xaa, 0xa6, 0xa6, 0x06, 0xf2, 0x58, 0x66, 0xb3, 0x39, 0x36, 0x36, 0x96, 0xc7, 0xc5, 0x16, 0x93, 0x97, 0x00, 0x06, 0x07, 0x07, 0x09, 0x37, 0x23, 0x23, 0xa3, 0xa2, 0xa2, 0x82, 0x05, 0xe3, 0x8d, 0x31, 0x34, 0x34, 0x04, 0x0c, 0x2a, 0x13, 0x10, 0x10, 0xc0, 0xd3, 0x80, 0x66, 0xeb, 0xef, 0xef, 0x07, 0xf7, 0xe0, 0xe0, 0x00, 0xf3, 0x83, 0x70, 0x13, 0x13, 0x13, 0xcf, 0xce, 0xce, 0xa2, 0xa3, 0xa3, 0xc9, 0x16, 0xd3, 0x05, 0xd6, 0x89, 0x15, 0xf2, 0x14, 0xaa, 0x40, 0x4b, 0x4b, 0x4b, 0x5e, 0x5e, 0x5e, 0x54, 0x54, 0x14, 0x66, 0x62, 0x4f, 0x4f, 0x0f, 0xeb, 0x16, 0x74, 0x91, 0x3b, 0xcd, 0xf3, 0x80, 0x2d, 0x34, 0x06, 0x2e, 0x8a, 0x86, 0xc9, 0xb3, 0xb6, 0xb6, 0x06, 0x5f, 0xd1, 0xc1, 0x7d, 0x7d, 0x7d, 0xe8, 0x5d, 0x48, 0x91, 0x4a, 0x42, 0x50, 0xa9, 0xe4, 0x9b, 0x66, 0xc5, 0xc1, 0x45, 0x30, 0x44, 0x39, 0x86, 0x2f, 0xd2, 0xcf, 0xdd, 0xc2, 0xef, 0xb7, 0xec, 0x72, 0xa3, 0x61, 0x69, 0x32, 0x85, 0x16, 0x17, 0x17, 0xd9, 0x13, 0x09, 0x04, 0x1a, 0xcc, 0x60, 0x30, 0xdc, 0x9d, 0x1b, 0x12, 0x54, 0x09, 0x88, 0xf0, 0xa7, 0x10, 0xec, 0xe1, 0xe5, 0x87, 0x27, 0xa2, 0x1c, 0x1f, 0x1f, 0xdf, 0xde, 0xde, 0x2e, 0x2f, 0x2f, 0xc7, 0x0b, 0xe5, 0xad, 0xa0, 0x1f, 0xb6, 0x41, 0x8e, 0x93, 0x93, 0x93, 0x1f, 0x86, 0xf5, 0x01, 0xc5, 0x0b, 0x0e, 0x6f, 0x2e, 0x9e, 0x32, 0x74, 0x0e, 0x0f, 0xf3, 0x5e, 0x6d, 0xf9, 0x15, 0xc0, 0x47, 0x08, 0xbe, 0x2e, 0xf1, 0x9a, 0x24, 0x61, 0xa0, 0x71, 0x31, 0xd1, 0x79, 0x21, 0xbd, 0x57, 0x5b, 0xf9, 0x7f, 0xa1, 0xc7, 0x2e, 0x07, 0x7f, 0x96, 0x3d, 0xb6, 0x3f, 0xa2, 0xed, 0xcb, 0x01, 0x88, 0x4e, 0x19, 0x65, 0x01, 0xb9, 0x02, 0x94, 0x13, 0x2a, 0x5a, 0x9d, 0x5c, 0x01, 0xd1, 0x29, 0xa3, 0x2c, 0xf0, 0x1f, 0x15, 0xdc, 0xd7, 0x70, 0xbb, 0x15, 0xe8, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXHTMLIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, 0x32, 0x33, 0x3a, 0x30, 0x32, 0x3a, 0x39, 0x35, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x3c, 0x50, 0x22, 0x3f, 0x00, 0x00, 0x05, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x6b, 0x4c, 0x5b, 0x55, 0x1c, 0xa7, 0xa5, 0xe5, 0xe5, 0x78, 0xb5, 0x94, 0xf2, 0x4a, 0x00, 0x91, 0x47, 0xd8, 0x32, 0x51, 0x24, 0x7c, 0x70, 0x20, 0xf2, 0x34, 0x31, 0x13, 0x1f, 0x0c, 0x30, 0x2c, 0xbc, 0x24, 0xca, 0xc6, 0x07, 0x1e, 0x09, 0x1f, 0xf8, 0x60, 0x42, 0x4c, 0xd0, 0x84, 0x98, 0x98, 0xf1, 0xc5, 0x69, 0x54, 0x60, 0x3a, 0x82, 0x3a, 0x5d, 0x98, 0x24, 0xdb, 0x88, 0x01, 0x24, 0x3a, 0x32, 0xca, 0x63, 0x4c, 0x26, 0x8f, 0x05, 0x48, 0x86, 0x06, 0x28, 0x14, 0x4a, 0x5b, 0x1e, 0x85, 0xb6, 0xf8, 0x83, 0xa3, 0xd7, 0x6b, 0xcb, 0x6e, 0x6f, 0x7b, 0xe9, 0x08, 0xc9, 0x3d, 0x69, 0x2e, 0xff, 0xf3, 0x3b, 0xff, 0xf7, 0xff, 0x7f, 0xce, 0x69, 0x2f, 0x82, 0xdd, 0xdd, 0x5d, 0xa7, 0xe3, 0x3c, 0x84, 0xc7, 0xd9, 0xf9, 0x3d, 0xdf, 0xf9, 0x00, 0x8e, 0xba, 0x82, 0x7c, 0x05, 0xf8, 0x0a, 0x70, 0xcc, 0x00, 0xdf, 0x42, 0x1c, 0x13, 0xc8, 0x59, 0x9c, 0xaf, 0x00, 0xe7, 0x14, 0x72, 0x54, 0xc0, 0x57, 0x80, 0x63, 0x02, 0x39, 0x8b, 0xf3, 0x15, 0x38, 0x28, 0x85, 0xab, 0x86, 0x15, 0x4b, 0x78, 0xdd, 0xa4, 0x33, 0x39, 0x99, 0x2c, 0x71, 0x8e, 0xc8, 0x21, 0x57, 0xe0, 0xc1, 0xc6, 0x68, 0xed, 0xec, 0xc5, 0x94, 0xfb, 0xcf, 0x5b, 0xba, 0x35, 0xa0, 0xbd, 0x93, 0x3c, 0xfa, 0xec, 0x67, 0x0b, 0x97, 0x34, 0x46, 0xb5, 0xe5, 0xaa, 0xdd, 0x88, 0xe0, 0x50, 0x7e, 0x0f, 0x20, 0xb5, 0xb7, 0x57, 0x7f, 0x6a, 0x5e, 0xb8, 0xac, 0xd0, 0xf6, 0xc3, 0x15, 0x57, 0xa1, 0xdb, 0xc4, 0x0b, 0x0b, 0x66, 0x3e, 0xf5, 0xac, 0x75, 0x95, 0x4e, 0xe6, 0x02, 0x74, 0x77, 0xf6, 0x78, 0x53, 0x9a, 0x57, 0x1c, 0x50, 0xfe, 0x8c, 0x5b, 0xb4, 0x19, 0x8f, 0x1d, 0x53, 0x91, 0x1d, 0x32, 0x74, 0x91, 0x35, 0xa3, 0xba, 0x7d, 0xa9, 0xf5, 0xeb, 0xc5, 0x2f, 0xfe, 0xd2, 0xcf, 0xd1, 0x71, 0x06, 0x7a, 0xd3, 0xb8, 0x71, 0x55, 0xd9, 0x8c, 0xcf, 0x19, 0xef, 0x94, 0x12, 0xf9, 0x85, 0x54, 0x9f, 0x2c, 0x06, 0x66, 0xab, 0x4b, 0xf6, 0x07, 0xf0, 0x70, 0x73, 0xa2, 0x65, 0xf1, 0xf2, 0x75, 0xd5, 0x77, 0x70, 0x88, 0x6e, 0xc6, 0xdf, 0x25, 0xe0, 0x9c, 0x5f, 0x01, 0x1d, 0x21, 0x74, 0x8c, 0xfb, 0xc9, 0x37, 0xfc, 0xf2, 0x6e, 0xae, 0xdc, 0xd8, 0x32, 0x6d, 0x12, 0xe4, 0xd7, 0xb5, 0x5e, 0x7c, 0xc2, 0xdc, 0x9e, 0x2e, 0x94, 0xbf, 0x7b, 0x4e, 0x56, 0x70, 0x42, 0xe8, 0x69, 0x29, 0x65, 0x15, 0xb1, 0xb9, 0x85, 0x76, 0x9d, 0x76, 0x7b, 0xd4, 0x5d, 0xcd, 0x8b, 0x9f, 0xc2, 0x36, 0x5d, 0xbb, 0x58, 0x28, 0x4e, 0xf5, 0x79, 0x25, 0xd7, 0xef, 0x7c, 0x8a, 0x4f, 0x86, 0xf0, 0xf1, 0xbf, 0x93, 0xb4, 0xc6, 0xb5, 0x0e, 0xd5, 0xb5, 0xf6, 0xa5, 0x2b, 0x0f, 0xd6, 0x47, 0xe9, 0xe2, 0x27, 0x9c, 0x3d, 0x11, 0x43, 0x91, 0xfc, 0xbd, 0x50, 0xd7, 0x70, 0x3a, 0x6e, 0x95, 0xb6, 0x39, 0x80, 0xe2, 0xa9, 0x9c, 0x5f, 0xd4, 0x3f, 0xd3, 0xf5, 0x46, 0x7b, 0xc4, 0xe6, 0xca, 0xce, 0xbf, 0x2e, 0xcd, 0x93, 0x88, 0xa4, 0x74, 0x9c, 0x99, 0xfe, 0x63, 0xe3, 0x3e, 0xc2, 0x40, 0x30, 0x1a, 0xc3, 0x7f, 0x7b, 0x5a, 0x20, 0x10, 0x7c, 0x14, 0x76, 0x29, 0x4f, 0x56, 0xc8, 0x2c, 0x4b, 0x5f, 0xb5, 0xf9, 0x14, 0x5a, 0x35, 0xa8, 0x28, 0xf9, 0x2c, 0xc9, 0xd9, 0x8e, 0x93, 0x3d, 0xb7, 0x4e, 0xdd, 0x29, 0x95, 0x5f, 0xb4, 0xc9, 0x7b, 0x68, 0x88, 0xf5, 0x38, 0xfd, 0x41, 0xe8, 0xc7, 0x03, 0xcf, 0x4d, 0x7c, 0x12, 0xf1, 0x79, 0xb8, 0x5b, 0x04, 0xd1, 0x89, 0x13, 0x45, 0x65, 0x58, 0xa6, 0xf4, 0xb3, 0x21, 0xec, 0xdf, 0x03, 0xd0, 0xde, 0xad, 0xbe, 0x85, 0x6e, 0x79, 0xdb, 0xbf, 0x38, 0xc9, 0xeb, 0x65, 0x36, 0xc6, 0xcc, 0x78, 0xf4, 0xbb, 0x5b, 0x9d, 0xaa, 0xeb, 0xdf, 0x2e, 0x5d, 0x99, 0xdd, 0x9a, 0x36, 0x5b, 0x62, 0x3f, 0xb5, 0x39, 0x80, 0x7c, 0x59, 0x91, 0x6a, 0x67, 0x99, 0x9c, 0x39, 0x3b, 0xa6, 0x9d, 0x9b, 0x2b, 0x1d, 0xf8, 0x84, 0xb8, 0x86, 0xe6, 0xcb, 0x0a, 0xd1, 0xc4, 0xfe, 0xe2, 0x00, 0x36, 0xb6, 0xff, 0xed, 0x9f, 0xef, 0x35, 0x86, 0x35, 0x3a, 0x7f, 0xa2, 0xd7, 0x8b, 0x67, 0x6c, 0xcc, 0x85, 0xcd, 0x7b, 0x00, 0xf6, 0xcc, 0x4e, 0x7d, 0xca, 0x03, 0x91, 0x40, 0x84, 0x33, 0x31, 0xdf, 0xbf, 0xe8, 0x25, 0xef, 0xf4, 0x03, 0xf7, 0xb1, 0xce, 0xa4, 0xbd, 0xa1, 0xfa, 0xa1, 0x5d, 0xd9, 0xf2, 0xfb, 0xfa, 0x3d, 0x4a, 0x0a, 0x84, 0x8b, 0xd0, 0xe5, 0x35, 0x69, 0x4e, 0x89, 0xbc, 0x1c, 0x7d, 0x45, 0xc7, 0xd9, 0xd0, 0xf6, 0x04, 0x40, 0xe9, 0x1d, 0xdb, 0xb8, 0x87, 0xcb, 0xab, 0x73, 0xe5, 0xc7, 0x6d, 0xd3, 0x36, 0x05, 0x82, 0x08, 0x75, 0x0b, 0xef, 0x3d, 0x3d, 0x42, 0x47, 0x40, 0x8f, 0xe8, 0x14, 0x05, 0x93, 0xd9, 0x66, 0x67, 0xae, 0x4c, 0xec, 0x5f, 0x20, 0x7f, 0xa7, 0xc0, 0xbf, 0xd4, 0x4f, 0x24, 0x33, 0xe3, 0x67, 0x39, 0xe5, 0x14, 0x00, 0xb1, 0xb1, 0xbc, 0xa3, 0xbc, 0xaa, 0xfc, 0xea, 0x1b, 0xe5, 0x97, 0xcb, 0x3b, 0x4b, 0x04, 0x61, 0xbe, 0x89, 0x09, 0xcf, 0xa9, 0xa7, 0xe2, 0x4a, 0x02, 0xca, 0xcf, 0x4a, 0xde, 0x12, 0x0b, 0xc4, 0x2c, 0x7d, 0x3d, 0x98, 0x0d, 0x1b, 0xff, 0x50, 0x86, 0xde, 0xa4, 0xbf, 0xb6, 0xd4, 0xf6, 0xea, 0x58, 0x72, 0xd8, 0x5d, 0xef, 0x68, 0x85, 0xdc, 0x52, 0x67, 0xb7, 0xfa, 0x36, 0x96, 0x22, 0x06, 0x24, 0x17, 0x1e, 0x16, 0xe2, 0x7b, 0x91, 0x25, 0x83, 0x7d, 0x88, 0x93, 0x7d, 0x62, 0x0c, 0x52, 0x77, 0x35, 0xbf, 0x55, 0x4e, 0x97, 0x59, 0x32, 0x00, 0xff, 0xf0, 0xd1, 0xfb, 0x7f, 0xea, 0x1f, 0x59, 0x2e, 0x71, 0x41, 0x0e, 0xa1, 0x85, 0x0e, 0xae, 0xec, 0x93, 0x42, 0x6d, 0xbe, 0xc8, 0x9e, 0x94, 0x63, 0x6c, 0xed, 0xf0, 0x01, 0xb0, 0xcd, 0x94, 0xa3, 0xf8, 0xf8, 0x0a, 0x38, 0x2a, 0xb3, 0x6c, 0xf5, 0xf2, 0x15, 0x60, 0x9b, 0x29, 0x47, 0xf1, 0x1d, 0xfb, 0x0a, 0xb0, 0xfa, 0x3a, 0x8d, 0x9b, 0xd2, 0x68, 0x34, 0x0a, 0xf7, 0x87, 0xa3, 0x32, 0xb9, 0xaf, 0xd7, 0x60, 0x30, 0xe0, 0xaf, 0x4d, 0x86, 0xac, 0x57, 0x60, 0x7c, 0x7c, 0x5c, 0x2a, 0x95, 0x8a, 0xc5, 0x62, 0x99, 0x8c, 0xe9, 0x0b, 0x23, 0x6c, 0xf7, 0xf4, 0xf4, 0xcc, 0xcf, 0xcf, 0xdb, 0x17, 0xe1, 0xf4, 0xf4, 0x34, 0xb1, 0x02, 0x43, 0x20, 0xd8, 0x2b, 0xb1, 0x1e, 0x80, 0x97, 0x97, 0x57, 0x48, 0x48, 0x08, 0x34, 0x6a, 0x34, 0x1a, 0x06, 0xbd, 0x5d, 0x5d, 0x5d, 0xa9, 0xa9, 0xa9, 0x65, 0x65, 0x65, 0x0c, 0x3c, 0x0c, 0x4b, 0x9e, 0x9e, 0x9e, 0xd1, 0xd1, 0xd1, 0x41, 0x41, 0x41, 0xe0, 0x59, 0x5f, 0x5f, 0x67, 0xe0, 0x34, 0x5f, 0x62, 0xf3, 0x45, 0x6a, 0x68, 0x68, 0x08, 0x62, 0x22, 0x91, 0x88, 0x81, 0xb9, 0xa5, 0xa5, 0x05, 0x3c, 0x09, 0x09, 0x09, 0x0c, 0x3c, 0x56, 0x97, 0x06, 0x07, 0x07, 0xa1, 0x04, 0x45, 0xb0, 0xca, 0x49, 0x31, 0x58, 0xaf, 0x00, 0x34, 0x52, 0xa3, 0xad, 0xad, 0x2d, 0x32, 0x32, 0x12, 0xd9, 0xca, 0xce, 0xce, 0x56, 0x2a, 0x95, 0x14, 0x8e, 0x36, 0x9b, 0x98, 0x98, 0xc0, 0x54, 0xab, 0xd5, 0xf6, 0xee, 0x8f, 0x81, 0x81, 0x01, 0xd2, 0xd0, 0xd8, 0x3c, 0x39, 0x39, 0x39, 0x89, 0x89, 0x89, 0x8d, 0x8d, 0x8d, 0xe9, 0xe9, 0xe9, 0x90, 0xad, 0xac, 0xac, 0xac, 0xad, 0xad, 0x95, 0x48, 0x24, 0x59, 0x59, 0x59, 0xfd, 0xfd, 0x7b, 0x6f, 0xf2, 0x38, 0x0d, 0x2a, 0x14, 0x06, 0x82, 0x54, 0x00, 0x66, 0x9c, 0x9d, 0x9d, 0x29, 0x63, 0x75, 0x75, 0x75, 0x44, 0x64, 0x78, 0x78, 0x98, 0x02, 0xe9, 0x44, 0x43, 0x43, 0x03, 0x18, 0x96, 0x97, 0x99, 0xde, 0x32, 0x44, 0x45, 0x45, 0xd1, 0xed, 0x3a, 0xbc, 0x02, 0x19, 0x19, 0x19, 0xc8, 0x74, 0x4d, 0x4d, 0x0d, 0x1c, 0xed, 0xec, 0xec, 0x24, 0xee, 0x62, 0x87, 0x24, 0x25, 0x25, 0xc9, 0xe5, 0x72, 0x4c, 0x5d, 0x5d, 0x5d, 0x51, 0x22, 0x8c, 0xb8, 0xb8, 0x38, 0xb4, 0x13, 0x10, 0xec, 0xc8, 0xf6, 0xf6, 0x76, 0x10, 0x38, 0x5b, 0xc6, 0xc6, 0xc6, 0xd2, 0xd2, 0xd2, 0x40, 0x27, 0x27, 0x27, 0x4f, 0x4d, 0x4d, 0x01, 0xc1, 0x53, 0xaf, 0xd7, 0x03, 0xb1, 0x7f, 0xd0, 0x13, 0xf0, 0x38, 0x9a, 0xaa, 0x00, 0x32, 0x04, 0x1e, 0x85, 0x42, 0x41, 0xec, 0xad, 0xae, 0xae, 0x52, 0x22, 0x0c, 0x7b, 0x60, 0x64, 0x64, 0xef, 0xf7, 0x71, 0x4c, 0x4c, 0x0c, 0x98, 0xab, 0xab, 0xab, 0x41, 0xd7, 0xd7, 0xd7, 0x83, 0x0e, 0x0c, 0x0c, 0x04, 0xbd, 0xb0, 0xb0, 0x40, 0x29, 0x71, 0x6c, 0x05, 0xb0, 0x89, 0xe3, 0xe3, 0xe3, 0x61, 0x92, 0x1c, 0x4a, 0x20, 0xb6, 0xb7, 0xff, 0xf7, 0x5b, 0x1e, 0x08, 0xc3, 0xf0, 0xf0, 0xf0, 0xc0, 0x2a, 0xde, 0xbd, 0xe1, 0x49, 0xa7, 0x4d, 0x26, 0x4e, 0xff, 0x34, 0xb0, 0x6d, 0x13, 0x13, 0xff, 0x88, 0x13, 0x66, 0xbe, 0xa2, 0x1f, 0x80, 0xe8, 0x74, 0x3a, 0x33, 0xdc, 0xd1, 0x53, 0x56, 0x01, 0xa0, 0xc4, 0x74, 0x3f, 0xa8, 0x29, 0x45, 0x60, 0xd5, 0xdb, 0xdb, 0x1b, 0x4f, 0xf4, 0xf4, 0xec, 0xec, 0x2c, 0xda, 0xba, 0xbb, 0xbb, 0xbb, 0xa2, 0xa2, 0xa2, 0xb5, 0xb5, 0x15, 0x20, 0x61, 0xa3, 0x33, 0xd3, 0x69, 0x4a, 0x33, 0x4e, 0x2d, 0x1c, 0x59, 0x64, 0x4a, 0xa7, 0x29, 0x86, 0x83, 0x09, 0xe8, 0x62, 0x1e, 0x33, 0x33, 0x33, 0xbe, 0xbe, 0xbe, 0x44, 0x38, 0x36, 0x36, 0x56, 0xad, 0x56, 0x93, 0xde, 0x05, 0x02, 0x02, 0xb7, 0x1b, 0x11, 0x9f, 0x9c, 0x9c, 0x24, 0x3c, 0x28, 0x85, 0xbb, 0xbb, 0x3b, 0xa1, 0x33, 0x33, 0x33, 0x37, 0x37, 0x37, 0x03, 0x02, 0xfe, 0x79, 0x5d, 0x57, 0x55, 0x55, 0x45, 0x0e, 0x00, 0xec, 0xf5, 0xbe, 0xbe, 0x3e, 0x72, 0x6d, 0x61, 0x6f, 0x40, 0x49, 0x70, 0x70, 0x30, 0x11, 0xa1, 0x3f, 0x21, 0xce, 0xec, 0x1b, 0x56, 0xad, 0x57, 0x00, 0x3d, 0x8a, 0xee, 0x27, 0x7a, 0xc9, 0x5d, 0x86, 0x8b, 0x86, 0x4c, 0xc9, 0x8d, 0x43, 0x68, 0x1c, 0x88, 0x4d, 0x4d, 0x4d, 0x38, 0xe6, 0xc1, 0x8f, 0x0a, 0xc0, 0x2d, 0xdc, 0xca, 0xcd, 0xcd, 0xcd, 0xb0, 0x41, 0xc4, 0xd1, 0x78, 0x88, 0x0d, 0xf7, 0x3a, 0xf8, 0x81, 0x80, 0x0d, 0xcc, 0xa0, 0xc9, 0xd1, 0x4c, 0x3f, 0xa0, 0x89, 0x42, 0x3c, 0x0f, 0xec, 0x55, 0x6a, 0x95, 0x10, 0x87, 0xfc, 0x56, 0x02, 0xee, 0xce, 0xcd, 0xcd, 0xa1, 0x62, 0xc4, 0x39, 0x33, 0x63, 0x8e, 0x98, 0x1e, 0x72, 0x00, 0x8e, 0x70, 0x91, 0x59, 0xa7, 0xf5, 0x16, 0x62, 0x96, 0x3f, 0xf2, 0x55, 0x3e, 0x80, 0xa3, 0x2e, 0x01, 0x5f, 0x01, 0xbe, 0x02, 0x1c, 0x33, 0xc0, 0xb7, 0x10, 0xc7, 0x04, 0x72, 0x16, 0xe7, 0x2b, 0xc0, 0x39, 0x85, 0x1c, 0x15, 0x1c, 0xfb, 0x0a, 0xfc, 0x0d, 0x0a, 0x08, 0x48, 0x44, 0xec, 0xf6, 0xcb, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXAudioIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x32, 0x39, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xa6, 0xa8, 0x92, 0xdf, 0x00, 0x00, 0x09, 0x77, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x99, 0x57, 0x4c, 0x94, 0x4b, 0x14, 0xc7, 0xd9, 0xa2, 0xd2, 0x44, 0x40, 0x2c, 0x14, 0x51, 0xc0, 0xa8, 0xd8, 0x30, 0x8a, 0x77, 0xc5, 0xcb, 0xb5, 0xbc, 0x20, 0xf6, 0x68, 0xa2, 0x89, 0x3d, 0x24, 0xbe, 0x58, 0x5e, 0x7c, 0xd0, 0x18, 0xbd, 0x46, 0xe3, 0x8b, 0x4f, 0x1a, 0x8d, 0x31, 0xea, 0x83, 0x35, 0x6a, 0x2c, 0xb9, 0x24, 0x46, 0x0d, 0x8a, 0x41, 0x54, 0x04, 0x0d, 0x08, 0x42, 0x58, 0x69, 0xa2, 0xec, 0x52, 0xa4, 0x08, 0xb2, 0x74, 0x41, 0x81, 0xfb, 0x93, 0xb9, 0x99, 0x7c, 0x77, 0x29, 0xba, 0x1f, 0x4d, 0x93, 0xfd, 0xb2, 0xd9, 0x9c, 0x99, 0x39, 0x33, 0xdf, 0xf9, 0x9f, 0x36, 0x73, 0xe6, 0xd3, 0xb4, 0xb7, 0xb7, 0x3b, 0xfc, 0xce, 0x8f, 0xf6, 0x77, 0x16, 0xfe, 0xbb, 0xec, 0x76, 0x00, 0x83, 0x6d, 0x41, 0xbb, 0x05, 0x6c, 0xb4, 0x40, 0x65, 0x65, 0x65, 0x7e, 0x7e, 0xfe, 0xb7, 0x6f, 0xdf, 0x6c, 0x9c, 0xd7, 0x2d, 0xbb, 0xa6, 0x6f, 0xb3, 0x50, 0x71, 0x71, 0x71, 0xb5, 0xc5, 0xa2, 0xd7, 0xe9, 0xbc, 0xc7, 0x7a, 0xbb, 0x7b, 0xb8, 0x2b, 0x5f, 0xcb, 0x8b, 0x34, 0x1a, 0x4d, 0x5d, 0x5d, 0xdd, 0xf3, 0xe7, 0xcf, 0x1b, 0x1b, 0x1b, 0x97, 0x2e, 0x5d, 0xea, 0xea, 0xea, 0xaa, 0x64, 0x50, 0x47, 0xf7, 0x25, 0x80, 0x9c, 0x9c, 0x9c, 0x4c, 0xa3, 0xd1, 0xa1, 0x5d, 0xd3, 0xdc, 0xd2, 0xac, 0xd7, 0xeb, 0x02, 0x03, 0x02, 0xa6, 0x4f, 0x9f, 0xee, 0xec, 0xec, 0x2c, 0x24, 0x43, 0xf4, 0xf2, 0xf2, 0x72, 0x3f, 0x3f, 0x3f, 0xad, 0x56, 0xfb, 0xf0, 0xe1, 0xc3, 0xcf, 0x9f, 0x3f, 0xaf, 0x5f, 0xbf, 0x5e, 0x8e, 0xaa, 0x93, 0x9e, 0x59, 0xba, 0x23, 0x47, 0x8e, 0xa8, 0x9e, 0xac, 0x9c, 0xd8, 0xd0, 0xd0, 0x90, 0x9a, 0x9a, 0x86, 0x9a, 0x1f, 0x3f, 0x8e, 0x8d, 0x7f, 0x12, 0x57, 0x55, 0x59, 0xd9, 0xd4, 0xd8, 0x44, 0xa7, 0x97, 0xd7, 0x28, 0x27, 0x27, 0x47, 0x38, 0xf5, 0x7a, 0x3d, 0x42, 0xbf, 0x79, 0xf3, 0xc6, 0xdb, 0xdb, 0x7b, 0xda, 0xb4, 0x69, 0xa0, 0xcd, 0xcd, 0xcd, 0x9d, 0x31, 0x63, 0x86, 0x72, 0x11, 0x15, 0x74, 0x9f, 0x01, 0x30, 0x9b, 0xcd, 0x38, 0x46, 0x7c, 0x7c, 0x7c, 0x74, 0xf4, 0x3f, 0xc8, 0xf1, 0xb9, 0xba, 0xda, 0x64, 0x36, 0xe1, 0xeb, 0xad, 0xad, 0xad, 0x63, 0xc6, 0x8c, 0x71, 0x72, 0x72, 0x42, 0xfd, 0x82, 0x78, 0xf5, 0xea, 0xd5, 0xf8, 0xf1, 0xe3, 0x27, 0x4c, 0x98, 0xf0, 0xe2, 0xc5, 0x8b, 0xa1, 0x43, 0x87, 0xfa, 0xf8, 0xf8, 0xa8, 0x90, 0x5b, 0x4e, 0xe9, 0x33, 0x00, 0x65, 0x65, 0x65, 0xb5, 0xb5, 0x75, 0x0f, 0x1e, 0xdc, 0xd7, 0x68, 0x1c, 0xc6, 0x8e, 0x1d, 0xeb, 0xe2, 0xe2, 0x82, 0xca, 0x09, 0x09, 0x8b, 0xa5, 0x1a, 0x0c, 0xe3, 0xc6, 0x8d, 0x1b, 0x36, 0x6c, 0x98, 0xd1, 0x68, 0x0c, 0x08, 0x08, 0xc0, 0x85, 0xc0, 0x30, 0x67, 0xce, 0x1c, 0x7a, 0x9e, 0x3d, 0x7b, 0x36, 0x75, 0xea, 0x54, 0x47, 0xc7, 0xef, 0x26, 0x52, 0xf7, 0xf4, 0x59, 0x1a, 0x45, 0x2c, 0x44, 0x47, 0x14, 0x6f, 0x6f, 0x1f, 0x4f, 0x4f, 0x4f, 0x0f, 0x0f, 0x8f, 0x11, 0x23, 0x46, 0xb8, 0xbb, 0xbb, 0x17, 0x14, 0x14, 0x20, 0x6e, 0x42, 0x42, 0x02, 0xee, 0x0e, 0x0c, 0x5c, 0x28, 0x38, 0x38, 0x18, 0x6c, 0xa9, 0xa9, 0xa9, 0xb3, 0x66, 0xcd, 0xa2, 0x93, 0x51, 0x75, 0xa2, 0x8b, 0x59, 0x7d, 0x03, 0xa0, 0xa9, 0xa9, 0x29, 0x3b, 0x3b, 0x1b, 0xe9, 0x3d, 0x3c, 0xdc, 0xbd, 0xbc, 0xbc, 0x46, 0x8e, 0x1c, 0x29, 0x31, 0xd0, 0x24, 0x6f, 0x26, 0x25, 0x25, 0xbe, 0x7e, 0xfd, 0x1a, 0x6f, 0x01, 0xd5, 0xbb, 0x77, 0xef, 0x16, 0x2e, 0x5c, 0x98, 0x96, 0x96, 0x56, 0x5f, 0x5f, 0x3f, 0x7f, 0xfe, 0xfc, 0xcc, 0xcc, 0x4c, 0xe2, 0x5b, 0x35, 0x86, 0xbe, 0x01, 0x40, 0x76, 0x7f, 0xff, 0xfe, 0xbd, 0x4e, 0xa7, 0x77, 0x77, 0xf7, 0x70, 0x73, 0x73, 0x43, 0xf1, 0xc2, 0x02, 0xd0, 0xc3, 0x87, 0x0f, 0x87, 0xce, 0xcb, 0x7b, 0xf7, 0xf2, 0xe5, 0x4b, 0xc2, 0x60, 0xf2, 0xe4, 0xc9, 0x26, 0x93, 0x89, 0x90, 0x20, 0x0c, 0x92, 0x92, 0x92, 0xa6, 0x4c, 0x99, 0x82, 0x11, 0x80, 0x34, 0xc8, 0x00, 0x4a, 0x4a, 0x3e, 0xf2, 0x23, 0x64, 0x51, 0x3c, 0xd9, 0x1d, 0xb9, 0x79, 0x80, 0x21, 0x09, 0x9d, 0x4e, 0x47, 0xda, 0x49, 0x4c, 0x4c, 0x1c, 0x32, 0x64, 0x08, 0x59, 0x08, 0xad, 0x13, 0x03, 0x44, 0xc8, 0xd7, 0xaf, 0x5f, 0xf1, 0xa8, 0xbc, 0xbc, 0x3c, 0xe2, 0x44, 0x1d, 0x86, 0x3e, 0xb0, 0x00, 0xef, 0x36, 0x99, 0x0a, 0xb0, 0x40, 0x5d, 0x5d, 0x2d, 0x79, 0x86, 0x26, 0x18, 0x04, 0x0c, 0x30, 0xe0, 0x33, 0x18, 0x61, 0xd4, 0xa8, 0x51, 0x44, 0x79, 0x46, 0x46, 0x06, 0xa2, 0xa3, 0xf5, 0xaa, 0xaa, 0x2a, 0x8c, 0x80, 0x77, 0x7d, 0xf8, 0xf0, 0x81, 0x20, 0xa6, 0x59, 0x5b, 0x5b, 0x3b, 0x38, 0x00, 0x2c, 0x16, 0x4b, 0x4c, 0xcc, 0xc3, 0x94, 0x94, 0x94, 0xaa, 0xaa, 0x4a, 0x93, 0xc9, 0x4c, 0x98, 0xea, 0xf5, 0x43, 0xd8, 0x71, 0x9b, 0x9b, 0x9b, 0x09, 0x6b, 0x81, 0x44, 0xfc, 0xe3, 0x48, 0xa4, 0x5a, 0xbc, 0x85, 0x7e, 0x68, 0xbc, 0x2e, 0x28, 0x28, 0xa8, 0xb0, 0xb0, 0x10, 0x84, 0xc4, 0x34, 0xf0, 0x06, 0x01, 0x00, 0x81, 0x6b, 0x36, 0x97, 0x14, 0x14, 0x98, 0xd8, 0xb0, 0xf0, 0x9f, 0x8c, 0x8c, 0x74, 0x12, 0x28, 0xe2, 0xd2, 0x24, 0xcd, 0xe3, 0xdc, 0x6d, 0x6d, 0x6d, 0x68, 0x9a, 0x07, 0x1a, 0x77, 0xa2, 0x1f, 0xa8, 0x9f, 0x3e, 0x7d, 0x22, 0x9a, 0x2b, 0x2a, 0x2a, 0x60, 0x26, 0x7c, 0xd9, 0xfb, 0xb0, 0x5b, 0x69, 0x69, 0xe9, 0x40, 0x03, 0xa8, 0xa9, 0xa9, 0x49, 0x4f, 0x37, 0x56, 0x56, 0x56, 0x39, 0x38, 0x68, 0x5a, 0x5b, 0xbf, 0x7b, 0xff, 0xdb, 0xb7, 0x6f, 0x11, 0xc8, 0xc7, 0xc7, 0x1b, 0x47, 0x9f, 0x39, 0x73, 0x66, 0x64, 0x64, 0x24, 0xbb, 0x01, 0x62, 0xb1, 0x5b, 0x91, 0xf2, 0xc9, 0x51, 0x10, 0xd5, 0xd5, 0xd5, 0x64, 0x52, 0xd2, 0x14, 0xbb, 0x1e, 0xa3, 0x3c, 0x98, 0x8b, 0xa8, 0x50, 0x9d, 0x88, 0xd4, 0xc7, 0x00, 0xdb, 0x56, 0x43, 0x43, 0x3d, 0xa2, 0x18, 0x0c, 0x86, 0xc6, 0xc6, 0x26, 0xd2, 0x0b, 0x61, 0x90, 0x9c, 0x9c, 0x82, 0x63, 0xb4, 0xb4, 0xb4, 0x20, 0x37, 0x7e, 0x42, 0xaa, 0xc1, 0x97, 0x90, 0x1b, 0x48, 0xf8, 0x09, 0xc6, 0xe1, 0x34, 0x61, 0x36, 0x17, 0x62, 0x2e, 0x3c, 0x07, 0x5f, 0x42, 0x74, 0x2c, 0xc0, 0x22, 0x8c, 0xaa, 0xb3, 0x80, 0xca, 0x69, 0xbc, 0xcc, 0xd5, 0xd5, 0x05, 0xd3, 0x07, 0x05, 0x05, 0xea, 0x74, 0xd0, 0xae, 0x44, 0x2a, 0xe1, 0x88, 0x7c, 0x48, 0x8c, 0xe8, 0x29, 0x29, 0xaf, 0xbf, 0x7c, 0xf9, 0xc2, 0xfe, 0x80, 0xac, 0xe8, 0x1e, 0x35, 0xf3, 0x20, 0x25, 0xcd, 0xb2, 0xf2, 0x52, 0xa0, 0x8a, 0x70, 0x1f, 0x3d, 0x7a, 0x34, 0xd8, 0xf0, 0x31, 0xa6, 0x0c, 0x34, 0x00, 0x5e, 0x89, 0xe8, 0x1a, 0x4d, 0x9b, 0xb3, 0xb3, 0xcb, 0x82, 0x05, 0x0b, 0xee, 0xdd, 0xbb, 0xb7, 0x6b, 0xd7, 0xae, 0xe6, 0xe6, 0x96, 0xec, 0xec, 0x9c, 0xe0, 0xe0, 0x29, 0xf1, 0xf1, 0x4f, 0xb0, 0x8f, 0x88, 0x0d, 0x24, 0x43, 0xcd, 0x3c, 0x10, 0x88, 0x5b, 0x5e, 0x56, 0x86, 0xfb, 0xe1, 0x63, 0x44, 0x08, 0x61, 0x00, 0x2a, 0x10, 0x62, 0x2b, 0x75, 0x00, 0xd4, 0xbb, 0x10, 0xef, 0x43, 0xf1, 0x45, 0x45, 0x85, 0xc8, 0xf5, 0xe7, 0x9f, 0xe1, 0xf8, 0x74, 0x71, 0xf1, 0x47, 0xb2, 0x26, 0x82, 0x92, 0x16, 0x03, 0x02, 0x82, 0xb2, 0xb2, 0xb2, 0xf1, 0x6c, 0xfc, 0x07, 0xad, 0x23, 0x6b, 0x07, 0x84, 0x76, 0xdc, 0x06, 0x7f, 0x03, 0x1a, 0x04, 0xa2, 0x33, 0xca, 0x3a, 0xc4, 0x37, 0x48, 0x06, 0x01, 0xc0, 0xa4, 0x49, 0x93, 0xd2, 0xde, 0xa4, 0x7f, 0x2c, 0xa9, 0x68, 0x6b, 0xd3, 0x86, 0x86, 0xce, 0x4d, 0x4c, 0x4c, 0x40, 0xe7, 0x1d, 0x19, 0xe6, 0x93, 0x9f, 0x9f, 0x2f, 0x25, 0x01, 0xc9, 0x91, 0x2d, 0x8c, 0xdd, 0x4a, 0x60, 0x60, 0x8b, 0x00, 0x09, 0x7e, 0x65, 0xa9, 0xb1, 0x60, 0x04, 0x29, 0x31, 0x66, 0x81, 0x4d, 0x36, 0x6d, 0x22, 0x7a, 0x65, 0x01, 0xd4, 0xe6, 0xe4, 0xe8, 0x94, 0x90, 0xf0, 0x9c, 0xfd, 0x28, 0x34, 0xd4, 0x80, 0x7c, 0x89, 0x89, 0x2f, 0xc8, 0x8f, 0x15, 0x15, 0xe5, 0x9c, 0xe1, 0xfe, 0x30, 0x18, 0xd8, 0x9e, 0xc0, 0x40, 0x30, 0xf0, 0x10, 0x1b, 0x04, 0x37, 0x0f, 0x04, 0xa7, 0x20, 0xbc, 0xcb, 0x26, 0x41, 0xbb, 0x63, 0xee, 0x15, 0x00, 0x16, 0x0d, 0x0b, 0x33, 0x64, 0x65, 0x19, 0x39, 0x48, 0xa0, 0xd7, 0xad, 0x5b, 0xa3, 0x38, 0x2f, 0xc4, 0xc6, 0x3e, 0x4a, 0x4e, 0x4e, 0xbe, 0x7f, 0xff, 0x7e, 0x6d, 0x4d, 0x4d, 0x44, 0xc4, 0x12, 0xdc, 0x89, 0x1c, 0x8f, 0xc4, 0xf8, 0x18, 0x0f, 0x6c, 0x18, 0x41, 0xab, 0xd5, 0xf1, 0xdf, 0x9d, 0x4c, 0x36, 0xf5, 0xf7, 0x0a, 0x00, 0x6e, 0x4d, 0x1e, 0x5c, 0xbe, 0x2c, 0x32, 0x37, 0x2f, 0x27, 0x24, 0x64, 0xc6, 0xaa, 0x55, 0xcb, 0x0f, 0x1e, 0xfc, 0xdb, 0xd1, 0xd1, 0xc9, 0xd7, 0xd7, 0xd7, 0xc7, 0xc7, 0x97, 0xda, 0x17, 0x7d, 0x87, 0x87, 0xff, 0x85, 0xfa, 0x39, 0xc0, 0x61, 0x17, 0x72, 0x14, 0xff, 0x6c, 0x6a, 0xe4, 0x4d, 0xdc, 0xc6, 0x26, 0x41, 0xbb, 0x63, 0x56, 0x5f, 0xd0, 0x20, 0x3d, 0x5a, 0x44, 0x44, 0x7f, 0x7f, 0x7f, 0x9d, 0x4e, 0x63, 0x34, 0x66, 0xb2, 0x5f, 0x79, 0x7a, 0x8e, 0x1c, 0xee, 0xe6, 0xa6, 0xd5, 0x68, 0xe7, 0xcd, 0x33, 0x40, 0x37, 0x35, 0x35, 0xe2, 0xdc, 0x41, 0x41, 0x13, 0x21, 0x38, 0xb1, 0x71, 0x1a, 0x25, 0x76, 0x57, 0xad, 0x5c, 0xe5, 0xef, 0x3f, 0x8e, 0x13, 0x91, 0x6a, 0xbf, 0x57, 0x82, 0x51, 0x59, 0xd4, 0x23, 0x3d, 0xab, 0xe0, 0xf4, 0x00, 0xc0, 0x2b, 0x68, 0xb2, 0x0d, 0xf3, 0x20, 0x13, 0xea, 0x9f, 0x38, 0x71, 0x22, 0x99, 0x91, 0x14, 0x44, 0x0c, 0xe0, 0x36, 0xf8, 0x4f, 0x6b, 0x6b, 0x3b, 0x2d, 0x0e, 0x11, 0x1c, 0xef, 0x28, 0x16, 0x28, 0x7a, 0xc2, 0xc2, 0xe6, 0x75, 0xf8, 0x12, 0x65, 0x90, 0x46, 0x29, 0x90, 0xad, 0x74, 0xaf, 0x00, 0x20, 0x01, 0xe9, 0x05, 0x00, 0x88, 0x08, 0x01, 0x18, 0x12, 0x0e, 0x18, 0xc0, 0x43, 0x7e, 0xe4, 0xf8, 0x80, 0x9f, 0xd0, 0x0f, 0x8c, 0xfc, 0xfc, 0xf7, 0xf5, 0x0d, 0xf5, 0xe4, 0x4d, 0xac, 0x86, 0x11, 0x42, 0x43, 0x43, 0x39, 0x9f, 0x02, 0x12, 0x7a, 0x70, 0x00, 0x08, 0x3d, 0x21, 0x28, 0x0f, 0x30, 0x04, 0x12, 0xfe, 0x69, 0x22, 0x90, 0xc8, 0xf1, 0x82, 0x87, 0x4e, 0x80, 0x61, 0x2b, 0x40, 0x82, 0x04, 0x0c, 0x88, 0x2e, 0x8e, 0x46, 0xbd, 0x97, 0x9e, 0x57, 0xa8, 0xb4, 0x80, 0xad, 0x86, 0xee, 0x3f, 0xfe, 0x5e, 0x65, 0xa1, 0xfe, 0x13, 0xeb, 0xe7, 0x57, 0xb6, 0x03, 0xf8, 0x79, 0x5d, 0xf5, 0x0f, 0xa7, 0xdd, 0x02, 0xfd, 0xa3, 0xd7, 0x9f, 0x5f, 0xd5, 0x6e, 0x81, 0x1f, 0xe9, 0x4a, 0x6c, 0x11, 0x6c, 0x67, 0x9d, 0x19, 0xb9, 0x5d, 0x3c, 0x7a, 0xf4, 0x28, 0xe7, 0x8b, 0xce, 0x43, 0x36, 0xf4, 0x74, 0xec, 0x45, 0xfd, 0xf5, 0x77, 0xe0, 0xc0, 0x01, 0x79, 0xe0, 0xd9, 0xb1, 0x63, 0x87, 0xd5, 0x6b, 0x36, 0x6c, 0xd8, 0x80, 0xa0, 0x57, 0xaf, 0x5e, 0xb5, 0xea, 0xb7, 0xa9, 0xd9, 0xbf, 0x2e, 0x44, 0xa1, 0x48, 0x8d, 0xcf, 0x85, 0x05, 0x82, 0xb2, 0x0d, 0x5b, 0xe9, 0x95, 0x32, 0x1a, 0x78, 0x14, 0xc7, 0x56, 0xfd, 0xb6, 0x35, 0x7b, 0x86, 0x2b, 0x4e, 0x07, 0x3d, 0xf3, 0xfc, 0x70, 0xf4, 0xc4, 0x89, 0x13, 0xc8, 0xb4, 0x79, 0xf3, 0xe6, 0xce, 0x9c, 0x9c, 0x32, 0x3a, 0x77, 0xda, 0xd4, 0xd3, 0x85, 0x05, 0xb8, 0xae, 0xda, 0xb6, 0x6d, 0xdb, 0xdc, 0xb9, 0x73, 0xd1, 0x10, 0x67, 0x77, 0x2e, 0xc1, 0xef, 0xde, 0xbd, 0x2b, 0xb5, 0x72, 0xec, 0xd8, 0xb1, 0x79, 0x1d, 0x0f, 0x55, 0x0b, 0x9d, 0xe7, 0xcf, 0x9f, 0x0f, 0xa3, 0xa8, 0x31, 0x18, 0xa8, 0x60, 0x24, 0x0f, 0xc4, 0xad, 0x5b, 0xb7, 0xb6, 0x6c, 0xd9, 0x12, 0x11, 0x11, 0xc1, 0x17, 0xa0, 0xce, 0xba, 0x8f, 0x8d, 0x8d, 0xe5, 0x82, 0x9a, 0x59, 0xe1, 0xe1, 0xe1, 0x27, 0x4f, 0x9e, 0x54, 0x4e, 0x14, 0x74, 0x49, 0x49, 0x49, 0x54, 0x54, 0x14, 0x47, 0x6e, 0xca, 0x6e, 0x04, 0xd8, 0xb7, 0x6f, 0x5f, 0xb7, 0x15, 0x5c, 0x67, 0xb8, 0x88, 0xc7, 0x2a, 0x9c, 0xc9, 0xc0, 0xc0, 0xb5, 0x07, 0x34, 0x67, 0x2f, 0x2a, 0x12, 0xc1, 0x29, 0x3f, 0x0a, 0xdd, 0xbe, 0x7d, 0x9b, 0x9e, 0x25, 0x4b, 0x96, 0x88, 0x57, 0x1e, 0x3f, 0x7e, 0x5c, 0x2e, 0xb5, 0x7d, 0xfb, 0x76, 0xd1, 0x29, 0xfe, 0xc5, 0x79, 0x53, 0x69, 0x81, 0xfd, 0xfb, 0xf7, 0x4b, 0x06, 0x94, 0x25, 0x27, 0x0a, 0x82, 0xe0, 0xa6, 0xcc, 0x97, 0x0c, 0x82, 0xe0, 0xcb, 0x08, 0xb7, 0x91, 0x56, 0x9c, 0x34, 0xff, 0xbb, 0xf0, 0x50, 0x0e, 0x44, 0x47, 0x47, 0x23, 0x0d, 0x57, 0xc7, 0x74, 0x52, 0xbf, 0x0a, 0x0c, 0x32, 0xd4, 0xb8, 0xcd, 0x0c, 0x0c, 0x0c, 0x64, 0x51, 0x01, 0x80, 0x1c, 0x32, 0x7b, 0xf6, 0x6c, 0x9a, 0x12, 0x80, 0x34, 0x17, 0xda, 0xbd, 0x78, 0xf1, 0xe2, 0xe2, 0xc5, 0x8b, 0x85, 0x04, 0x9b, 0x36, 0x6d, 0x92, 0x6f, 0xa1, 0x54, 0x88, 0x89, 0x89, 0x59, 0xb3, 0x66, 0x0d, 0x43, 0x56, 0x00, 0x38, 0x90, 0xf3, 0x69, 0x90, 0x7e, 0x6a, 0xbd, 0x33, 0x67, 0xce, 0xf0, 0x6d, 0xe1, 0xf0, 0xe1, 0xc3, 0x5c, 0x1c, 0xd1, 0xb3, 0x71, 0xe3, 0x46, 0xb9, 0x82, 0x24, 0xba, 0xb8, 0xd8, 0x62, 0xdd, 0xb8, 0xb8, 0x38, 0x24, 0xa6, 0xfc, 0xa3, 0xfe, 0x60, 0x21, 0x08, 0x6c, 0x2a, 0xe4, 0xe0, 0xfa, 0x96, 0x4e, 0x68, 0xa1, 0x57, 0xe0, 0x59, 0x45, 0xe1, 0xa5, 0x4b, 0x97, 0x18, 0xa5, 0x9f, 0xcf, 0x47, 0x1c, 0x98, 0xf1, 0x04, 0xee, 0x49, 0xb9, 0xd6, 0x15, 0xd3, 0xc5, 0x3f, 0x8e, 0xc1, 0xc5, 0xe3, 0xd3, 0xa7, 0x4f, 0x95, 0x9d, 0x82, 0xc6, 0x81, 0xf9, 0x12, 0x05, 0xbd, 0x77, 0xef, 0xde, 0x9d, 0x3b, 0x77, 0x42, 0xe0, 0x84, 0xc0, 0xb8, 0x7e, 0xfd, 0x3a, 0x9a, 0xe5, 0x58, 0x2e, 0xd3, 0x9a, 0xe0, 0xb7, 0x06, 0x80, 0x02, 0x56, 0xae, 0x5c, 0xf9, 0xe8, 0xd1, 0x23, 0x86, 0x29, 0x4a, 0x90, 0x12, 0x23, 0x40, 0x33, 0x53, 0x4c, 0xf8, 0xe1, 0x3f, 0x75, 0x3d, 0x3c, 0xcb, 0x96, 0x2d, 0x43, 0x7a, 0xc1, 0xbc, 0x62, 0xc5, 0x0a, 0x74, 0xf9, 0xc3, 0x89, 0x82, 0x41, 0x4c, 0x87, 0x5e, 0xbd, 0x7a, 0xb5, 0x9c, 0x02, 0x0d, 0x00, 0x51, 0x5b, 0x93, 0xd6, 0x64, 0x3f, 0x84, 0x75, 0x10, 0x5f, 0xbb, 0x76, 0x4d, 0x48, 0x7f, 0xe7, 0xce, 0x1d, 0xae, 0x6e, 0x28, 0x08, 0xd7, 0xae, 0x5d, 0xab, 0x9c, 0x00, 0x2d, 0x74, 0xc0, 0x75, 0x83, 0xe8, 0x27, 0x3c, 0x94, 0x0c, 0x68, 0x97, 0x26, 0xd7, 0x2a, 0xb2, 0x53, 0x49, 0xcb, 0xce, 0xee, 0x08, 0x0c, 0x2e, 0x86, 0xb8, 0xc7, 0x96, 0x3c, 0x82, 0x46, 0x9b, 0x9d, 0xef, 0xbf, 0xac, 0x01, 0x60, 0x41, 0xa6, 0x51, 0x34, 0xe1, 0x48, 0x94, 0x7c, 0xa4, 0x39, 0xae, 0x12, 0xe8, 0xc1, 0xe7, 0xe4, 0x72, 0x22, 0x2a, 0xf8, 0x48, 0x4a, 0x27, 0x6e, 0x20, 0xa6, 0x48, 0x06, 0x3e, 0xbd, 0xc0, 0xc9, 0x28, 0xdf, 0x63, 0x20, 0x78, 0x37, 0x0e, 0x29, 0xe7, 0x0a, 0x02, 0x66, 0xf6, 0x66, 0x72, 0x34, 0x4d, 0x25, 0x4d, 0x93, 0x2b, 0x47, 0xb2, 0x1f, 0xc4, 0xe9, 0xd3, 0xa7, 0x8b, 0x8a, 0x8a, 0x20, 0xd2, 0xd3, 0xd3, 0x51, 0x3f, 0x04, 0xe9, 0x88, 0xdb, 0x6c, 0x88, 0xff, 0x3d, 0xcc, 0x57, 0x3e, 0x97, 0x2f, 0x5f, 0x16, 0xc3, 0x84, 0xe6, 0xba, 0x75, 0xeb, 0xa8, 0xd0, 0x45, 0x93, 0xea, 0xf6, 0xca, 0x95, 0x2b, 0x82, 0x93, 0xfd, 0x5f, 0x74, 0xf2, 0xd9, 0x5d, 0x10, 0xfc, 0xe3, 0x6f, 0x37, 0x6f, 0xde, 0x84, 0x81, 0x28, 0x97, 0xaf, 0x21, 0x0f, 0x4a, 0x06, 0xf4, 0x77, 0xe8, 0xd0, 0x21, 0x18, 0xb0, 0xad, 0x08, 0x4a, 0x39, 0x24, 0xa6, 0x9f, 0x3d, 0x7b, 0x56, 0xac, 0x7f, 0xee, 0xdc, 0x39, 0x31, 0x44, 0xfd, 0x19, 0x12, 0x12, 0x22, 0x68, 0xcc, 0xce, 0x57, 0x36, 0xc1, 0xa0, 0xfc, 0xb7, 0xce, 0x42, 0x28, 0x66, 0xf7, 0xee, 0xdd, 0x42, 0xc7, 0xcc, 0xe4, 0x2b, 0xe2, 0xa9, 0x53, 0xa7, 0x48, 0x6a, 0x58, 0xe3, 0xc2, 0x85, 0x0b, 0x62, 0x26, 0xce, 0x43, 0x0a, 0x17, 0xeb, 0x2e, 0x5a, 0xb4, 0x68, 0xcf, 0x9e, 0x3d, 0xd0, 0xec, 0x18, 0xe8, 0x49, 0x30, 0xf0, 0x26, 0xbe, 0x7c, 0x09, 0x06, 0x5c, 0x82, 0x4c, 0x2f, 0xaa, 0x64, 0x09, 0x40, 0x22, 0x14, 0x3c, 0xfc, 0x93, 0xa9, 0x25, 0x00, 0x16, 0xb9, 0x71, 0xe3, 0x86, 0xf2, 0xba, 0x17, 0xab, 0xf2, 0xa1, 0x56, 0x29, 0xb7, 0xa4, 0xbb, 0xae, 0x89, 0x31, 0x2e, 0xc1, 0x84, 0x82, 0x3b, 0xe7, 0x63, 0xf9, 0x4a, 0x34, 0x0d, 0x2a, 0x09, 0x55, 0xf6, 0x4b, 0x82, 0x0b, 0x39, 0x76, 0x1f, 0x62, 0x4e, 0xe4, 0x2b, 0xd9, 0xff, 0xf3, 0x04, 0x89, 0x9f, 0x45, 0x48, 0x62, 0xc2, 0xa9, 0xba, 0x9c, 0xd8, 0x35, 0x80, 0x2e, 0x59, 0x7f, 0xcd, 0x4e, 0xeb, 0x20, 0xfe, 0x35, 0xa5, 0xec, 0x41, 0x2a, 0x3b, 0x80, 0x1e, 0x94, 0x33, 0x20, 0x43, 0x76, 0x0b, 0x0c, 0x88, 0x9a, 0x7b, 0x78, 0x89, 0xdd, 0x02, 0x3d, 0x28, 0x67, 0x40, 0x86, 0xec, 0x16, 0x18, 0x10, 0x35, 0xf7, 0xf0, 0x12, 0xbb, 0x05, 0x7a, 0x50, 0xce, 0x80, 0x0c, 0xfd, 0x0b, 0xbe, 0x35, 0x47, 0x3f, 0x08, 0xc9, 0x3b, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXJSIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x38, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x0e, 0x0a, 0xaa, 0x03, 0x00, 0x00, 0x05, 0x39, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x7d, 0x48, 0x5b, 0x57, 0x14, 0xcf, 0x8b, 0x2f, 0x31, 0xd1, 0x1a, 0x4d, 0xb4, 0x06, 0xc7, 0xfc, 0x88, 0x55, 0x59, 0x97, 0x5a, 0xf1, 0xb3, 0x43, 0x83, 0xba, 0x32, 0x97, 0x0d, 0x3a, 0x0b, 0x2b, 0x08, 0x75, 0x65, 0x82, 0x8c, 0xc1, 0xdc, 0x1f, 0xab, 0x48, 0xdd, 0x64, 0x62, 0x19, 0x6e, 0x73, 0xc2, 0xa6, 0x83, 0x6e, 0x38, 0x46, 0xff, 0x28, 0xc3, 0x75, 0x6b, 0x51, 0x36, 0x54, 0x56, 0x23, 0x88, 0x3a, 0x3b, 0xa1, 0x22, 0xd4, 0xd8, 0xc9, 0x28, 0x9b, 0x1f, 0x0c, 0xad, 0x4c, 0xa3, 0xb5, 0x89, 0x71, 0xd1, 0x7c, 0xb8, 0x63, 0x9f, 0xbc, 0x3c, 0x93, 0x98, 0x9b, 0xbc, 0x7b, 0xcd, 0x10, 0xde, 0x23, 0x84, 0x73, 0xcf, 0xfb, 0xdd, 0x73, 0x7e, 0xbf, 0x73, 0xee, 0xbb, 0x2f, 0xb9, 0xd4, 0xce, 0xce, 0x8e, 0xe8, 0x28, 0x5f, 0xe2, 0xa3, 0x4c, 0x7e, 0x97, 0xbb, 0x20, 0xe0, 0xff, 0xee, 0xa0, 0xd0, 0x01, 0xa1, 0x03, 0x98, 0x15, 0x10, 0x96, 0x10, 0x66, 0x01, 0xb1, 0xa7, 0xd3, 0xd8, 0x11, 0xf6, 0x02, 0xac, 0x8f, 0x19, 0xcc, 0x13, 0xbf, 0xba, 0xec, 0xdb, 0x30, 0x56, 0x16, 0xe9, 0xa3, 0x5f, 0x78, 0xc9, 0x23, 0xf2, 0xfc, 0x17, 0x57, 0x18, 0x8f, 0x34, 0xfe, 0x99, 0xf8, 0x73, 0x97, 0x68, 0xe5, 0x71, 0x0f, 0x00, 0xbf, 0x21, 0x19, 0x01, 0xb3, 0x1f, 0xbf, 0xb3, 0x74, 0xeb, 0x1b, 0x96, 0x41, 0x58, 0x64, 0x94, 0xb7, 0x80, 0xc5, 0x1b, 0x9f, 0xb3, 0x80, 0x85, 0x6f, 0x3f, 0xc9, 0xfc, 0xee, 0xae, 0x5c, 0xf3, 0x1c, 0xeb, 0xe1, 0x6d, 0x10, 0x78, 0x06, 0x2c, 0xc6, 0x31, 0x2e, 0xfb, 0x40, 0xa8, 0xd8, 0xd7, 0x57, 0xe7, 0x5a, 0x2f, 0x07, 0x82, 0x44, 0x62, 0x08, 0x74, 0xc0, 0x32, 0x39, 0xc6, 0xa6, 0x49, 0xfd, 0xe0, 0x4b, 0xa5, 0xee, 0x55, 0x5a, 0x19, 0xc7, 0x7a, 0x58, 0x23, 0xf7, 0x97, 0x3f, 0x1d, 0xe6, 0xf5, 0xbf, 0xae, 0xbe, 0x65, 0x7d, 0x68, 0x04, 0x27, 0x77, 0x16, 0x8b, 0xe1, 0x61, 0x10, 0xe8, 0x80, 0x63, 0xc3, 0xcc, 0x24, 0xa6, 0x15, 0x31, 0x09, 0x6f, 0xbc, 0x27, 0x4b, 0xce, 0xa0, 0x15, 0x2a, 0x6f, 0x2a, 0xb2, 0xc4, 0xb4, 0x63, 0xda, 0xbc, 0xf8, 0xf3, 0x55, 0xcc, 0x2d, 0x87, 0xd5, 0xe2, 0x8d, 0xe1, 0xe1, 0x21, 0x20, 0x80, 0xcd, 0x2a, 0x0e, 0x97, 0xb3, 0xf6, 0x41, 0x46, 0x20, 0x98, 0x83, 0xe6, 0xfa, 0xf4, 0x93, 0x14, 0xe0, 0x33, 0xc1, 0x61, 0x3b, 0x05, 0x01, 0x22, 0x91, 0x63, 0x7d, 0x95, 0x29, 0x33, 0x45, 0x4b, 0x90, 0xf5, 0x16, 0x4b, 0xdc, 0x18, 0x87, 0x79, 0x0d, 0x89, 0x47, 0x02, 0x70, 0x3b, 0xb0, 0xbd, 0xf2, 0x68, 0x75, 0xf0, 0x27, 0x26, 0x4d, 0xc4, 0x89, 0xe7, 0x91, 0xf9, 0xe4, 0xa9, 0x6e, 0xcc, 0xd2, 0xcd, 0xaf, 0x90, 0x78, 0x24, 0x00, 0x4b, 0xc0, 0xc2, 0xf5, 0x4f, 0xef, 0x97, 0x9f, 0xdc, 0x5e, 0x59, 0x82, 0x34, 0x61, 0x32, 0x79, 0xe2, 0xdb, 0x1f, 0x22, 0xf3, 0x45, 0x9d, 0x3e, 0xa3, 0x2a, 0x7d, 0x8d, 0x81, 0xfd, 0xfd, 0xf5, 0xd5, 0xa9, 0x8b, 0xf9, 0x5b, 0x0b, 0xb3, 0xc8, 0x59, 0x7e, 0x00, 0x58, 0x02, 0x36, 0xa6, 0xee, 0x31, 0x7b, 0xa8, 0x44, 0x75, 0x3c, 0xe3, 0xb3, 0xce, 0xa8, 0x6c, 0x9d, 0x9f, 0x4c, 0x7b, 0xb7, 0x28, 0x71, 0x46, 0xeb, 0xf7, 0xb1, 0x2f, 0x96, 0x33, 0x43, 0xcb, 0xef, 0x13, 0xf6, 0x27, 0x7b, 0x2b, 0x10, 0x3d, 0xd7, 0x17, 0x02, 0x4b, 0x40, 0xac, 0xbe, 0x22, 0x32, 0x23, 0x13, 0xc2, 0xda, 0xd7, 0x56, 0xfe, 0xb8, 0x7c, 0xc1, 0x74, 0xe7, 0x07, 0x5f, 0x29, 0xf6, 0xf9, 0x5c, 0x5b, 0xff, 0x3e, 0x78, 0x53, 0xb7, 0x3a, 0xd4, 0x03, 0x5e, 0xb1, 0x34, 0x5c, 0xfd, 0x7a, 0x75, 0xb8, 0xfa, 0xd9, 0x7d, 0x88, 0x60, 0x07, 0x70, 0x2a, 0x81, 0x73, 0xb9, 0xb6, 0x6d, 0xf7, 0x2f, 0x64, 0xdd, 0x3d, 0x25, 0x82, 0xcf, 0xd4, 0xa5, 0x42, 0x64, 0xa8, 0xc7, 0xbf, 0xf5, 0x33, 0x60, 0xf8, 0x36, 0x19, 0x6e, 0x23, 0xf1, 0x48, 0x00, 0x56, 0x07, 0xa0, 0x58, 0x94, 0x24, 0x5c, 0xa9, 0x7b, 0x85, 0xa9, 0x9a, 0x6d, 0x71, 0x0e, 0x59, 0x3e, 0xdb, 0x82, 0x1b, 0xa3, 0x3a, 0x7b, 0x1e, 0x89, 0x47, 0x02, 0x70, 0x05, 0x40, 0x02, 0x4a, 0x22, 0x45, 0xa6, 0xf1, 0x09, 0xa0, 0x68, 0x9e, 0x13, 0xb9, 0xd1, 0x08, 0x08, 0xe0, 0x86, 0x0b, 0xbd, 0x2d, 0x08, 0xe0, 0xd4, 0xdc, 0x69, 0x35, 0x8b, 0x5c, 0x4e, 0x8e, 0xc3, 0x87, 0xe9, 0x34, 0x3f, 0xf6, 0xe1, 0xc5, 0x70, 0x11, 0xf8, 0x3f, 0x20, 0x8d, 0x55, 0x33, 0x04, 0x9c, 0x9b, 0x56, 0xf8, 0xb9, 0x1f, 0x53, 0xf8, 0x72, 0x64, 0xc6, 0x69, 0xf9, 0x09, 0xad, 0x07, 0x2b, 0x53, 0xff, 0x8f, 0x4e, 0xcb, 0x93, 0x47, 0x37, 0xaf, 0x31, 0x7e, 0x69, 0x6c, 0xbc, 0x07, 0x80, 0xdf, 0x90, 0x80, 0x80, 0xe8, 0x33, 0x67, 0x29, 0x9a, 0xde, 0x71, 0x38, 0x80, 0xc1, 0x3f, 0x3f, 0xdf, 0x80, 0x4f, 0xd2, 0xbb, 0x1f, 0x25, 0x7a, 0x09, 0x78, 0x78, 0xe5, 0x22, 0x97, 0x62, 0x4c, 0xa1, 0x9e, 0x3b, 0xe4, 0x6d, 0x13, 0x78, 0x06, 0xe4, 0x9a, 0x93, 0xa9, 0x0d, 0xd7, 0xe0, 0xad, 0x14, 0x38, 0x89, 0xa8, 0x53, 0x79, 0x9a, 0xf7, 0xdb, 0x03, 0xc7, 0xfb, 0x41, 0x52, 0xf0, 0xa6, 0xf0, 0x73, 0x3b, 0xf0, 0x5b, 0xdb, 0xcb, 0x8b, 0x1b, 0x0f, 0xee, 0x31, 0xa7, 0x12, 0x91, 0xe9, 0x99, 0x3e, 0x96, 0x90, 0xe1, 0x16, 0x13, 0x4d, 0x1a, 0x97, 0xa0, 0xc8, 0xd1, 0x89, 0x28, 0x02, 0xb5, 0x83, 0x80, 0xc4, 0x04, 0x04, 0x2e, 0x95, 0x2c, 0x92, 0x4c, 0x19, 0xc8, 0x72, 0x0a, 0x2a, 0x9a, 0x20, 0x20, 0xa8, 0x72, 0x1d, 0x02, 0x58, 0xe8, 0xc0, 0x21, 0x14, 0x35, 0xa8, 0x90, 0x84, 0x3b, 0x70, 0xfd, 0xe9, 0x15, 0x14, 0x03, 0x4c, 0x30, 0xc9, 0x6d, 0x74, 0x6b, 0x6b, 0x2b, 0x22, 0x22, 0x22, 0x2c, 0x2c, 0x6c, 0x73, 0x73, 0x93, 0xa6, 0x09, 0xbc, 0xe3, 0x03, 0xd1, 0x46, 0x38, 0x4d, 0x74, 0x74, 0xb4, 0x5c, 0x2e, 0x0f, 0x19, 0x7b, 0x50, 0x48, 0xb2, 0x03, 0x10, 0xce, 0xe5, 0x72, 0xc1, 0xb7, 0x58, 0x8c, 0x5e, 0x99, 0x80, 0x0c, 0x04, 0x86, 0x6c, 0x02, 0x81, 0x0e, 0x8c, 0x8e, 0x8e, 0x36, 0x35, 0x35, 0xc1, 0xb2, 0x61, 0x93, 0x55, 0x54, 0x54, 0xd4, 0xd5, 0xd5, 0xb1, 0x43, 0x30, 0x7a, 0x7b, 0x7b, 0xbb, 0xba, 0xba, 0xfa, 0xfb, 0xfb, 0x2d, 0x16, 0x8b, 0x56, 0xab, 0x85, 0xc5, 0x96, 0x94, 0x94, 0xd4, 0xd7, 0xd7, 0xc7, 0xc5, 0xf0, 0xb3, 0xc9, 0x08, 0x18, 0x1e, 0x1e, 0xe6, 0xa6, 0x4f, 0x4b, 0x4b, 0xe3, 0x0e, 0x07, 0x07, 0x07, 0xcb, 0xcb, 0x77, 0xcf, 0x51, 0xf4, 0x7a, 0xbd, 0xd3, 0xe9, 0x84, 0x21, 0xfc, 0x00, 0xb3, 0xdb, 0xed, 0x5c, 0x0c, 0x6f, 0x9b, 0x80, 0x80, 0xda, 0xda, 0xda, 0xfc, 0xfc, 0x7c, 0xab, 0xd5, 0x0a, 0x24, 0x3a, 0x3b, 0x3b, 0xbb, 0xbb, 0xbb, 0x3d, 0xd8, 0x18, 0x0c, 0x06, 0xf0, 0x40, 0xe1, 0xa1, 0x03, 0x60, 0xcc, 0xcf, 0xcf, 0x37, 0x37, 0x37, 0x83, 0x12, 0x0f, 0x18, 0xbf, 0x21, 0x01, 0x01, 0xf0, 0xd4, 0x96, 0x95, 0x95, 0x31, 0xe9, 0xc7, 0xc7, 0xc7, 0xbd, 0x79, 0x14, 0x14, 0x14, 0x80, 0x73, 0x7a, 0x7a, 0x3a, 0x2b, 0x2b, 0xab, 0xa4, 0xa4, 0x24, 0x3b, 0x3b, 0xbb, 0xb1, 0xb1, 0x51, 0xa3, 0xd1, 0x78, 0x23, 0xf9, 0x78, 0x90, 0x07, 0x2f, 0x41, 0x01, 0x1a, 0x1a, 0x1a, 0x80, 0x44, 0x65, 0x65, 0x25, 0x77, 0x16, 0xac, 0x16, 0x9d, 0x6e, 0xdf, 0xa1, 0x1d, 0x45, 0x51, 0x35, 0x35, 0x35, 0x5c, 0x0c, 0x6f, 0x1b, 0xbd, 0x5d, 0xf0, 0xa9, 0xca, 0xfe, 0x39, 0xb0, 0xab, 0x0e, 0x0c, 0x0c, 0x18, 0x8d, 0xc6, 0xfa, 0xfa, 0xfa, 0xe2, 0xe2, 0x62, 0x89, 0x44, 0x02, 0x74, 0x3b, 0x3a, 0x3a, 0xe6, 0xe6, 0xdc, 0x67, 0x44, 0xfb, 0x67, 0x04, 0x31, 0x0a, 0x85, 0x80, 0xb6, 0xb6, 0x36, 0xd8, 0x73, 0x60, 0x9b, 0x6a, 0x6d, 0x6d, 0x1d, 0x19, 0x19, 0x99, 0x99, 0x99, 0x91, 0xc9, 0x64, 0xa0, 0x61, 0x68, 0x68, 0x28, 0x08, 0xa6, 0x07, 0x40, 0x09, 0x3c, 0x03, 0x07, 0x44, 0x76, 0xbb, 0xa1, 0xd2, 0x26, 0x93, 0xa9, 0xb4, 0xb4, 0x14, 0x96, 0x4d, 0x6e, 0x6e, 0xee, 0xe4, 0xe4, 0xa4, 0xcd, 0x66, 0x83, 0x97, 0x00, 0x3c, 0xfa, 0x6e, 0x10, 0x5f, 0x8b, 0xb0, 0x00, 0x60, 0xe6, 0xcd, 0x44, 0xa1, 0x50, 0xc0, 0xa2, 0x87, 0x85, 0xd4, 0xde, 0xbe, 0xf7, 0x3f, 0x38, 0x2e, 0x2e, 0xae, 0xa5, 0xa5, 0x25, 0x33, 0x73, 0xf7, 0x60, 0x18, 0xf3, 0x22, 0x2c, 0x00, 0xb6, 0x48, 0x20, 0x94, 0x90, 0x90, 0xc0, 0xa5, 0x05, 0x4f, 0x76, 0x75, 0x75, 0x75, 0x4a, 0x4a, 0xca, 0xec, 0xec, 0xec, 0xda, 0xda, 0x9a, 0x4a, 0xa5, 0x4a, 0x4e, 0x4e, 0x96, 0x4a, 0x09, 0x9c, 0x2b, 0x42, 0x16, 0x02, 0x02, 0x7a, 0x7a, 0x7a, 0x26, 0x26, 0x26, 0xd4, 0x6a, 0x35, 0xec, 0xa1, 0xcc, 0xcb, 0xb5, 0xa8, 0xa8, 0x88, 0x2b, 0xe0, 0xd8, 0xd3, 0x0b, 0x3c, 0xe9, 0xe9, 0xe9, 0x5c, 0x3f, 0x19, 0x9b, 0xf7, 0xfe, 0xc5, 0x4e, 0x64, 0xde, 0xb2, 0x2c, 0x9b, 0xaa, 0xaa, 0x2a, 0xf6, 0x56, 0x08, 0x0c, 0x02, 0x3f, 0xe6, 0x96, 0x97, 0x97, 0x61, 0x3f, 0x81, 0xc5, 0xa3, 0x54, 0x2a, 0xf3, 0xf2, 0xf2, 0x72, 0x72, 0x72, 0x58, 0x31, 0x21, 0x30, 0x08, 0x08, 0x08, 0x01, 0x4b, 0x3f, 0x29, 0x42, 0xf1, 0x1e, 0xf0, 0x93, 0x1e, 0xff, 0x96, 0x20, 0x00, 0xbf, 0x86, 0x78, 0x11, 0x84, 0x0e, 0xe0, 0xd5, 0x0f, 0x7f, 0xb6, 0xd0, 0x01, 0xfc, 0x1a, 0xe2, 0x45, 0x38, 0xf2, 0x1d, 0xf8, 0x0f, 0x1c, 0x65, 0x73, 0xb3, 0xdd, 0xbe, 0x50, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXPlistIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x33, 0x35, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc8, 0x4f, 0xd5, 0xc2, 0x00, 0x00, 0x06, 0xa8, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x7b, 0x4c, 0x53, 0x57, 0x18, 0xb7, 0xef, 0x77, 0x91, 0x87, 0x82, 0x20, 0x68, 0x01, 0xd1, 0xf8, 0x20, 0x6e, 0x09, 0xd1, 0x44, 0xc1, 0xcc, 0xa0, 0xce, 0x4c, 0x0d, 0xfc, 0xb7, 0x11, 0xa6, 0x93, 0xb0, 0x65, 0x53, 0x18, 0x31, 0x41, 0xcd, 0x4c, 0x4c, 0x96, 0x25, 0xfe, 0xb3, 0xa0, 0x46, 0x8c, 0x61, 0x03, 0x5f, 0x7f, 0xb0, 0x31, 0x46, 0x74, 0x31, 0x6e, 0xcb, 0x62, 0x80, 0x6c, 0x73, 0x8a, 0x12, 0xc5, 0xa0, 0x19, 0xbe, 0x98, 0x48, 0x43, 0x71, 0x56, 0x94, 0xd2, 0x07, 0xa5, 0x94, 0xb6, 0xfb, 0xe1, 0x71, 0xb7, 0x87, 0xdb, 0xf6, 0xda, 0x7b, 0x5b, 0x75, 0x66, 0xbd, 0x69, 0x9a, 0xef, 0x7c, 0x8f, 0xdf, 0xf9, 0x5e, 0xe7, 0x3b, 0xed, 0x15, 0xf9, 0x7c, 0xbe, 0x69, 0xaf, 0xf3, 0x23, 0x7e, 0x9d, 0x9d, 0x9f, 0xf4, 0x3d, 0x16, 0xc0, 0xab, 0xae, 0x60, 0xac, 0x02, 0xb1, 0x0a, 0x44, 0x98, 0x81, 0x58, 0x0b, 0x45, 0x98, 0xc0, 0x88, 0xcd, 0x63, 0x15, 0x88, 0x38, 0x85, 0x11, 0x02, 0xc4, 0x2a, 0x10, 0x61, 0x02, 0x23, 0x36, 0x8f, 0x55, 0x20, 0x58, 0x0a, 0x87, 0xdc, 0xde, 0x40, 0xb6, 0xcd, 0xe3, 0xf3, 0x04, 0x72, 0x23, 0xe6, 0x44, 0xb9, 0x02, 0x5d, 0xd6, 0xf1, 0x0f, 0xba, 0x1f, 0xcf, 0x6b, 0x37, 0x05, 0x3a, 0xf6, 0xfb, 0xe3, 0xb1, 0xcc, 0x36, 0xd3, 0x97, 0x7f, 0x59, 0x87, 0x83, 0x85, 0x17, 0xa8, 0x1f, 0x26, 0x47, 0x14, 0x95, 0xff, 0x03, 0x48, 0xed, 0x0f, 0x0f, 0x46, 0x0f, 0xf5, 0xd9, 0xfe, 0x78, 0x32, 0x86, 0x8d, 0x95, 0x12, 0x91, 0x73, 0x7d, 0x06, 0xcb, 0x83, 0x9f, 0xcc, 0xce, 0x0d, 0x9d, 0x66, 0x30, 0xd5, 0x12, 0xf1, 0xfb, 0xb3, 0x35, 0x9f, 0x1a, 0x74, 0x0b, 0xb5, 0x32, 0x96, 0x8e, 0x80, 0xa5, 0x54, 0x80, 0x0d, 0x6d, 0xf2, 0xc4, 0xed, 0x3d, 0x6a, 0xb4, 0x1f, 0xb9, 0x6f, 0x33, 0x3a, 0x27, 0x68, 0x3e, 0x07, 0x3d, 0xea, 0xf1, 0x7e, 0xdd, 0x6f, 0xc3, 0xa7, 0x70, 0x86, 0xaa, 0xca, 0xa0, 0x7b, 0x67, 0xa6, 0x4a, 0xc4, 0xa1, 0xfd, 0x3c, 0x91, 0xf0, 0x00, 0xfe, 0xb4, 0xbb, 0x6b, 0xfb, 0x6c, 0x8d, 0x03, 0x0e, 0x38, 0x44, 0xef, 0x32, 0x4b, 0x29, 0xdd, 0x9a, 0xae, 0xa1, 0x39, 0x84, 0xce, 0xd5, 0xcb, 0x4b, 0x67, 0x6b, 0x4f, 0x3d, 0x18, 0x75, 0xfe, 0xab, 0xdf, 0xfa, 0xc8, 0x89, 0x4f, 0xb6, 0x46, 0x56, 0x31, 0x57, 0xb7, 0x35, 0x5d, 0xab, 0x97, 0x0a, 0x09, 0x84, 0x77, 0x0b, 0xc1, 0xd9, 0x9f, 0xcd, 0x4e, 0x74, 0x0b, 0xf6, 0xa6, 0xbd, 0x94, 0x89, 0x45, 0x1b, 0x92, 0x55, 0x65, 0xe9, 0xda, 0xf5, 0x33, 0x55, 0x12, 0x5a, 0x30, 0x95, 0xb6, 0x4c, 0xf8, 0xbe, 0x35, 0x39, 0x8e, 0x1a, 0x6d, 0xd7, 0x46, 0xc6, 0x69, 0x89, 0x4e, 0x2a, 0x46, 0x0c, 0x95, 0x06, 0x5d, 0xb6, 0x9a, 0x5f, 0x4e, 0x79, 0x07, 0xb0, 0xbe, 0xd3, 0xfc, 0x8b, 0x79, 0x8a, 0xeb, 0x8b, 0xf5, 0x72, 0xf8, 0x5d, 0x9a, 0xa6, 0x99, 0x21, 0xe7, 0x31, 0x12, 0xae, 0x59, 0xdd, 0x08, 0x03, 0xc1, 0x58, 0xa8, 0x33, 0x2d, 0x12, 0x89, 0xea, 0x73, 0x13, 0xca, 0xd3, 0xb5, 0x74, 0x6c, 0xdc, 0x34, 0xbf, 0x70, 0x81, 0x35, 0x34, 0xee, 0x6f, 0x98, 0xe2, 0x59, 0xea, 0xcf, 0xb2, 0xe3, 0xf2, 0xe2, 0xe4, 0xdc, 0x7b, 0x04, 0x95, 0xbe, 0xa1, 0x97, 0x1d, 0x59, 0x9c, 0x50, 0xb3, 0x30, 0x1e, 0x4d, 0xf5, 0xc5, 0xdd, 0x91, 0xbb, 0x76, 0x37, 0xd4, 0x30, 0x51, 0xcc, 0x2e, 0x3f, 0x7e, 0x50, 0x43, 0x16, 0x93, 0x77, 0x00, 0xb4, 0xfd, 0x8f, 0x0f, 0x9d, 0xe2, 0x69, 0xa2, 0x8f, 0xe6, 0x68, 0xd7, 0x24, 0x29, 0x05, 0xf4, 0xaf, 0xd3, 0xeb, 0xfb, 0x7e, 0x70, 0x14, 0x33, 0x80, 0x78, 0x4f, 0x23, 0x87, 0x4f, 0xf3, 0x0e, 0xe0, 0xc3, 0x0c, 0xad, 0xd9, 0xe5, 0x21, 0x33, 0xc7, 0xed, 0xf5, 0x9d, 0x7a, 0xe0, 0xc0, 0x67, 0xae, 0x5a, 0x5a, 0x9e, 0x81, 0x83, 0xa8, 0x49, 0x55, 0x70, 0xf4, 0xbf, 0xdf, 0x2b, 0xd2, 0x3f, 0xdf, 0x98, 0x1c, 0x23, 0x54, 0xff, 0x40, 0x5c, 0x90, 0xa8, 0x5c, 0x33, 0x43, 0xe9, 0xd7, 0x0b, 0x83, 0xe2, 0x7d, 0x06, 0x80, 0xc9, 0x9a, 0xfa, 0xcc, 0x2e, 0x52, 0xb1, 0x08, 0x33, 0x11, 0x11, 0xbe, 0x1d, 0xe2, 0x1c, 0x5b, 0x27, 0x7c, 0x4d, 0x83, 0x8e, 0x06, 0xa3, 0xfd, 0xaa, 0xc5, 0xc5, 0x58, 0x81, 0x90, 0x8b, 0x45, 0xef, 0xa5, 0x69, 0xaa, 0x0c, 0x7a, 0xf4, 0x15, 0xcd, 0x0f, 0x87, 0x16, 0x12, 0x00, 0x83, 0x7b, 0x75, 0x64, 0x1c, 0xe3, 0xa8, 0x79, 0xd0, 0x31, 0xee, 0x9d, 0xf2, 0x76, 0x2c, 0x4b, 0x23, 0xeb, 0x7d, 0x2b, 0x95, 0x51, 0x23, 0x44, 0x87, 0x65, 0xbc, 0xb0, 0xe3, 0x21, 0x6b, 0xe6, 0x26, 0x2b, 0x24, 0x9f, 0xcc, 0xd5, 0x7d, 0x3c, 0x47, 0x97, 0xcc, 0x67, 0x00, 0xd0, 0xc8, 0x11, 0x05, 0x40, 0x80, 0xfe, 0x76, 0x79, 0xbf, 0xea, 0xb7, 0xd5, 0xf5, 0xdb, 0xd0, 0x5a, 0x84, 0xc3, 0x7d, 0x13, 0x13, 0x9d, 0x37, 0xe3, 0x14, 0xb8, 0xc5, 0xde, 0x4d, 0xd3, 0xc8, 0x05, 0x9c, 0x1e, 0x2a, 0x02, 0xde, 0x67, 0x80, 0xb2, 0x7d, 0x46, 0xa6, 0x28, 0xc4, 0x9f, 0xe7, 0xc4, 0x61, 0x1c, 0x7d, 0x37, 0xe8, 0x38, 0xd4, 0x67, 0x65, 0x0d, 0x78, 0x96, 0xbe, 0x44, 0x24, 0x2a, 0x4a, 0x51, 0xc3, 0xf5, 0xfc, 0x04, 0x05, 0x4b, 0x24, 0x70, 0x89, 0xc9, 0x15, 0xdd, 0xe7, 0xb7, 0xc7, 0x63, 0x25, 0x5d, 0x8f, 0x02, 0x31, 0xc1, 0xaf, 0xee, 0x19, 0xbe, 0x3f, 0x3a, 0x11, 0x28, 0x8a, 0x84, 0x13, 0x85, 0x16, 0x12, 0x98, 0xb9, 0x28, 0x99, 0xf1, 0xb8, 0x3b, 0xa3, 0xb4, 0x63, 0x94, 0x61, 0x62, 0x01, 0x44, 0x39, 0xa1, 0xbc, 0xe1, 0x62, 0x15, 0xe0, 0x9d, 0xb2, 0x28, 0x1b, 0xc4, 0x2a, 0x10, 0xe5, 0x84, 0xf2, 0x86, 0xfb, 0x7f, 0x57, 0x60, 0xe2, 0xe9, 0xe3, 0xf5, 0x86, 0xfc, 0x0b, 0x02, 0xf9, 0x81, 0x03, 0x07, 0x4e, 0x9f, 0x3e, 0xcd, 0x3b, 0xb1, 0xe1, 0x1b, 0x08, 0xbb, 0xc6, 0x7b, 0x7b, 0x7b, 0x13, 0x12, 0x12, 0xc8, 0x2e, 0xd3, 0xa7, 0x4f, 0x0f, 0x05, 0x72, 0xfb, 0xf6, 0x6d, 0xe8, 0x64, 0x66, 0x66, 0x86, 0x52, 0xe0, 0xe0, 0xbb, 0xdd, 0xee, 0xf6, 0xf6, 0xf6, 0xc1, 0xc1, 0x41, 0x0e, 0x1d, 0x88, 0x04, 0xb6, 0x90, 0x4e, 0xa7, 0x9b, 0x3f, 0x7f, 0x7e, 0x6a, 0xea, 0xe4, 0x6f, 0x66, 0x87, 0xc3, 0x11, 0x2a, 0x5f, 0x72, 0xb9, 0x5c, 0xa1, 0x50, 0xa4, 0xa5, 0xa5, 0x85, 0x52, 0xe0, 0xe0, 0x9f, 0x3b, 0x77, 0x6e, 0xf5, 0xea, 0xd5, 0xe5, 0xe5, 0xe5, 0x1c, 0x3a, 0x93, 0x22, 0xee, 0xf8, 0xb8, 0xa5, 0x57, 0xae, 0x5c, 0x01, 0x82, 0x4c, 0x26, 0xe3, 0x50, 0x43, 0x22, 0x39, 0xa4, 0xb4, 0xc8, 0xe3, 0xf1, 0xd0, 0xcb, 0x93, 0x27, 0x4f, 0x02, 0x3c, 0x2f, 0x2f, 0x8f, 0x66, 0x06, 0xd2, 0x41, 0x2a, 0xb0, 0x77, 0xef, 0xde, 0x65, 0xcb, 0x96, 0xad, 0x5d, 0xbb, 0xb6, 0xb3, 0xb3, 0x73, 0xf9, 0xf2, 0xe5, 0x6a, 0xb5, 0x7a, 0xc9, 0x92, 0x25, 0x35, 0x35, 0x35, 0x1c, 0xbd, 0x8e, 0x9d, 0x02, 0x9f, 0xcd, 0x9b, 0x37, 0x03, 0x67, 0xc5, 0x8a, 0x15, 0x2b, 0x57, 0xae, 0xb4, 0x58, 0x2c, 0x2c, 0x85, 0xb3, 0x67, 0xcf, 0x6e, 0xd9, 0xb2, 0x25, 0x39, 0x39, 0x19, 0xf8, 0xf0, 0x32, 0x37, 0x37, 0x77, 0xd3, 0xa6, 0x4d, 0x8c, 0xce, 0xcd, 0x9b, 0x37, 0x6f, 0xdd, 0xba, 0x85, 0xa5, 0xcd, 0x66, 0xfb, 0xf5, 0xe9, 0x03, 0x67, 0x70, 0xa2, 0x18, 0x05, 0x3f, 0x11, 0x18, 0x93, 0xc1, 0x60, 0x20, 0x62, 0x8d, 0x66, 0xca, 0xfb, 0xa9, 0xd2, 0xd2, 0x52, 0x96, 0x32, 0x47, 0x05, 0xb0, 0xb1, 0x54, 0xea, 0xff, 0xb3, 0xd1, 0xd7, 0xd7, 0x47, 0xdb, 0xb6, 0xb6, 0xb6, 0x92, 0x2d, 0xd6, 0xad, 0x5b, 0x57, 0x58, 0x58, 0x88, 0xb7, 0x29, 0x58, 0x2e, 0x58, 0xb0, 0x80, 0xe8, 0x74, 0x75, 0x75, 0xf9, 0xfd, 0xa3, 0xa8, 0x7d, 0xfb, 0xf6, 0xd1, 0x20, 0x84, 0x0e, 0xd2, 0x42, 0xf7, 0xee, 0xdd, 0x43, 0x62, 0x60, 0x18, 0x1f, 0x1f, 0x5f, 0x5f, 0x5f, 0x7f, 0xfd, 0xfa, 0xf5, 0xe2, 0xe2, 0x62, 0x82, 0x83, 0x8d, 0x69, 0x08, 0x8e, 0x00, 0xa0, 0x76, 0xe3, 0xc6, 0x8d, 0xe6, 0xe6, 0x66, 0x62, 0xc8, 0x0a, 0x60, 0xe7, 0xce, 0x9d, 0xe0, 0x2f, 0x5a, 0xb4, 0x88, 0xa0, 0x41, 0x5a, 0x56, 0x56, 0x86, 0x82, 0x90, 0xa5, 0xd9, 0x6c, 0xce, 0xcf, 0xcf, 0x27, 0x3e, 0xe0, 0x08, 0xcd, 0x7b, 0xfa, 0x2c, 0x5d, 0xba, 0x14, 0xa7, 0x82, 0x28, 0xd0, 0xdf, 0x41, 0x02, 0x80, 0x18, 0x73, 0x03, 0x1b, 0x6c, 0xdb, 0xb6, 0x8d, 0xa8, 0x0e, 0x0d, 0x0d, 0x49, 0x24, 0x93, 0xaf, 0x1b, 0x76, 0xef, 0xde, 0x4d, 0x1b, 0x73, 0x07, 0x00, 0x4d, 0xa7, 0xf3, 0xd9, 0x2b, 0x30, 0x56, 0x00, 0x2d, 0x2d, 0x2d, 0x24, 0x30, 0x74, 0x4e, 0x65, 0x65, 0xe5, 0xf1, 0xe3, 0xc7, 0x91, 0x35, 0x1a, 0x19, 0xb4, 0xf0, 0x33, 0x40, 0xa0, 0xf1, 0xbd, 0x6a, 0xd5, 0x2a, 0x42, 0x27, 0x26, 0x26, 0x22, 0x5b, 0xa0, 0x07, 0x06, 0x06, 0x18, 0x69, 0x24, 0x44, 0x51, 0x51, 0x11, 0x0e, 0x06, 0x10, 0x50, 0xde, 0xc3, 0x87, 0x0f, 0x23, 0xfd, 0x59, 0x59, 0x59, 0xdb, 0xb7, 0x6f, 0x17, 0x80, 0x19, 0xe4, 0x10, 0x33, 0x28, 0x17, 0x2e, 0x5c, 0x20, 0xf4, 0xf0, 0xf0, 0x70, 0x4f, 0x4f, 0x0f, 0x68, 0xe6, 0x78, 0x30, 0x3a, 0xc2, 0x08, 0x1c, 0x0f, 0xf4, 0x43, 0x77, 0x77, 0xf7, 0xae, 0x5d, 0xbb, 0x0a, 0x0a, 0x0a, 0xc8, 0x1c, 0xab, 0xab, 0xab, 0x43, 0xa1, 0x18, 0x40, 0xb1, 0x78, 0xd2, 0x37, 0xbb, 0xdd, 0xce, 0x70, 0x82, 0x13, 0xac, 0xc2, 0x91, 0x25, 0x69, 0xa1, 0xa4, 0xa4, 0xa4, 0xa6, 0xa6, 0x26, 0x14, 0xb7, 0xa4, 0xa4, 0x84, 0x18, 0x9f, 0x3f, 0x7f, 0x9e, 0xd1, 0xc7, 0x7c, 0xbc, 0x7c, 0xf9, 0x32, 0xf8, 0xd8, 0x1e, 0x34, 0x46, 0x04, 0x23, 0x22, 0x04, 0x38, 0x38, 0xca, 0xc4, 0x10, 0x17, 0x1f, 0x3d, 0x4f, 0xf7, 0xef, 0xdf, 0x0f, 0xf0, 0x8e, 0x8e, 0x0e, 0xa2, 0x69, 0x34, 0x1a, 0x95, 0xca, 0xc9, 0xf7, 0x59, 0xc7, 0x8e, 0x1d, 0x63, 0x40, 0xce, 0x9c, 0x39, 0x03, 0x0e, 0x5a, 0x17, 0x0e, 0x8c, 0x8d, 0x8d, 0xb5, 0xb5, 0xb5, 0xa1, 0xa5, 0xd1, 0x57, 0x8c, 0x02, 0x21, 0xb8, 0xce, 0x00, 0xd9, 0x9b, 0xf9, 0xc6, 0x58, 0x24, 0x36, 0x56, 0xab, 0x35, 0xe8, 0xdd, 0x84, 0xc9, 0xcb, 0xa0, 0x63, 0x32, 0x32, 0x86, 0x0c, 0x91, 0x9d, 0x9d, 0xed, 0x72, 0xb9, 0xa0, 0x53, 0x51, 0x51, 0x01, 0x26, 0x0e, 0xe8, 0x8e, 0x1d, 0x3b, 0x1a, 0x1b, 0x1b, 0xab, 0xab, 0xab, 0xb1, 0x44, 0xca, 0xd1, 0x51, 0x0c, 0x02, 0xb9, 0xc5, 0x09, 0x5f, 0xa5, 0x52, 0x11, 0x10, 0x7a, 0x0b, 0xa2, 0xc9, 0x15, 0xc0, 0x9e, 0x3d, 0x7b, 0x30, 0x0d, 0x52, 0x52, 0x52, 0x70, 0x1b, 0x1c, 0x3c, 0x78, 0x10, 0xf7, 0x00, 0xb1, 0x41, 0x00, 0x19, 0x19, 0x19, 0x04, 0x91, 0xfe, 0xc6, 0x4c, 0x64, 0xb6, 0xc7, 0x0d, 0x40, 0x8b, 0x08, 0x9d, 0x93, 0x93, 0x83, 0x5c, 0x42, 0x07, 0xc8, 0x18, 0x9d, 0xf4, 0x98, 0x46, 0x41, 0x1a, 0x1a, 0x1a, 0x18, 0x73, 0x42, 0xd4, 0xd6, 0xd6, 0xe2, 0xca, 0x87, 0x2d, 0x62, 0xc3, 0x90, 0xc5, 0xad, 0x6c, 0x32, 0x99, 0x58, 0x3a, 0x5c, 0x01, 0x5c, 0xbc, 0x78, 0x91, 0xa5, 0x1d, 0xad, 0x25, 0x5a, 0x0b, 0x4d, 0x85, 0x1e, 0xbb, 0x73, 0xe7, 0xce, 0xa5, 0x4b, 0x97, 0xf0, 0x4d, 0x2a, 0x13, 0x88, 0x8f, 0xac, 0xf5, 0xf7, 0xf7, 0x23, 0x65, 0x81, 0x22, 0xc2, 0x61, 0x07, 0x80, 0x2b, 0x13, 0x8d, 0x88, 0xb1, 0x83, 0xb8, 0xab, 0xaa, 0xaa, 0x4e, 0x9c, 0x38, 0xc1, 0x61, 0x1c, 0x0a, 0xf4, 0x65, 0xf2, 0xd9, 0x01, 0xe0, 0xe6, 0x62, 0x95, 0x3e, 0xf0, 0xdc, 0xbc, 0x4c, 0xff, 0x9e, 0xbb, 0x97, 0xff, 0xb6, 0x27, 0x7e, 0x63, 0x42, 0xe3, 0xd7, 0x25, 0x33, 0x3d, 0xf4, 0x7a, 0xfd, 0xc6, 0x8d, 0x1b, 0x59, 0x21, 0xfd, 0xa7, 0x96, 0xb1, 0x37, 0x73, 0xaf, 0xba, 0x1c, 0x5c, 0x37, 0xf1, 0xab, 0xf6, 0x2d, 0xac, 0xfd, 0x63, 0x01, 0x84, 0x95, 0xa6, 0x17, 0xa8, 0x14, 0xab, 0xc0, 0x0b, 0x4c, 0x6e, 0x58, 0xd0, 0xb1, 0x0a, 0x84, 0x95, 0xa6, 0x17, 0xa8, 0xf4, 0x0f, 0x7b, 0x3c, 0x70, 0xd0, 0xa5, 0xfc, 0x34, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXTextIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x33, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xd4, 0x6c, 0xf8, 0x31, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x5b, 0x2c, 0x6c, 0x57, 0x18, 0x9e, 0x61, 0xce, 0x5c, 0x5c, 0xe2, 0x5a, 0xd7, 0x10, 0x97, 0x53, 0xd7, 0xba, 0x3d, 0xd0, 0x3e, 0x20, 0x2a, 0x82, 0x88, 0x22, 0x1e, 0x08, 0xaa, 0x24, 0x08, 0x21, 0x12, 0x11, 0x91, 0xf4, 0xa9, 0x69, 0x1a, 0xf5, 0x26, 0x22, 0xc1, 0x83, 0x04, 0x91, 0xa6, 0x09, 0x5e, 0x2a, 0x8d, 0x34, 0x91, 0xa0, 0xe1, 0xd4, 0x83, 0x07, 0xd2, 0x70, 0x8a, 0xe8, 0x11, 0xe2, 0x1a, 0x8a, 0xc1, 0x30, 0x86, 0x41, 0xbf, 0xb1, 0xcc, 0xea, 0x9c, 0x33, 0xec, 0xd9, 0x33, 0xb3, 0x9c, 0x46, 0xb2, 0x57, 0x64, 0xe7, 0x5f, 0xff, 0xff, 0xfd, 0xf7, 0xb5, 0xd6, 0xac, 0xbd, 0x89, 0xef, 0xee, 0xee, 0x44, 0x2f, 0x79, 0xd8, 0xbc, 0xe4, 0xe0, 0x75, 0xb1, 0x0b, 0x09, 0xfc, 0xdf, 0x1d, 0x14, 0x3a, 0x20, 0x74, 0xc0, 0xca, 0x0a, 0x08, 0x4b, 0xc8, 0xca, 0x02, 0x5a, 0xad, 0x2e, 0x74, 0xc0, 0xea, 0x12, 0x5a, 0x69, 0x40, 0xe8, 0x80, 0x95, 0x05, 0xb4, 0x5a, 0x5d, 0x62, 0xb5, 0x05, 0x9d, 0x01, 0xad, 0xe8, 0x6e, 0x4a, 0xa5, 0x7c, 0xa7, 0x51, 0xdf, 0x9a, 0xba, 0x1a, 0xda, 0x88, 0xc5, 0xaf, 0x65, 0x8a, 0x24, 0x07, 0x67, 0x89, 0x48, 0xcc, 0xc4, 0x35, 0x9b, 0x04, 0x7e, 0x3d, 0xf9, 0x27, 0xff, 0xdd, 0x9f, 0xfc, 0x03, 0xfa, 0x25, 0x38, 0x26, 0xd7, 0xe9, 0x13, 0xfe, 0x78, 0x0e, 0x24, 0x9b, 0x3d, 0xb0, 0xae, 0x51, 0x73, 0xf8, 0x30, 0x16, 0xad, 0x99, 0x89, 0x37, 0xb6, 0x40, 0x39, 0x6c, 0x3a, 0x70, 0x7e, 0x7b, 0x43, 0x2c, 0xba, 0x49, 0xa4, 0x9e, 0xaf, 0xa4, 0xa0, 0x8f, 0xb5, 0xd7, 0xbb, 0xd7, 0x1a, 0xc2, 0xf4, 0x91, 0xca, 0x9c, 0x6d, 0x5f, 0x81, 0xde, 0xbb, 0xd6, 0x1c, 0x69, 0xaf, 0x41, 0x5c, 0xdc, 0xde, 0x12, 0x91, 0xf5, 0x4f, 0x36, 0x1d, 0x50, 0xeb, 0x03, 0xaa, 0x76, 0xf7, 0x7d, 0x1b, 0xfe, 0x05, 0xfe, 0xbe, 0xf7, 0x09, 0xa6, 0xc1, 0xfd, 0xe0, 0x1d, 0x4c, 0x98, 0x95, 0xee, 0xbe, 0x84, 0xa9, 0xbe, 0x7b, 0x48, 0x98, 0x62, 0x2c, 0x26, 0x18, 0x25, 0x70, 0xf7, 0x50, 0x51, 0x99, 0x0d, 0x97, 0x41, 0xb9, 0xf8, 0x41, 0x7a, 0xa9, 0x4f, 0xd8, 0xe2, 0xb8, 0xa9, 0x22, 0x97, 0x3f, 0x0a, 0x32, 0x49, 0xa8, 0xf5, 0x4b, 0x88, 0x86, 0xf8, 0xa8, 0x8a, 0x42, 0x9f, 0x1e, 0xed, 0xd8, 0xa3, 0x30, 0xb3, 0x98, 0x6c, 0x12, 0x08, 0x95, 0xdb, 0x13, 0xaf, 0x81, 0x32, 0x05, 0x87, 0xfb, 0x68, 0x85, 0x23, 0x91, 0x86, 0xc8, 0xed, 0x38, 0x60, 0x66, 0x89, 0xd8, 0x6c, 0xe2, 0x6f, 0x5c, 0xbd, 0x4f, 0x6e, 0xb4, 0x38, 0xda, 0xbf, 0x72, 0x72, 0xe7, 0x70, 0xff, 0xa5, 0xa3, 0xcb, 0x8f, 0xbe, 0xaf, 0x51, 0xfe, 0xaf, 0x5d, 0xbd, 0x38, 0x60, 0x66, 0x89, 0xd8, 0x24, 0xe0, 0x6a, 0x2b, 0xf9, 0xce, 0x2b, 0xd0, 0xa4, 0x63, 0x85, 0xd8, 0xe6, 0x5b, 0xcf, 0x00, 0x93, 0x30, 0xb3, 0x00, 0x6c, 0x96, 0x90, 0x59, 0x2e, 0xd9, 0x82, 0x85, 0x04, 0xd8, 0xd6, 0xd3, 0x7c, 0x6b, 0x2f, 0xbe, 0x03, 0x6c, 0x36, 0x31, 0x2d, 0xdc, 0xd1, 0x8d, 0xf6, 0xaf, 0x4b, 0x15, 0xa6, 0x7f, 0x6b, 0x2e, 0x28, 0x73, 0x55, 0x73, 0xf1, 0xe6, 0x5c, 0x29, 0x16, 0x89, 0xc3, 0xe5, 0xf6, 0xd8, 0xee, 0x94, 0xcf, 0x84, 0x10, 0x33, 0xfc, 0x36, 0xfa, 0xf3, 0xf1, 0x5e, 0xe9, 0xfa, 0x5b, 0x8e, 0x1b, 0x35, 0xee, 0xd2, 0x3f, 0x05, 0x7c, 0x56, 0xe4, 0xe2, 0xc9, 0x24, 0x74, 0x62, 0x84, 0xe5, 0x12, 0xfa, 0x43, 0x75, 0xc2, 0x11, 0x3d, 0xfc, 0x41, 0xfa, 0x46, 0xa5, 0x64, 0x18, 0x3d, 0x4c, 0xb1, 0x4c, 0xa0, 0xc4, 0xd5, 0x2b, 0x4a, 0xe1, 0xc0, 0x11, 0x1f, 0xa4, 0xc0, 0x70, 0x00, 0x2c, 0x10, 0xb1, 0x5c, 0x42, 0x16, 0xb8, 0xb7, 0x5e, 0x85, 0x65, 0x07, 0xac, 0x8f, 0xc6, 0x02, 0x0b, 0x42, 0x02, 0x16, 0x14, 0x8d, 0xa9, 0x8a, 0xd0, 0x01, 0xa6, 0xe5, 0xb4, 0xc0, 0x98, 0xd0, 0x01, 0x0b, 0x8a, 0xc6, 0x54, 0x85, 0x6f, 0x07, 0xb4, 0x5a, 0xed, 0xe4, 0xe4, 0xe4, 0xee, 0xee, 0x2e, 0x53, 0xef, 0xef, 0x19, 0xdb, 0xd8, 0xd8, 0x98, 0x9a, 0x9a, 0x32, 0xfb, 0x6a, 0x03, 0x05, 0x3e, 0x63, 0x74, 0x74, 0x14, 0xde, 0xb2, 0xb2, 0xb2, 0xf8, 0x80, 0x2d, 0xc3, 0xc4, 0xc7, 0xc7, 0xc3, 0xc5, 0xec, 0xec, 0xac, 0x59, 0xea, 0x7c, 0x3b, 0x70, 0x70, 0x70, 0x00, 0xeb, 0xe4, 0xf9, 0x5e, 0xdd, 0xd8, 0x4d, 0x2c, 0x73, 0xc1, 0x2b, 0x81, 0xa5, 0xa5, 0xa5, 0xe5, 0xe5, 0x65, 0x84, 0x7a, 0x76, 0x76, 0xf6, 0xfb, 0xfd, 0x40, 0x9d, 0xb0, 0xa8, 0x0c, 0x83, 0x3f, 0x3d, 0x3d, 0x6d, 0x6c, 0x6c, 0x8c, 0x89, 0x89, 0x71, 0x70, 0x70, 0x88, 0x8c, 0x8c, 0x6c, 0x6e, 0x6e, 0x3e, 0x3f, 0x3f, 0xa7, 0x80, 0xfa, 0xfa, 0xfa, 0xcf, 0xef, 0x47, 0x45, 0x45, 0x05, 0x0a, 0x5c, 0x54, 0x54, 0x84, 0x59, 0x62, 0x62, 0xe2, 0xe0, 0xe0, 0x20, 0x30, 0x2a, 0x95, 0x6a, 0x7a, 0x7a, 0xfa, 0xf2, 0xf2, 0x12, 0xf4, 0xc2, 0xc2, 0x02, 0x71, 0xb1, 0xb3, 0xb3, 0x43, 0xd5, 0xb9, 0x08, 0x93, 0xfd, 0x9a, 0x9b, 0x9b, 0x7b, 0x54, 0xbf, 0xa5, 0xa5, 0x85, 0xea, 0x62, 0x6f, 0xf8, 0xf9, 0xf9, 0x11, 0x98, 0x9b, 0x9b, 0x1b, 0x21, 0x22, 0x22, 0x22, 0x90, 0x03, 0x30, 0x48, 0xd5, 0xde, 0xfe, 0xe1, 0xbb, 0x8b, 0x4c, 0x26, 0x53, 0x2a, 0x95, 0x36, 0xfa, 0x0f, 0x44, 0x25, 0x25, 0x25, 0x00, 0xe4, 0xe4, 0xe4, 0x18, 0xbb, 0xb0, 0xb3, 0xb3, 0xbb, 0xba, 0xba, 0xa2, 0x2e, 0x9e, 0x22, 0x44, 0x4f, 0x09, 0x28, 0x7f, 0x7f, 0x7f, 0x3f, 0x29, 0x29, 0xc9, 0xd3, 0x53, 0x77, 0x89, 0x87, 0xfb, 0x4f, 0xef, 0x47, 0x6c, 0x6c, 0xec, 0xd8, 0xd8, 0x18, 0xc5, 0xe4, 0xe5, 0xe5, 0x41, 0x9a, 0x96, 0x96, 0xb6, 0xb5, 0xb5, 0x05, 0xe6, 0xfc, 0xfc, 0xbc, 0xaf, 0xaf, 0xee, 0x2b, 0x62, 0x53, 0x53, 0x13, 0xc1, 0xa0, 0x81, 0x65, 0x65, 0x65, 0xe0, 0x24, 0x24, 0x24, 0x1c, 0x1f, 0x1f, 0x87, 0x87, 0x87, 0x4b, 0xa5, 0xd2, 0xde, 0xde, 0xde, 0xa3, 0xa3, 0x23, 0x00, 0x3a, 0x3a, 0x3a, 0xc2, 0xc2, 0xc2, 0x24, 0x12, 0xdd, 0xbb, 0x8e, 0x8f, 0x8f, 0x0f, 0x71, 0x51, 0x58, 0x58, 0x48, 0xed, 0x73, 0x10, 0xa6, 0x13, 0x20, 0xca, 0xfd, 0xfd, 0xfd, 0xb0, 0x8e, 0x7d, 0x66, 0x6c, 0x4b, 0xad, 0x56, 0xdb, 0xda, 0xda, 0x42, 0xda, 0xde, 0xde, 0xfe, 0x9b, 0x7e, 0x60, 0xa9, 0x80, 0x13, 0x1d, 0x1d, 0x4d, 0xf1, 0xe8, 0x43, 0x66, 0x66, 0x26, 0x98, 0x5e, 0x5e, 0xba, 0x1b, 0x75, 0x5f, 0x5f, 0x1f, 0x15, 0x11, 0x22, 0x20, 0x20, 0x00, 0x7c, 0x9c, 0x16, 0x1f, 0xf0, 0xb9, 0xa7, 0x0c, 0x5e, 0xf0, 0x56, 0x57, 0x57, 0x6f, 0x6e, 0x74, 0x1f, 0x6b, 0x1b, 0x1a, 0x1a, 0xf0, 0x34, 0x1c, 0x17, 0x17, 0xff, 0xbd, 0x58, 0x22, 0xc9, 0xa1, 0xa1, 0xa1, 0xc0, 0xc0, 0xc0, 0xbd, 0xbd, 0xbd, 0x94, 0x94, 0x94, 0xf2, 0xf2, 0x72, 0x43, 0xa4, 0xc5, 0x34, 0xdf, 0x04, 0xc8, 0xaa, 0xc5, 0x6e, 0x33, 0xf6, 0x84, 0xa6, 0x13, 0x66, 0x4f, 0x4f, 0x4f, 0x54, 0x54, 0x14, 0x05, 0x20, 0xe2, 0x90, 0x90, 0x10, 0x3a, 0x05, 0xd1, 0xd6, 0xd6, 0x76, 0x78, 0x78, 0x28, 0x97, 0xcb, 0xb1, 0x4d, 0x3b, 0x3b, 0x3b, 0xeb, 0xea, 0xea, 0x0c, 0xa5, 0x1c, 0x2e, 0x0c, 0x61, 0x1f, 0xd2, 0xdc, 0x0d, 0xa2, 0xd2, 0x91, 0x91, 0x11, 0x68, 0x22, 0xa6, 0xb5, 0xb5, 0x35, 0x1c, 0x17, 0xe3, 0xe3, 0xe3, 0xb5, 0xb5, 0xb5, 0x58, 0x57, 0x04, 0x10, 0x1a, 0x1a, 0x0a, 0x69, 0x7a, 0x7a, 0x3a, 0xd9, 0xb5, 0x60, 0x2e, 0x2e, 0x2e, 0x56, 0x57, 0x57, 0xb7, 0xb6, 0xb6, 0x52, 0x0b, 0xdd, 0xdd, 0xdd, 0xc0, 0xe0, 0xe4, 0x81, 0xc8, 0xd9, 0xd9, 0x19, 0xe1, 0x0e, 0x0f, 0x0f, 0x53, 0x29, 0x88, 0xb8, 0xb8, 0x38, 0x00, 0xaa, 0xaa, 0xaa, 0xb0, 0xd8, 0xd6, 0xd7, 0xd7, 0xbb, 0xba, 0xba, 0x4a, 0x4b, 0x4b, 0x91, 0xb0, 0x21, 0xc6, 0x98, 0xe6, 0xbb, 0x07, 0x56, 0x56, 0x56, 0x60, 0x1d, 0x03, 0x8e, 0x15, 0x8a, 0x87, 0x2f, 0xb8, 0x88, 0x98, 0x58, 0xc4, 0x8f, 0xb4, 0x58, 0xac, 0xfb, 0x9f, 0x17, 0x44, 0xa9, 0xa9, 0xa9, 0x64, 0x07, 0x63, 0x5a, 0x50, 0x50, 0x40, 0x00, 0xd8, 0xdf, 0x3a, 0x65, 0x91, 0x28, 0x3f, 0x3f, 0x1f, 0x9b, 0xd8, 0xdb, 0xdb, 0x9b, 0x4c, 0x33, 0x32, 0x32, 0x68, 0x4c, 0xc5, 0xc5, 0xc5, 0x84, 0x49, 0x8f, 0x2c, 0x4c, 0x67, 0x66, 0x66, 0x28, 0xe0, 0x51, 0x82, 0x6f, 0x02, 0x50, 0xc6, 0x59, 0xe1, 0xe8, 0xa8, 0xfb, 0xbc, 0x8c, 0x1c, 0x70, 0x68, 0x54, 0x56, 0x56, 0x6e, 0x6f, 0x6f, 0x53, 0xa3, 0x13, 0x13, 0x13, 0x38, 0x9a, 0x48, 0x04, 0x00, 0xe0, 0x9c, 0xa9, 0xa9, 0xa9, 0x21, 0x87, 0x0c, 0x30, 0xf8, 0x09, 0x27, 0xa2, 0xdc, 0xdc, 0x5c, 0x24, 0xe0, 0xe1, 0xe1, 0x81, 0x29, 0x72, 0xce, 0xce, 0xce, 0xa6, 0x16, 0x50, 0xf5, 0xe4, 0xe4, 0x64, 0x02, 0x73, 0x72, 0x72, 0x42, 0x21, 0x06, 0x06, 0x06, 0xa8, 0xf4, 0x29, 0xc2, 0xbc, 0x77, 0x62, 0x58, 0xd9, 0xdc, 0xdc, 0x74, 0x71, 0x71, 0x21, 0x99, 0x10, 0x67, 0x86, 0x4f, 0xfc, 0x9c, 0xe1, 0x4a, 0x13, 0x14, 0x14, 0x64, 0x58, 0x45, 0x43, 0x80, 0x49, 0x1a, 0xdb, 0x0c, 0xcb, 0xc6, 0xdf, 0xdf, 0x9f, 0xb4, 0xd4, 0x24, 0xde, 0xbc, 0x04, 0x4c, 0x9a, 0xfb, 0xf8, 0x00, 0x5e, 0x57, 0x89, 0x8f, 0x1f, 0x16, 0x7f, 0x8f, 0x42, 0x02, 0xfc, 0x6b, 0xf5, 0x3c, 0x48, 0xa1, 0x03, 0xcf, 0x53, 0x57, 0xfe, 0x56, 0x85, 0x0e, 0xf0, 0xaf, 0xd5, 0xf3, 0x20, 0x85, 0x0e, 0x3c, 0x4f, 0x5d, 0xf9, 0x5b, 0x15, 0x3a, 0xc0, 0xbf, 0x56, 0xcf, 0x83, 0xfc, 0x17, 0xab, 0x70, 0xa9, 0x05, 0xf0, 0x5c, 0xd1, 0x77, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXVideoIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x37, 0x39, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xcc, 0x4b, 0x33, 0xb9, 0x00, 0x00, 0x09, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x7b, 0x4c, 0x54, 0xd9, 0x19, 0x9f, 0x99, 0x7b, 0x67, 0x18, 0x9e, 0x83, 0xc0, 0xcc, 0x30, 0x83, 0x2c, 0xa2, 0x80, 0x3c, 0x15, 0x96, 0xe2, 0xae, 0x8f, 0xd4, 0xf5, 0x11, 0x13, 0xb7, 0xb6, 0x31, 0xa6, 0xd5, 0x08, 0x6a, 0xb4, 0xba, 0x3e, 0x6a, 0x1a, 0x13, 0x63, 0xac, 0x35, 0x21, 0x9a, 0xfe, 0x63, 0x62, 0x8d, 0xb1, 0x35, 0x46, 0x8d, 0xd1, 0xac, 0xa6, 0x35, 0xd1, 0xa6, 0x66, 0xdd, 0x9a, 0xad, 0x31, 0x0d, 0x6e, 0xa3, 0x8d, 0x6f, 0x08, 0x6f, 0x99, 0x05, 0x11, 0x81, 0x85, 0x79, 0xc0, 0xbc, 0x98, 0xc7, 0xbd, 0x33, 0xf7, 0x4e, 0x7f, 0x77, 0xce, 0xee, 0x75, 0x32, 0x28, 0x8f, 0x19, 0x08, 0x6b, 0x32, 0x07, 0xb8, 0x7c, 0xe7, 0x9c, 0xef, 0x3b, 0xe7, 0xfb, 0x7d, 0xdf, 0x77, 0xce, 0x77, 0xee, 0xb9, 0xd2, 0x40, 0x20, 0x20, 0xf9, 0x90, 0x8b, 0xec, 0x43, 0x56, 0x5e, 0xd0, 0x3d, 0x06, 0x60, 0xa6, 0x3d, 0x18, 0xf3, 0x40, 0xcc, 0x03, 0x51, 0x5a, 0x60, 0x86, 0x43, 0xe8, 0xd9, 0xb3, 0x67, 0x83, 0x83, 0x83, 0xd1, 0x60, 0x98, 0x19, 0x00, 0x0c, 0xc3, 0xb4, 0xb6, 0x77, 0x9d, 0xf9, 0xeb, 0xc5, 0x23, 0x7f, 0xfc, 0xc3, 0xed, 0xdb, 0x5f, 0x45, 0x03, 0x80, 0x8e, 0x46, 0x78, 0xb2, 0xb2, 0x83, 0x83, 0x16, 0xe3, 0x90, 0xcd, 0x60, 0xe8, 0xf9, 0xde, 0x62, 0x4d, 0x4e, 0x4e, 0xee, 0x1d, 0xb4, 0xf5, 0xf5, 0x7e, 0xff, 0xe2, 0xc5, 0x8b, 0xc9, 0x8e, 0x13, 0xca, 0x1f, 0x15, 0x80, 0xbb, 0x77, 0xef, 0x32, 0x5e, 0x6f, 0x5c, 0x42, 0xb2, 0xcb, 0xed, 0x95, 0x4a, 0xa5, 0x18, 0x97, 0xa6, 0x69, 0xa5, 0x52, 0x91, 0x9c, 0x94, 0xa4, 0xce, 0x48, 0xcb, 0xd4, 0x6a, 0x92, 0x92, 0x92, 0xd0, 0xd8, 0xdf, 0x6f, 0x6c, 0x6c, 0xed, 0xec, 0x37, 0x59, 0x19, 0x2f, 0x23, 0x95, 0xd1, 0x1f, 0x65, 0xeb, 0xca, 0xb4, 0x6a, 0x9e, 0x93, 0x98, 0x4c, 0x96, 0x21, 0xab, 0xfd, 0xf1, 0xe3, 0xc7, 0x0e, 0x87, 0x23, 0x25, 0x25, 0x25, 0x54, 0xad, 0x89, 0xd3, 0x51, 0x01, 0x18, 0x1a, 0x1a, 0xea, 0xea, 0xfc, 0x4e, 0x9d, 0x53, 0x2e, 0x97, 0xcb, 0xe7, 0xcc, 0xce, 0xc0, 0xa1, 0x84, 0x65, 0x39, 0x37, 0xe3, 0xb3, 0xd8, 0x6c, 0xcd, 0x86, 0x01, 0x9b, 0xfd, 0x89, 0x67, 0xc4, 0xe9, 0xb0, 0x19, 0xfb, 0x8c, 0xb6, 0xb4, 0x0c, 0x5d, 0x41, 0x5e, 0xee, 0xec, 0xac, 0xcc, 0xa4, 0xe4, 0x44, 0xc0, 0x18, 0x30, 0x5a, 0xad, 0x56, 0x67, 0xf7, 0xeb, 0x3e, 0xa9, 0x4c, 0x3e, 0x38, 0x68, 0xec, 0xea, 0xea, 0xaa, 0xa8, 0xa8, 0x98, 0xb8, 0xd2, 0xa1, 0x9c, 0x51, 0x01, 0x50, 0x05, 0x8b, 0x5e, 0xa7, 0xcb, 0xc9, 0xd6, 0xe6, 0xe7, 0xea, 0x29, 0x19, 0xdc, 0x00, 0x3f, 0x08, 0x0f, 0x9e, 0x97, 0x70, 0x5c, 0x80, 0xf1, 0xb1, 0x76, 0xa7, 0xbb, 0x7f, 0xc0, 0xdc, 0xfa, 0xb2, 0xeb, 0xf5, 0xab, 0xae, 0xde, 0xbe, 0x3e, 0xf4, 0x26, 0x26, 0x26, 0x3b, 0x9c, 0xae, 0xef, 0xda, 0x5b, 0xf4, 0x9a, 0xa4, 0x3f, 0x1d, 0xaf, 0x8d, 0x53, 0x50, 0x5a, 0xad, 0x36, 0x54, 0xa7, 0x49, 0xd1, 0x51, 0x01, 0xa8, 0xab, 0xab, 0x63, 0x3d, 0x9e, 0xf8, 0xb4, 0x5c, 0x4d, 0xba, 0xca, 0x6e, 0x77, 0xd0, 0x32, 0x4a, 0x4a, 0x41, 0x7b, 0x19, 0x0d, 0x24, 0x40, 0x23, 0x91, 0xc4, 0xc9, 0xa9, 0xcc, 0x8c, 0x94, 0x2c, 0xad, 0x6a, 0x51, 0x79, 0x01, 0xc3, 0xfa, 0x7b, 0x7a, 0x07, 0x9a, 0x5a, 0x0d, 0xf7, 0x1f, 0xd4, 0x1b, 0xda, 0x1b, 0xaa, 0x7f, 0xfd, 0xf9, 0x6f, 0xb7, 0x57, 0xc3, 0x75, 0x93, 0x52, 0x77, 0x34, 0x73, 0x54, 0x00, 0x1a, 0x1a, 0x1a, 0x1c, 0x56, 0x2b, 0x9d, 0xf2, 0x51, 0x6e, 0x4e, 0xae, 0xd5, 0xee, 0xa2, 0x64, 0x28, 0xd0, 0x5f, 0x22, 0x10, 0xf8, 0x93, 0x0a, 0x0f, 0x50, 0x14, 0x25, 0x21, 0xf4, 0x6c, 0x9d, 0x7a, 0xb6, 0x5e, 0xf3, 0xf3, 0x25, 0x95, 0x4f, 0xea, 0x5f, 0xb6, 0xb7, 0xb5, 0x3e, 0x7b, 0xd1, 0xb4, 0xe4, 0xd3, 0xca, 0xd1, 0x3a, 0x4d, 0xaa, 0x25, 0x2a, 0x00, 0x1e, 0x8f, 0x47, 0x4a, 0xd1, 0x0c, 0xcb, 0xf5, 0xf4, 0x9b, 0x38, 0xde, 0x27, 0xa7, 0x69, 0xb9, 0x9c, 0xa2, 0x69, 0x4a, 0x4e, 0x09, 0x4f, 0xc1, 0x17, 0x14, 0x01, 0x22, 0x38, 0xe6, 0x47, 0x54, 0x52, 0x84, 0xd8, 0xa7, 0x1f, 0x17, 0x16, 0xe4, 0xcd, 0xfe, 0xe6, 0xde, 0xa3, 0xaf, 0xbf, 0xf9, 0x0f, 0xcd, 0x3b, 0xf7, 0xed, 0xdb, 0x97, 0x95, 0x95, 0x35, 0x29, 0xbd, 0x45, 0xe6, 0xa8, 0x00, 0x64, 0x66, 0x66, 0x42, 0x43, 0x9b, 0xd5, 0xf2, 0x8f, 0x7f, 0xfe, 0xab, 0xb4, 0xa4, 0x38, 0x0b, 0xb1, 0x92, 0x9c, 0xa8, 0x4a, 0x49, 0x50, 0x25, 0x27, 0xc4, 0xc7, 0x2b, 0x04, 0x00, 0xf8, 0x09, 0x16, 0xc1, 0x1d, 0x32, 0xf8, 0x41, 0x08, 0x2c, 0x50, 0x41, 0x5a, 0xb6, 0xf8, 0x93, 0x8a, 0x53, 0xa7, 0xeb, 0x92, 0x65, 0xce, 0xa6, 0xa6, 0xa6, 0x99, 0x01, 0x70, 0xf2, 0xe4, 0x49, 0xa4, 0xa4, 0x53, 0xa7, 0xff, 0xd2, 0xd3, 0xd1, 0xa8, 0xd5, 0xaa, 0x0b, 0x8b, 0xe7, 0x27, 0x26, 0xd0, 0x71, 0x71, 0x4a, 0xa8, 0xe8, 0xf7, 0x07, 0xa4, 0xd2, 0x80, 0xa0, 0x2e, 0x60, 0xc8, 0xa4, 0x3c, 0x4f, 0xd0, 0x70, 0xa8, 0x52, 0x94, 0x54, 0xc6, 0x07, 0x38, 0xce, 0xef, 0xf3, 0xb1, 0x0a, 0x05, 0x9d, 0xae, 0x4a, 0x17, 0x82, 0x2c, 0xd2, 0x12, 0x95, 0x07, 0x0a, 0x0a, 0x0a, 0x30, 0x6f, 0xda, 0xac, 0x59, 0x99, 0x5a, 0xb5, 0x32, 0x4e, 0x9e, 0xa8, 0xa4, 0x52, 0x92, 0xe2, 0x3b, 0x0d, 0x2f, 0x47, 0x1c, 0xc3, 0x89, 0x49, 0x49, 0x64, 0x3f, 0x12, 0x00, 0x08, 0x19, 0x22, 0xe8, 0x08, 0x81, 0x90, 0xb8, 0xdd, 0x6e, 0x8d, 0x36, 0xb3, 0xb0, 0xa8, 0x94, 0xe3, 0x78, 0xaf, 0xcb, 0x5b, 0xf7, 0xfc, 0xf1, 0x2f, 0xd6, 0xfd, 0x52, 0xe8, 0x88, 0xa8, 0x44, 0x05, 0x80, 0xcc, 0x18, 0x90, 0x04, 0x54, 0xaa, 0xd4, 0x00, 0xcf, 0xf9, 0x18, 0x6c, 0x9b, 0x72, 0x1f, 0xeb, 0x5b, 0xbe, 0x7c, 0x79, 0x5a, 0x5a, 0x3a, 0x72, 0x1c, 0xb4, 0x86, 0xe6, 0x34, 0x25, 0xc3, 0x53, 0x22, 0x81, 0x43, 0x64, 0xf1, 0x4a, 0x65, 0x6f, 0x7f, 0x7f, 0x73, 0x6b, 0x1b, 0x03, 0xfb, 0xe3, 0x97, 0xf5, 0x19, 0x4d, 0xc6, 0x68, 0x5e, 0x6b, 0xa7, 0x00, 0x00, 0x76, 0xcf, 0x0c, 0xb5, 0x9a, 0xe7, 0x39, 0xb7, 0x87, 0x89, 0x53, 0xca, 0x19, 0x96, 0x0d, 0x48, 0xa9, 0xcb, 0x97, 0x2e, 0x74, 0xb4, 0x37, 0x05, 0xfd, 0x20, 0xc5, 0x82, 0x86, 0xa2, 0x00, 0x33, 0x3c, 0x6c, 0x59, 0xf7, 0xab, 0xdf, 0xfc, 0x6c, 0xd1, 0x12, 0x96, 0xf5, 0xb3, 0x00, 0xcb, 0xf8, 0x59, 0x24, 0x0a, 0xbb, 0x23, 0x1a, 0x00, 0x53, 0x70, 0x98, 0xc3, 0x8e, 0xa3, 0xd5, 0x68, 0xfc, 0x7e, 0x0e, 0xeb, 0xc1, 0xeb, 0x15, 0xdc, 0xe0, 0x74, 0xba, 0xe5, 0x0a, 0x79, 0x4d, 0xcd, 0xe6, 0x3d, 0xbb, 0xbf, 0x58, 0xb7, 0xee, 0x73, 0x43, 0xc7, 0x4b, 0xb3, 0xd9, 0x58, 0x55, 0x55, 0x69, 0x36, 0x19, 0x5f, 0xf7, 0xf4, 0xb0, 0x1c, 0x0f, 0x3c, 0x5e, 0x2f, 0xcb, 0xb0, 0x3e, 0x9e, 0x27, 0x77, 0x0a, 0x91, 0x5f, 0x2c, 0x4c, 0x01, 0x00, 0xb9, 0x9c, 0xd6, 0x68, 0xb5, 0x7e, 0xbf, 0x1f, 0x1e, 0xf0, 0x7a, 0xa0, 0x16, 0xeb, 0x74, 0x8e, 0x28, 0xe4, 0xf2, 0xfc, 0xfc, 0xfc, 0xd2, 0x92, 0x12, 0xbd, 0x5e, 0xf7, 0xaa, 0xfb, 0xd5, 0x67, 0x9f, 0x2d, 0x37, 0x18, 0x0c, 0x26, 0x8b, 0xd9, 0xef, 0xe7, 0x3d, 0x6e, 0xaf, 0x00, 0x80, 0x65, 0xbd, 0x8c, 0x8f, 0xf7, 0x73, 0x11, 0x45, 0xfe, 0x5b, 0xa1, 0x29, 0x08, 0x21, 0x8a, 0xa6, 0x34, 0x6a, 0x35, 0xc7, 0x75, 0xc2, 0x01, 0x0c, 0x93, 0x80, 0xf0, 0xc0, 0xd9, 0xce, 0x64, 0xb6, 0x7c, 0xfb, 0x6d, 0x9d, 0x5e, 0x9f, 0xdd, 0xd2, 0xda, 0x1c, 0x17, 0x17, 0x67, 0xe8, 0x30, 0x48, 0xa4, 0x92, 0x8a, 0xf2, 0x72, 0x97, 0xdb, 0xed, 0x72, 0x7b, 0x58, 0x9f, 0x1f, 0xda, 0xc3, 0x09, 0x7e, 0xde, 0xff, 0x56, 0x97, 0x88, 0xa8, 0x29, 0x00, 0x40, 0x53, 0x74, 0x7a, 0x3a, 0xb6, 0xc2, 0x60, 0xfa, 0x52, 0x20, 0x97, 0xd1, 0xd0, 0xaf, 0xec, 0xe3, 0xa5, 0x76, 0xbb, 0xb5, 0xcf, 0xcc, 0xa4, 0xeb, 0x8a, 0x0e, 0xd7, 0xfe, 0x19, 0x51, 0x8e, 0x83, 0x2a, 0x96, 0xad, 0x5a, 0xa3, 0x19, 0x71, 0xb9, 0x20, 0x82, 0xbd, 0x15, 0x8d, 0x3c, 0xcf, 0xc3, 0x75, 0x08, 0xbf, 0x88, 0x94, 0x17, 0x84, 0xa6, 0x00, 0x00, 0x96, 0xaf, 0x5e, 0xa7, 0x4d, 0x49, 0x55, 0x69, 0x35, 0x50, 0x2f, 0xdd, 0xed, 0x1c, 0x52, 0xa9, 0x52, 0x32, 0x34, 0x6a, 0xa4, 0x01, 0x21, 0x7f, 0x61, 0xdf, 0xa7, 0x29, 0x09, 0x94, 0x0d, 0xf0, 0xd8, 0x8b, 0xc0, 0x3c, 0x64, 0x36, 0xa5, 0xce, 0x52, 0xcd, 0x52, 0xa5, 0x3a, 0xdd, 0x01, 0x5a, 0xae, 0x28, 0x2a, 0x2a, 0x8a, 0xf8, 0x2c, 0x1d, 0x2d, 0x00, 0x28, 0x85, 0xbd, 0x25, 0x5e, 0x19, 0xff, 0xdf, 0xff, 0x3d, 0xf1, 0x30, 0xfc, 0x90, 0xc3, 0x23, 0xa1, 0xdd, 0x43, 0x76, 0x37, 0x6d, 0xb4, 0x8f, 0xb0, 0x32, 0xf4, 0x06, 0x01, 0x08, 0x89, 0x80, 0xc7, 0x5e, 0x8b, 0xe5, 0x8a, 0x7f, 0x52, 0xc9, 0x88, 0xc3, 0x6e, 0x32, 0xdb, 0xe8, 0x04, 0x4b, 0x7b, 0x5b, 0xdb, 0xc1, 0xdf, 0x7f, 0xb1, 0x64, 0xd1, 0x02, 0x8d, 0x46, 0x13, 0xb1, 0x07, 0x04, 0x3f, 0x46, 0x26, 0xec, 0xf3, 0xf9, 0x90, 0x92, 0x46, 0x46, 0x46, 0xcc, 0x66, 0x4b, 0x43, 0x63, 0xd3, 0xc9, 0x93, 0xa7, 0xcc, 0x96, 0x21, 0xe4, 0x54, 0xa4, 0x58, 0xc1, 0xee, 0x38, 0x2d, 0x08, 0x23, 0x23, 0x0f, 0x08, 0xc3, 0x07, 0xa9, 0xe0, 0x3f, 0xa1, 0xc6, 0x23, 0x85, 0xc1, 0x1b, 0xc5, 0x85, 0x05, 0x7f, 0xff, 0xdb, 0x97, 0x19, 0x19, 0x6a, 0x9c, 0x49, 0x11, 0x60, 0x42, 0xcf, 0xe4, 0x4b, 0x84, 0x62, 0x64, 0x22, 0x44, 0x30, 0xc7, 0x71, 0x0a, 0x85, 0x1c, 0x47, 0xb3, 0xdf, 0xed, 0xdd, 0x69, 0x32, 0x99, 0x84, 0xa0, 0x41, 0xce, 0x22, 0x56, 0x79, 0x8f, 0x65, 0xd0, 0x8f, 0x13, 0x2a, 0xf8, 0xf2, 0xf2, 0xf3, 0x81, 0xd0, 0xeb, 0xf5, 0x46, 0xac, 0x3d, 0xd4, 0x88, 0xdc, 0x03, 0x10, 0x86, 0x9e, 0xc0, 0x80, 0x02, 0x02, 0x56, 0x14, 0x54, 0x9f, 0x64, 0x01, 0xfe, 0x1f, 0x30, 0x4f, 0x52, 0x50, 0x64, 0x8f, 0x0a, 0x80, 0x38, 0xca, 0x0c, 0x12, 0x53, 0x90, 0xc8, 0x66, 0x50, 0x7b, 0x4c, 0x1d, 0x03, 0x30, 0xb3, 0xf6, 0x8f, 0x79, 0x60, 0xa6, 0xed, 0x1f, 0xf3, 0xc0, 0x87, 0xec, 0x01, 0x9c, 0x21, 0x4f, 0x9f, 0x3e, 0x7d, 0xeb, 0xd6, 0xad, 0xb1, 0x41, 0x20, 0xcd, 0x05, 0xcf, 0x9b, 0xd1, 0x1e, 0x9b, 0xdf, 0x3b, 0x0b, 0x92, 0x68, 0x64, 0xa5, 0xa3, 0xa3, 0x03, 0x83, 0xce, 0x9d, 0x3b, 0x77, 0x0c, 0xf1, 0xa3, 0x47, 0x8f, 0x8a, 0x37, 0x0e, 0xb8, 0xfc, 0x19, 0x83, 0x33, 0xe2, 0xae, 0xc8, 0xf3, 0x80, 0x42, 0xa1, 0xc0, 0x9b, 0xca, 0xd8, 0xf7, 0x39, 0x39, 0x39, 0x39, 0xf3, 0xe6, 0xcd, 0x4b, 0x4b, 0x4b, 0x03, 0x54, 0x5c, 0x41, 0xbf, 0xd7, 0x8a, 0xd1, 0x74, 0x44, 0x0c, 0x1d, 0x82, 0x38, 0x90, 0x4e, 0x44, 0x1c, 0x91, 0x06, 0x0d, 0xb7, 0x6c, 0xd9, 0x32, 0x11, 0xe6, 0xc9, 0xf2, 0x84, 0x7b, 0xe0, 0xc8, 0x91, 0x23, 0x9f, 0x04, 0xcb, 0x9a, 0x35, 0x6b, 0xda, 0xda, 0xda, 0x9e, 0x3f, 0x7f, 0xbe, 0x6a, 0xd5, 0x2a, 0x34, 0x2c, 0x5d, 0xba, 0xf4, 0xda, 0xb5, 0x6b, 0xa2, 0xa5, 0xb6, 0x6d, 0xdb, 0x46, 0x1a, 0x97, 0x2d, 0x5b, 0x66, 0xb3, 0xd9, 0xc4, 0x76, 0x91, 0xb8, 0x71, 0xe3, 0xc6, 0xd6, 0xad, 0x5b, 0x31, 0xc8, 0xf1, 0xe3, 0xc7, 0x47, 0xdb, 0x1e, 0x2d, 0x07, 0x0f, 0x1e, 0x5c, 0xb8, 0x70, 0x21, 0x3e, 0x20, 0x94, 0x94, 0x94, 0x1c, 0x3e, 0x7c, 0xd8, 0xe5, 0x72, 0x89, 0xb2, 0x20, 0xfa, 0xfb, 0xfb, 0x77, 0xec, 0xd8, 0x51, 0x58, 0x58, 0x08, 0x86, 0xf2, 0xf2, 0xf2, 0xd1, 0x0c, 0x6f, 0x99, 0xc3, 0x10, 0xeb, 0x74, 0x3a, 0xb1, 0xef, 0xea, 0xd5, 0xab, 0x67, 0xcf, 0x9e, 0x15, 0xab, 0x1b, 0x36, 0x6c, 0x20, 0xcc, 0x4e, 0xa7, 0x33, 0xf4, 0x00, 0xdc, 0xdd, 0xdd, 0x1d, 0x36, 0xc8, 0xae, 0x5d, 0xbb, 0x44, 0x29, 0x10, 0xe4, 0x94, 0x2a, 0x7a, 0x60, 0x60, 0x60, 0x20, 0x3b, 0x3b, 0x9b, 0x30, 0xe0, 0x5d, 0x94, 0x10, 0xc5, 0xc5, 0xc5, 0xc0, 0x40, 0xc6, 0xc1, 0x37, 0x9b, 0xd1, 0xef, 0x68, 0xb9, 0xb9, 0xb9, 0x16, 0x8b, 0x25, 0x6c, 0x22, 0x54, 0x85, 0x23, 0x71, 0x68, 0xe9, 0xec, 0xec, 0x2c, 0x2d, 0x2d, 0xc5, 0xa0, 0xbb, 0x77, 0xef, 0x46, 0x84, 0xe0, 0xa6, 0x64, 0xf3, 0xe6, 0xcd, 0xa8, 0x6e, 0xda, 0xb4, 0x29, 0x54, 0xbe, 0xb9, 0xb9, 0x19, 0x36, 0x26, 0x73, 0x87, 0x01, 0xb8, 0x7d, 0xfb, 0x36, 0x69, 0x87, 0x73, 0xae, 0x5c, 0xb9, 0xb2, 0x62, 0xc5, 0x0a, 0x52, 0xad, 0xa9, 0xa9, 0x21, 0x13, 0xad, 0x5f, 0xbf, 0x1e, 0x2d, 0xab, 0x57, 0xaf, 0xee, 0xeb, 0xeb, 0x43, 0x0b, 0xae, 0xb8, 0xc9, 0x42, 0x3a, 0x74, 0xe8, 0x10, 0xaa, 0x98, 0x94, 0x28, 0x00, 0x53, 0x9e, 0x3b, 0x77, 0x0e, 0xfa, 0x1c, 0x3b, 0x76, 0x2c, 0x3e, 0x3e, 0x1e, 0x22, 0xd5, 0xd5, 0xd5, 0xa1, 0xaa, 0x12, 0x3a, 0x1c, 0x00, 0x5a, 0x2f, 0x5e, 0xbc, 0x08, 0x6e, 0x7c, 0x32, 0x01, 0x8d, 0xf3, 0x3a, 0x16, 0x22, 0x4c, 0x88, 0x3d, 0x27, 0x4c, 0x18, 0x57, 0xd3, 0x44, 0xb3, 0x30, 0x00, 0x44, 0x3f, 0xbc, 0x25, 0x42, 0x96, 0x88, 0x60, 0x04, 0x70, 0x12, 0x00, 0x90, 0x22, 0xfb, 0xd2, 0x99, 0x33, 0x67, 0xfe, 0xfd, 0x63, 0xd9, 0xb9, 0x73, 0x27, 0x18, 0x16, 0x2c, 0x58, 0x00, 0x7e, 0x5c, 0xf4, 0x92, 0x61, 0xb1, 0x72, 0xc4, 0x19, 0x21, 0x8b, 0x46, 0xa5, 0x52, 0x89, 0x1d, 0x59, 0x6c, 0x24, 0xc4, 0x3b, 0x00, 0x20, 0x42, 0xf0, 0x05, 0x0e, 0x02, 0xf5, 0xf5, 0xf5, 0x77, 0xee, 0xdc, 0x01, 0xb1, 0x76, 0xed, 0xda, 0x30, 0x31, 0x54, 0xdf, 0x07, 0x00, 0x81, 0x0b, 0x91, 0xed, 0xdb, 0xb7, 0x8b, 0x22, 0xfb, 0xf7, 0xef, 0x47, 0x0b, 0x01, 0x20, 0xea, 0x87, 0x96, 0xb0, 0x92, 0x97, 0x97, 0x07, 0x91, 0x9b, 0x37, 0x6f, 0x92, 0x76, 0x7c, 0x77, 0x12, 0x47, 0x10, 0x1b, 0xe1, 0x10, 0xb1, 0x91, 0x10, 0xef, 0x78, 0xa5, 0xc4, 0xba, 0x41, 0xbc, 0x9e, 0x3f, 0x7f, 0xfe, 0xf2, 0xe5, 0xcb, 0x3d, 0x3d, 0x3d, 0x18, 0xee, 0xc0, 0x81, 0x03, 0x61, 0x93, 0x8d, 0x51, 0x85, 0x38, 0x7a, 0xe1, 0x16, 0x91, 0x27, 0x94, 0xd6, 0xeb, 0xf5, 0xa4, 0xfd, 0xd2, 0xa5, 0x4b, 0x65, 0x65, 0x65, 0x22, 0x0f, 0xdc, 0x42, 0xae, 0x8a, 0xc5, 0x45, 0x88, 0x4f, 0xc8, 0x48, 0x32, 0x84, 0x01, 0x34, 0x08, 0x04, 0x02, 0x2e, 0xf4, 0x45, 0x91, 0x1f, 0x88, 0x30, 0x40, 0xa4, 0xda, 0xd8, 0xd8, 0x88, 0x6e, 0xf8, 0x01, 0xef, 0x7b, 0xb0, 0x28, 0x79, 0x69, 0x0c, 0xe5, 0x84, 0x2b, 0xe1, 0x28, 0x32, 0x04, 0xac, 0x12, 0xba, 0x9f, 0xee, 0xd9, 0xb3, 0x07, 0xed, 0x50, 0xe8, 0xe1, 0xc3, 0x87, 0x10, 0x79, 0xfa, 0xf4, 0x29, 0xd2, 0x05, 0x5a, 0xc4, 0x35, 0x30, 0x7f, 0xfe, 0x7c, 0x54, 0xb1, 0x41, 0x89, 0xab, 0xb6, 0xa5, 0xa5, 0x05, 0x52, 0x27, 0x4e, 0x9c, 0x00, 0xbf, 0xdd, 0x6e, 0x27, 0xfe, 0xc7, 0xbe, 0xf7, 0xe6, 0xcd, 0x1b, 0xb4, 0x60, 0x91, 0x10, 0xd8, 0x24, 0xaa, 0x43, 0xd5, 0x00, 0xfd, 0x8e, 0x10, 0x22, 0x1c, 0x8b, 0x17, 0x2f, 0x26, 0xfa, 0x61, 0x25, 0x85, 0xc9, 0x54, 0x55, 0x55, 0x91, 0xae, 0xd0, 0x27, 0x02, 0x00, 0x2b, 0x1e, 0x9c, 0x98, 0x35, 0x31, 0x31, 0x91, 0x74, 0x91, 0x70, 0x22, 0x34, 0xec, 0x57, 0x5b, 0x5b, 0x0b, 0x86, 0xfb, 0xf7, 0xef, 0x93, 0x7d, 0x09, 0x4b, 0x73, 0xe5, 0xca, 0x95, 0x62, 0x2a, 0xdc, 0xb8, 0x71, 0x23, 0x99, 0xe8, 0xc2, 0x85, 0x0b, 0x44, 0x04, 0x7b, 0x1d, 0xb6, 0x5a, 0x42, 0xc3, 0x22, 0x8f, 0x1e, 0x3d, 0x0a, 0xd3, 0x04, 0xd5, 0xf7, 0x02, 0xb8, 0x77, 0xef, 0x5e, 0x6a, 0x6a, 0x2a, 0xd6, 0x1f, 0x2e, 0x4e, 0xc2, 0xc4, 0x90, 0x01, 0xc8, 0xa0, 0xa1, 0x4f, 0x04, 0x00, 0xee, 0x17, 0x08, 0x27, 0x66, 0xc2, 0x75, 0x15, 0xe9, 0x45, 0x48, 0x60, 0xbd, 0xc2, 0x93, 0xd0, 0x86, 0x00, 0x00, 0x0f, 0xbe, 0x0e, 0x62, 0x77, 0x27, 0x0c, 0xe8, 0x02, 0xf3, 0xde, 0xbd, 0x7b, 0x87, 0x87, 0x87, 0xc5, 0x89, 0xae, 0x5f, 0xbf, 0x4e, 0x96, 0x3e, 0xe1, 0xa9, 0xac, 0xac, 0x7c, 0xf0, 0xe0, 0x81, 0xd8, 0x1b, 0x4a, 0x8c, 0xf5, 0x52, 0x8f, 0xcf, 0xc0, 0x30, 0x15, 0x39, 0x08, 0x84, 0xea, 0x3a, 0x41, 0x1a, 0xfb, 0x3d, 0x82, 0x04, 0x47, 0x09, 0x62, 0xef, 0xd1, 0x52, 0x48, 0x67, 0x58, 0x63, 0x08, 0x74, 0xd1, 0x63, 0x61, 0x3c, 0xd8, 0xb8, 0x31, 0xc8, 0x9c, 0x39, 0x73, 0x48, 0x50, 0x85, 0xf5, 0x92, 0xea, 0x58, 0x00, 0xde, 0x29, 0xf0, 0x53, 0x6b, 0x0c, 0x3f, 0x4a, 0xfc, 0xd4, 0xf4, 0x1b, 0x57, 0x9f, 0x18, 0x80, 0x71, 0x4d, 0x34, 0xcd, 0x0c, 0x31, 0x0f, 0x4c, 0xb3, 0x81, 0xc7, 0x1d, 0x3e, 0xe6, 0x81, 0x71, 0x4d, 0x34, 0xcd, 0x0c, 0x31, 0x0f, 0x4c, 0xb3, 0x81, 0xc7, 0x1d, 0x3e, 0xe6, 0x81, 0x71, 0x4d, 0x34, 0xcd, 0x0c, 0xff, 0x07, 0x71, 0xef, 0x64, 0x50, 0x13, 0xcd, 0x1c, 0x52, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXXMLIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x30, 0x39, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x9d, 0x3c, 0x78, 0xe3, 0x00, 0x00, 0x05, 0x7c, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x59, 0x4c, 0x1b, 0x57, 0x14, 0xc5, 0x0b, 0xbb, 0xc1, 0x26, 0xa2, 0x31, 0x56, 0x58, 0x4c, 0xb1, 0x1b, 0x37, 0x15, 0x8e, 0x42, 0x05, 0x94, 0x25, 0x88, 0x25, 0x6c, 0x05, 0x52, 0x14, 0x0a, 0xfd, 0xa8, 0x08, 0x1f, 0x91, 0xe0, 0x83, 0x02, 0xa2, 0x2a, 0x6a, 0xfb, 0xd3, 0x82, 0x00, 0x15, 0x3e, 0x8a, 0x8a, 0x10, 0x42, 0x42, 0x4a, 0xbf, 0x10, 0x12, 0x84, 0x06, 0xd5, 0x12, 0x15, 0x5b, 0x49, 0x0a, 0x51, 0x31, 0x34, 0xdd, 0x00, 0xa5, 0xb5, 0x4d, 0x42, 0x83, 0xa1, 0x24, 0x0a, 0xc4, 0x94, 0x60, 0x03, 0xb6, 0xb1, 0x7b, 0x9d, 0x57, 0xdc, 0x67, 0x9b, 0x24, 0xe3, 0x19, 0x3b, 0x08, 0x69, 0x46, 0x23, 0xfb, 0xbe, 0xf3, 0xee, 0xbd, 0xef, 0xdc, 0x7b, 0xdf, 0x32, 0x33, 0x0c, 0xb3, 0xd9, 0xec, 0x71, 0x9c, 0x2f, 0xe6, 0x71, 0x26, 0x6f, 0xe1, 0x4e, 0x07, 0x70, 0xd4, 0x15, 0xa4, 0x2b, 0x40, 0x57, 0x80, 0x62, 0x06, 0xe8, 0x29, 0x44, 0x31, 0x81, 0x94, 0xcd, 0xe9, 0x0a, 0x50, 0x4e, 0x21, 0x45, 0x07, 0x74, 0x05, 0x28, 0x26, 0x90, 0xb2, 0x39, 0x5d, 0x81, 0xc3, 0x52, 0xa8, 0xff, 0x67, 0xdb, 0x11, 0x36, 0xea, 0x76, 0x3d, 0x4c, 0xae, 0x7f, 0xf2, 0x75, 0x71, 0x05, 0x36, 0x15, 0xcb, 0xb7, 0x9b, 0xbe, 0x1e, 0x2e, 0xfe, 0xd4, 0x31, 0x80, 0xf5, 0xdf, 0x94, 0xdf, 0x15, 0x7d, 0xac, 0xec, 0x19, 0x36, 0x3c, 0xd1, 0x39, 0xf6, 0x92, 0x46, 0xd8, 0xa4, 0x2d, 0x6d, 0x0c, 0x4d, 0xe6, 0xd5, 0x1f, 0x7e, 0x51, 0xf5, 0x8d, 0xad, 0xff, 0xae, 0x02, 0x9c, 0xe5, 0xed, 0x69, 0xd3, 0x7b, 0xd0, 0xd0, 0x3d, 0xd8, 0x98, 0xeb, 0xbc, 0x76, 0xe7, 0xaa, 0x2c, 0x3c, 0x37, 0x41, 0x5c, 0x72, 0x21, 0x40, 0x28, 0x38, 0xe8, 0x21, 0xff, 0x4f, 0x35, 0x00, 0xc3, 0x96, 0x76, 0x49, 0x36, 0xb5, 0xf8, 0xcd, 0x04, 0x90, 0x23, 0xc8, 0xc2, 0xb8, 0xbb, 0x77, 0x6f, 0xf0, 0x26, 0xdc, 0xfc, 0xb8, 0x33, 0xa2, 0x92, 0x4c, 0x41, 0x92, 0x94, 0xa0, 0xe1, 0xa1, 0x6a, 0xe4, 0x03, 0xd8, 0x5a, 0xfa, 0x7b, 0xb1, 0x7f, 0x7c, 0x79, 0x58, 0x0e, 0x84, 0x70, 0xd7, 0xbe, 0xc1, 0x3c, 0x61, 0x7e, 0x32, 0x8e, 0x20, 0x99, 0x2b, 0x0a, 0x8b, 0xc8, 0x49, 0x58, 0xb9, 0xf9, 0xf3, 0xfe, 0xae, 0x1e, 0x21, 0x0f, 0x67, 0xef, 0xc0, 0xcd, 0x09, 0xe3, 0x8b, 0xde, 0x4d, 0x07, 0x13, 0xb6, 0x9f, 0x8f, 0xa3, 0xd5, 0x0b, 0x11, 0x86, 0xd3, 0xaf, 0x94, 0x66, 0xf3, 0xda, 0x8f, 0xf3, 0x8b, 0xfd, 0x63, 0x30, 0x36, 0xee, 0x9d, 0xc9, 0x66, 0x0b, 0x92, 0xa5, 0xc2, 0xfc, 0xf3, 0x82, 0x84, 0x68, 0x0f, 0x26, 0x03, 0xef, 0xc2, 0x65, 0xc3, 0xf6, 0x8e, 0x7a, 0x54, 0x0e, 0x45, 0xd3, 0x28, 0xee, 0xe3, 0xb8, 0xa7, 0xbf, 0xaf, 0x30, 0x2f, 0x49, 0x54, 0x9c, 0xe1, 0x1f, 0x7a, 0x12, 0xc7, 0x5f, 0x28, 0x3b, 0x1d, 0xc0, 0xad, 0x0f, 0xbf, 0x7a, 0x30, 0x3d, 0x8f, 0xfb, 0xe5, 0x46, 0x85, 0x42, 0xfe, 0x20, 0xbb, 0x5e, 0x3c, 0x0e, 0x8e, 0x3f, 0x5f, 0xde, 0x54, 0x2e, 0x43, 0x18, 0x10, 0x8c, 0x1e, 0x5b, 0xd3, 0x0c, 0x06, 0xe3, 0xcd, 0x4f, 0xca, 0x84, 0x17, 0xcf, 0x3f, 0xdf, 0x16, 0xef, 0x75, 0x7a, 0x0a, 0xe9, 0x37, 0xff, 0xdf, 0x22, 0x4f, 0xa5, 0xc6, 0x48, 0x2e, 0xe7, 0x05, 0xbd, 0x2e, 0xc4, 0x3d, 0x12, 0x94, 0x79, 0xaf, 0x85, 0x9f, 0xfb, 0xe8, 0xfd, 0xb3, 0x55, 0x25, 0x30, 0xa9, 0xfe, 0xb8, 0x2a, 0x7b, 0xa2, 0x7e, 0x08, 0x86, 0x30, 0x1d, 0x76, 0x35, 0x5b, 0x04, 0x3d, 0x20, 0x35, 0xa7, 0x03, 0xc0, 0xbd, 0xaf, 0xdd, 0x9a, 0x63, 0x30, 0x98, 0x91, 0x85, 0x29, 0xfc, 0xb8, 0x37, 0x70, 0x9c, 0xa0, 0x6c, 0xda, 0x33, 0xa8, 0xbf, 0xff, 0x69, 0x49, 0x36, 0x89, 0xd8, 0x13, 0xb4, 0xb2, 0x53, 0x73, 0x3a, 0x80, 0xc8, 0x77, 0x52, 0x20, 0x49, 0x68, 0xcf, 0x31, 0x19, 0x8d, 0x2b, 0x37, 0x6e, 0xc3, 0xed, 0x2f, 0x08, 0x06, 0x1c, 0x26, 0xb1, 0x4f, 0x30, 0xcf, 0x6e, 0x80, 0x43, 0x9b, 0x68, 0xfe, 0x2c, 0x8f, 0xc8, 0x0d, 0xdb, 0x36, 0x67, 0xc2, 0x2b, 0xe7, 0x4e, 0x3b, 0x9b, 0x0b, 0xa7, 0xd7, 0x80, 0x85, 0x90, 0xed, 0xae, 0x6f, 0xa5, 0xc8, 0x64, 0xb3, 0x04, 0x89, 0x52, 0x88, 0x24, 0xe4, 0xad, 0xc3, 0xd7, 0x31, 0x1c, 0xc6, 0xea, 0xd1, 0x99, 0x7b, 0xdf, 0x4e, 0x6a, 0xfe, 0xfc, 0xcb, 0x6a, 0x05, 0x02, 0xd3, 0x93, 0x1d, 0x9e, 0x15, 0x2f, 0x2a, 0xb9, 0x00, 0xf3, 0x0a, 0xc7, 0x89, 0xc8, 0xa4, 0x02, 0x38, 0x70, 0xbc, 0xa9, 0xb8, 0xaf, 0xea, 0x1b, 0x57, 0x8f, 0xcf, 0x9a, 0x0c, 0xc6, 0x03, 0xcc, 0xf2, 0xcf, 0x09, 0x3d, 0x99, 0x73, 0xed, 0x0b, 0x1c, 0x01, 0xf9, 0xf1, 0xc2, 0xdd, 0xc9, 0xaa, 0x2f, 0xed, 0xf6, 0x5c, 0x9f, 0x13, 0xdc, 0xa8, 0x4b, 0xa9, 0xaf, 0x5e, 0x4a, 0xf5, 0x0e, 0x0a, 0xb4, 0xd3, 0x27, 0xd8, 0x74, 0x7a, 0x0a, 0xe1, 0x7e, 0x79, 0xa7, 0x23, 0x62, 0x3f, 0xbb, 0x22, 0xfd, 0xa0, 0xf8, 0x2e, 0x1c, 0x4c, 0xd7, 0x6f, 0xec, 0x3e, 0xfe, 0x6f, 0xfd, 0xed, 0x3c, 0xd2, 0xe0, 0x6a, 0x48, 0xd6, 0x6f, 0x69, 0x71, 0xf6, 0x41, 0x92, 0x08, 0x71, 0x49, 0x66, 0x58, 0x66, 0x1c, 0x83, 0xcd, 0x72, 0x54, 0x26, 0x8e, 0x50, 0x0a, 0x00, 0x0d, 0xe3, 0x7d, 0x22, 0xf0, 0xcc, 0x95, 0x8b, 0x92, 0xcb, 0x6f, 0xab, 0xc7, 0x66, 0xe1, 0x68, 0xb3, 0xdb, 0xe0, 0xed, 0xa8, 0x30, 0x58, 0xcc, 0x53, 0x29, 0x31, 0xa2, 0xf7, 0x2e, 0x04, 0x9f, 0x15, 0xdb, 0x75, 0x91, 0x6c, 0xc2, 0xce, 0xe5, 0xda, 0xeb, 0xd1, 0xaf, 0x8a, 0x99, 0xcf, 0xbb, 0x1d, 0x7d, 0x02, 0x3e, 0xd7, 0xd1, 0xaf, 0x5d, 0x5b, 0x77, 0xec, 0xa2, 0x82, 0x50, 0x5a, 0x03, 0x24, 0x73, 0xe6, 0x52, 0x33, 0x17, 0x3f, 0x4e, 0xbb, 0x94, 0x1b, 0x21, 0x67, 0x74, 0x00, 0x84, 0xd2, 0xe4, 0x46, 0x25, 0xba, 0x02, 0x6e, 0x4c, 0x2e, 0x21, 0xd7, 0x74, 0x05, 0x08, 0xa5, 0xc9, 0x8d, 0x4a, 0xc7, 0xbe, 0x02, 0x2e, 0x78, 0x94, 0x20, 0x9d, 0xde, 0xfd, 0xfd, 0x7d, 0x38, 0x83, 0xc1, 0x9c, 0xcd, 0x26, 0x4f, 0xe3, 0xc8, 0x2a, 0x50, 0x5d, 0x5d, 0xed, 0xe5, 0xe5, 0xe5, 0xf9, 0xf4, 0x6a, 0x6f, 0x6f, 0x27, 0x9d, 0x85, 0x23, 0x0b, 0x20, 0x32, 0x32, 0x32, 0x2a, 0x2a, 0xca, 0xd7, 0xd7, 0x17, 0xa8, 0x6b, 0xb5, 0xda, 0xe3, 0x17, 0x40, 0x6d, 0x6d, 0xad, 0x52, 0xa9, 0xcc, 0xc8, 0xc8, 0x20, 0x4d, 0x1d, 0x19, 0x92, 0xa9, 0xc0, 0xf4, 0xf4, 0x74, 0x7a, 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x72, 0x72, 0xf2, 0xd4, 0xd4, 0xd4, 0xc8, 0xc8, 0x48, 0x62, 0x62, 0x22, 0x34, 0x8b, 0x8a, 0x8a, 0x76, 0x76, 0x76, 0x64, 0x32, 0x59, 0x52, 0x52, 0x52, 0x5a, 0x5a, 0x5a, 0x67, 0x67, 0x27, 0x9f, 0xcf, 0x17, 0x8b, 0xc5, 0xbd, 0xbd, 0xbd, 0x31, 0x31, 0x31, 0x21, 0x21, 0x21, 0xf5, 0xf5, 0xf5, 0x7b, 0x7b, 0x36, 0x1f, 0x91, 0x28, 0xb2, 0xb7, 0x98, 0x93, 0x78, 0x94, 0x6d, 0x69, 0x69, 0xb1, 0x0e, 0xdc, 0xd4, 0xd4, 0x54, 0x57, 0x57, 0x67, 0x6d, 0xaa, 0x54, 0xaa, 0xaa, 0xaa, 0x2a, 0x6b, 0xd3, 0x51, 0x80, 0x60, 0xf0, 0x11, 0xf3, 0xf3, 0xf3, 0x41, 0xa7, 0xb9, 0xb9, 0x19, 0x07, 0x9d, 0x92, 0xc9, 0x54, 0xa0, 0xa6, 0xa6, 0x66, 0x70, 0x70, 0x90, 0xc7, 0xb3, 0xbc, 0xbf, 0x4b, 0xa5, 0x52, 0x89, 0x44, 0x02, 0x42, 0x6e, 0x6e, 0xee, 0xcc, 0xcc, 0x8c, 0x48, 0x24, 0x6a, 0x6c, 0x6c, 0x84, 0x6a, 0x00, 0x52, 0x5a, 0x5a, 0x3a, 0x3e, 0x3e, 0x0e, 0x02, 0x5c, 0x43, 0x43, 0x43, 0xe5, 0xe5, 0xe5, 0x20, 0xcc, 0xcf, 0xdb, 0x7c, 0x53, 0x7a, 0xda, 0x49, 0xe9, 0x87, 0xcc, 0xfe, 0xe5, 0xe3, 0xe3, 0x53, 0x58, 0x58, 0xc8, 0xe5, 0x72, 0xb3, 0xb3, 0xb3, 0xcb, 0xca, 0xca, 0x74, 0x3a, 0x5d, 0x74, 0x74, 0x74, 0x5f, 0x5f, 0x5f, 0x40, 0x40, 0x00, 0x70, 0x01, 0x1c, 0x66, 0x0b, 0x08, 0x79, 0x79, 0x79, 0xb1, 0xb1, 0xb1, 0x20, 0xc0, 0x4e, 0x93, 0x95, 0x95, 0xb5, 0xb2, 0xb2, 0x02, 0xb2, 0x46, 0x73, 0xc8, 0xdb, 0x26, 0xe0, 0xa4, 0x2f, 0x32, 0x15, 0x40, 0x83, 0xc1, 0x2c, 0x6f, 0x68, 0x68, 0x00, 0x42, 0x30, 0xad, 0x3b, 0x3a, 0x3a, 0x10, 0x7b, 0x9c, 0x87, 0x9f, 0x9f, 0x1f, 0x7c, 0x69, 0x03, 0x04, 0x02, 0x80, 0x9d, 0x1e, 0xc9, 0x26, 0x93, 0x09, 0xd7, 0xa1, 0x2e, 0x93, 0x0f, 0x00, 0x32, 0xda, 0xd5, 0xd5, 0x05, 0xd5, 0x00, 0x12, 0x15, 0x15, 0x15, 0x1b, 0x1b, 0x44, 0xbf, 0x4e, 0x53, 0x27, 0x8d, 0x7b, 0x20, 0x19, 0x00, 0xd0, 0xcd, 0xc9, 0xc9, 0x59, 0x5d, 0x5d, 0x1d, 0x18, 0x18, 0xa8, 0xac, 0xac, 0x54, 0x28, 0x14, 0x05, 0x05, 0x05, 0xd6, 0xed, 0x1c, 0x56, 0x21, 0x8c, 0x81, 0x7e, 0xf1, 0xc1, 0x70, 0x19, 0x4a, 0x61, 0x34, 0x1a, 0x91, 0x0e, 0x2e, 0xe3, 0x3a, 0x84, 0x64, 0xa7, 0x96, 0x3c, 0x52, 0x86, 0xa5, 0x89, 0x12, 0x0f, 0xc7, 0x90, 0x5c, 0x2e, 0x6f, 0x6d, 0x6d, 0x45, 0x23, 0x41, 0x73, 0x62, 0x62, 0xa2, 0xad, 0xad, 0x0d, 0xcd, 0x96, 0xc0, 0xc0, 0xc0, 0x85, 0x85, 0x05, 0xd4, 0x05, 0x4b, 0xbc, 0xbb, 0xbb, 0x1b, 0x64, 0x16, 0x8b, 0xd5, 0xd3, 0xd3, 0x03, 0x26, 0x8e, 0x8f, 0x0f, 0x1c, 0x0e, 0x67, 0x74, 0x74, 0xd4, 0x59, 0x3e, 0x64, 0x2a, 0x00, 0xfc, 0xe0, 0x29, 0x00, 0xd8, 0x80, 0x00, 0x59, 0xd4, 0xeb, 0xf5, 0x88, 0xb1, 0x15, 0x64, 0x32, 0x2d, 0x6e, 0x81, 0x22, 0x5c, 0xe8, 0xac, 0x05, 0x04, 0x2d, 0x12, 0x08, 0x00, 0x28, 0x82, 0x3e, 0x32, 0x41, 0xe1, 0xa1, 0x5f, 0x47, 0x04, 0xef, 0x7d, 0x96, 0x4c, 0x7f, 0x95, 0x78, 0x56, 0x66, 0x5e, 0x16, 0x4e, 0x66, 0x0a, 0xbd, 0x2c, 0x6e, 0x84, 0xc6, 0xa1, 0x03, 0x20, 0x94, 0x26, 0x37, 0x2a, 0xd1, 0x15, 0x70, 0x63, 0x72, 0x09, 0xb9, 0xa6, 0x2b, 0x40, 0x28, 0x4d, 0x6e, 0x54, 0xa2, 0x2b, 0xe0, 0xc6, 0xe4, 0x12, 0x72, 0x4d, 0x57, 0x80, 0x50, 0x9a, 0xdc, 0xa8, 0xf4, 0x2f, 0x8a, 0xf9, 0x6c, 0x7c, 0x9d, 0x47, 0x95, 0x15, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +static const u_int8_t FLEXBinaryIcon2x[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x31, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xce, 0xc3, 0x0a, 0xd6, 0x00, 0x00, 0x05, 0xc2, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x6f, 0x48, 0x64, 0x55, 0x14, 0x3f, 0x33, 0xe3, 0x8c, 0x63, 0xce, 0x44, 0x6e, 0x5b, 0xae, 0xd9, 0x22, 0xa8, 0x59, 0xae, 0x08, 0x91, 0x9a, 0x1b, 0xea, 0x87, 0x30, 0xd1, 0x45, 0x03, 0x29, 0x58, 0x61, 0x2b, 0xe9, 0x93, 0x89, 0x84, 0x44, 0x11, 0x51, 0x7d, 0x0b, 0x4a, 0x21, 0xb2, 0xed, 0x8b, 0xfa, 0x29, 0xa8, 0x2c, 0xf1, 0x83, 0x4a, 0x1b, 0xad, 0x6c, 0x61, 0x05, 0x9b, 0xc9, 0x36, 0xba, 0x9b, 0xe8, 0x1a, 0xa2, 0x28, 0xfe, 0xd7, 0x36, 0xf3, 0xcf, 0x6c, 0x3a, 0xce, 0x8c, 0x33, 0x9d, 0x3b, 0xf7, 0xcd, 0x9d, 0xf7, 0xe6, 0xcd, 0xcc, 0xfb, 0x3b, 0xc4, 0xc2, 0xbb, 0x1f, 0xc6, 0x73, 0xcf, 0xfd, 0x9d, 0xdf, 0xb9, 0xe7, 0x9c, 0xfb, 0xe7, 0x71, 0x35, 0x05, 0x83, 0x41, 0xb8, 0x97, 0x9b, 0xf9, 0x5e, 0x9e, 0x3c, 0x99, 0xbb, 0x11, 0xc0, 0xff, 0x5d, 0x41, 0xa3, 0x02, 0x46, 0x05, 0x34, 0x66, 0xc0, 0x58, 0x42, 0x1a, 0x13, 0xa8, 0xd9, 0x5c, 0x46, 0x05, 0x0e, 0xff, 0x82, 0xe0, 0x89, 0x66, 0x47, 0x3c, 0x02, 0x5d, 0x09, 0x53, 0x78, 0xc4, 0x42, 0x71, 0x67, 0x16, 0x7e, 0x7a, 0x13, 0xb6, 0x26, 0xe0, 0x68, 0x07, 0x52, 0xec, 0x70, 0xfa, 0x1c, 0x94, 0xbc, 0x01, 0x45, 0xaf, 0x08, 0x41, 0xbc, 0x1e, 0x06, 0x39, 0xf0, 0x1c, 0x78, 0xdd, 0x60, 0x3f, 0x05, 0x17, 0x7f, 0xe0, 0x0d, 0x84, 0x45, 0xa5, 0x84, 0xb3, 0x7d, 0x30, 0x71, 0x99, 0x18, 0x9f, 0x7f, 0x17, 0x0a, 0x5e, 0x0c, 0xb3, 0x44, 0xff, 0x8d, 0x13, 0x00, 0x1a, 0x5f, 0x7b, 0x0d, 0x7c, 0x87, 0x1c, 0xdc, 0xef, 0x81, 0xad, 0x9b, 0xf0, 0x7d, 0x33, 0x2c, 0xff, 0x08, 0x17, 0x3e, 0x07, 0x53, 0x2c, 0xab, 0xc5, 0xab, 0xb0, 0xf2, 0x0b, 0xc1, 0xa7, 0x67, 0x72, 0x56, 0xfc, 0x3f, 0x8a, 0x09, 0x83, 0x30, 0xf9, 0x19, 0x6c, 0x4d, 0x12, 0x8e, 0xc3, 0x3b, 0x7c, 0xa6, 0x28, 0x39, 0xd6, 0x12, 0x3a, 0xdc, 0x86, 0x6b, 0x2d, 0xdc, 0xec, 0x6d, 0xe9, 0x90, 0xf3, 0x2c, 0x38, 0x1f, 0xe1, 0xcc, 0x66, 0xbe, 0x82, 0x99, 0x2f, 0xa2, 0x28, 0x48, 0x77, 0x7d, 0x0c, 0xae, 0xbe, 0x1a, 0x43, 0x4f, 0x55, 0x4a, 0x09, 0x4f, 0x3c, 0x84, 0x6d, 0x73, 0x22, 0x2e, 0x21, 0x6f, 0x20, 0x56, 0x2e, 0x7f, 0xff, 0x18, 0x7c, 0x47, 0x04, 0xe3, 0xcc, 0x86, 0x97, 0xc7, 0xc1, 0x79, 0x96, 0xec, 0x81, 0x2b, 0x4d, 0x30, 0x37, 0x48, 0x94, 0xe3, 0x1f, 0x42, 0x51, 0x33, 0x98, 0xad, 0x44, 0x9e, 0xfd, 0x1a, 0xb6, 0x27, 0x61, 0xfd, 0x37, 0xd8, 0xb8, 0x41, 0xba, 0xf1, 0x9a, 0x4c, 0xc2, 0xbb, 0xeb, 0x70, 0xab, 0x1b, 0xdc, 0xab, 0xb0, 0xf0, 0x1d, 0x78, 0xf6, 0xe2, 0x91, 0x45, 0xe9, 0x45, 0x15, 0x08, 0x78, 0xe1, 0x56, 0x0f, 0x07, 0x2a, 0x7f, 0x87, 0xcc, 0x1e, 0x9b, 0xc9, 0x02, 0xd5, 0x97, 0xc1, 0x6c, 0x21, 0xf2, 0xde, 0x12, 0x2c, 0x5c, 0x21, 0x02, 0xb6, 0xdb, 0x5f, 0x82, 0xeb, 0x53, 0x89, 0xd9, 0xcb, 0x27, 0x3c, 0x58, 0x81, 0xf1, 0x8f, 0x00, 0x8b, 0x2c, 0x7b, 0xf6, 0x38, 0x05, 0x51, 0x00, 0xee, 0xb5, 0xc8, 0xd2, 0xcf, 0xbd, 0x10, 0x9a, 0x66, 0xe8, 0xc7, 0xf1, 0x28, 0x3c, 0x54, 0xcc, 0x75, 0xff, 0x99, 0x8b, 0xe8, 0x25, 0x25, 0xdd, 0x09, 0x85, 0x1e, 0x45, 0x4b, 0x08, 0xd3, 0x40, 0x1b, 0xe6, 0xfb, 0x81, 0x3c, 0x01, 0xf8, 0xd4, 0xe3, 0xb0, 0xfd, 0x07, 0xd1, 0x30, 0xcc, 0xf3, 0xdf, 0x80, 0xff, 0x98, 0xc3, 0xb8, 0x3e, 0x01, 0x57, 0x97, 0x00, 0x4f, 0x3b, 0x0c, 0x2c, 0x49, 0x78, 0xa6, 0x04, 0xda, 0xd6, 0x23, 0x0c, 0xdd, 0xd9, 0x11, 0x39, 0xbe, 0x24, 0x0e, 0x60, 0x99, 0x03, 0xdb, 0xee, 0xc7, 0xa5, 0x23, 0x30, 0xc4, 0xf3, 0x91, 0xb6, 0x83, 0x30, 0xc6, 0xfe, 0x60, 0x04, 0x60, 0x73, 0x46, 0x64, 0xbe, 0xc4, 0xc0, 0x92, 0x84, 0x66, 0x1b, 0x38, 0xc2, 0xa7, 0x05, 0x9f, 0x21, 0xa1, 0x2c, 0x5a, 0x42, 0x77, 0x37, 0x38, 0xbc, 0x59, 0x14, 0x1b, 0xd3, 0x30, 0x4c, 0x42, 0x6a, 0x6e, 0x90, 0x81, 0x99, 0x39, 0xb3, 0x62, 0x1a, 0x86, 0x61, 0x43, 0xb2, 0x05, 0x51, 0x00, 0x16, 0x3b, 0x67, 0x7b, 0xe2, 0x8d, 0x26, 0x61, 0x1a, 0x86, 0x89, 0x46, 0xc4, 0xea, 0x33, 0x30, 0x33, 0x67, 0x28, 0xa6, 0x61, 0x18, 0x36, 0x24, 0x5b, 0x10, 0x05, 0x90, 0x8a, 0x2b, 0x27, 0xd4, 0x7c, 0xff, 0x42, 0xd0, 0x2f, 0xe0, 0x39, 0x0e, 0x1f, 0x6d, 0x0c, 0x23, 0x18, 0x8e, 0xd3, 0x61, 0x60, 0xbd, 0x08, 0x85, 0x7e, 0x44, 0x01, 0x64, 0x3c, 0xc6, 0x01, 0x02, 0x7e, 0x72, 0x62, 0xf2, 0xdb, 0xee, 0x3c, 0xd7, 0x63, 0x18, 0xfe, 0x68, 0x3c, 0x99, 0x81, 0xf5, 0x22, 0x14, 0x3a, 0x12, 0x05, 0xf0, 0xf0, 0x93, 0xc0, 0x96, 0xe6, 0xca, 0xcf, 0x11, 0x30, 0xde, 0xa6, 0x7f, 0xdf, 0xe6, 0xba, 0x67, 0x4a, 0x23, 0x7a, 0x49, 0x49, 0x77, 0x42, 0xa1, 0x47, 0x51, 0x00, 0x78, 0x56, 0x9c, 0xbb, 0xc4, 0x61, 0x6e, 0x74, 0x82, 0x3f, 0x74, 0x25, 0x63, 0x1f, 0x2f, 0x60, 0x7a, 0x62, 0xde, 0x77, 0x1a, 0x9e, 0xb8, 0x28, 0x24, 0x49, 0xd8, 0xd3, 0x9d, 0x50, 0xe8, 0x4d, 0x74, 0xd4, 0xe0, 0xf0, 0x33, 0xef, 0x93, 0x6f, 0x84, 0xc0, 0x09, 0x59, 0x42, 0x3d, 0x67, 0xc9, 0x74, 0xd7, 0xae, 0xc3, 0x9d, 0x19, 0xce, 0xb0, 0xec, 0x2d, 0xb0, 0x3a, 0x84, 0x24, 0x52, 0x3d, 0xdd, 0x09, 0x79, 0x0e, 0x45, 0x15, 0xc0, 0xb1, 0x8c, 0x02, 0x38, 0xff, 0x1e, 0x87, 0xc1, 0x6f, 0x69, 0xfc, 0xb2, 0x60, 0xb3, 0xcf, 0x7a, 0x1a, 0x9e, 0x7a, 0x9d, 0x67, 0x2e, 0x4f, 0xd4, 0x9d, 0x90, 0xe7, 0x36, 0x56, 0x00, 0x38, 0x5c, 0xf9, 0x01, 0xbc, 0xf0, 0x6d, 0xe4, 0x23, 0x14, 0x35, 0xd6, 0x34, 0x28, 0x7f, 0x1b, 0x5e, 0xfa, 0x55, 0x71, 0xfa, 0xa9, 0x33, 0xdd, 0x09, 0xc3, 0x31, 0x98, 0x24, 0x9e, 0x16, 0xf1, 0x8a, 0xd9, 0xf9, 0x93, 0x7c, 0x96, 0xe2, 0x61, 0x82, 0x9f, 0x74, 0xda, 0x9b, 0xde, 0x84, 0x52, 0x01, 0x68, 0x9f, 0x71, 0x92, 0x19, 0xe2, 0x2c, 0xa1, 0x24, 0x7b, 0xd5, 0x91, 0xde, 0x08, 0x40, 0xc7, 0x64, 0xaa, 0xa2, 0x32, 0x2a, 0xa0, 0x2a, 0x6d, 0x3a, 0x1a, 0x19, 0x15, 0xd0, 0x31, 0x99, 0xaa, 0xa8, 0x8c, 0x0a, 0xa8, 0x4a, 0x9b, 0x8e, 0x46, 0x6a, 0x2a, 0x70, 0x12, 0x6a, 0x92, 0x93, 0xf0, 0xfb, 0xfd, 0x5d, 0x5d, 0x5d, 0x43, 0x43, 0x43, 0x92, 0x48, 0x4d, 0x00, 0xfc, 0x16, 0x52, 0xd4, 0xaa, 0xaa, 0xaa, 0xd0, 0x9f, 0xc9, 0x64, 0x1a, 0x1d, 0x1d, 0x4d, 0x6c, 0x38, 0x37, 0x47, 0x9e, 0x8f, 0x72, 0x73, 0x73, 0x13, 0xc3, 0x34, 0x8e, 0x2a, 0xae, 0x40, 0x41, 0x41, 0x41, 0x4a, 0x4a, 0x0a, 0x7a, 0x3d, 0x38, 0x38, 0x48, 0x9c, 0x39, 0x9b, 0xcd, 0x96, 0x9a, 0x9a, 0x9a, 0x9d, 0x2d, 0xeb, 0x79, 0x27, 0x31, 0x55, 0xa2, 0x51, 0x15, 0x09, 0xc0, 0xa4, 0x22, 0xe3, 0xf0, 0xf0, 0xb0, 0xa4, 0xad, 0xcf, 0xe7, 0x93, 0xc4, 0x68, 0x04, 0x28, 0xae, 0x00, 0x4b, 0xc6, 0xc6, 0xc6, 0x46, 0x7b, 0x7b, 0x7b, 0x75, 0x75, 0x75, 0x6b, 0x6b, 0xeb, 0xd8, 0xd8, 0x18, 0xd3, 0x53, 0xa1, 0xb9, 0xb9, 0xb9, 0xbc, 0xbc, 0xbc, 0xa2, 0xa2, 0xa2, 0xb2, 0xb2, 0x72, 0x6f, 0x2f, 0xfc, 0x9c, 0x01, 0xb0, 0xbb, 0xbb, 0xdb, 0xd8, 0xd8, 0x88, 0x43, 0x6d, 0x6d, 0x6d, 0x83, 0x83, 0x83, 0xc5, 0xc5, 0xc5, 0xe9, 0xe9, 0xe9, 0x75, 0x75, 0x75, 0x9b, 0x9b, 0x9b, 0x51, 0x0c, 0x72, 0xbb, 0x2a, 0x12, 0x40, 0x2b, 0x80, 0xdb, 0x80, 0xf9, 0xb0, 0x58, 0x2c, 0x3d, 0x3d, 0x3d, 0x8c, 0xca, 0xed, 0x76, 0xe3, 0x32, 0x63, 0xa3, 0x4b, 0x4b, 0x4b, 0x6c, 0x68, 0x62, 0x82, 0x7b, 0x34, 0x77, 0x3a, 0x9d, 0x7c, 0x4c, 0x53, 0x53, 0x13, 0xc3, 0x28, 0x12, 0x40, 0x11, 0x9a, 0x82, 0x69, 0x00, 0x38, 0x69, 0x4c, 0x73, 0x77, 0x77, 0x77, 0x5e, 0x1e, 0x79, 0x42, 0x4d, 0x4b, 0x4b, 0x5b, 0x5e, 0x5e, 0x66, 0x6c, 0xd3, 0xd3, 0xd3, 0x03, 0x03, 0x03, 0x34, 0x06, 0x7e, 0x00, 0x08, 0xe8, 0xeb, 0xeb, 0xa3, 0xfa, 0xda, 0xda, 0x5a, 0x8c, 0xa7, 0xa5, 0xa5, 0x05, 0xbb, 0x58, 0x07, 0x66, 0xab, 0x48, 0x50, 0x1f, 0x00, 0xcb, 0xd9, 0xfc, 0x3c, 0xf7, 0x5e, 0xd4, 0xd9, 0xd9, 0xc9, 0xf7, 0x7d, 0x74, 0xc4, 0xbd, 0x68, 0x44, 0x05, 0x30, 0x35, 0x35, 0x45, 0x03, 0x70, 0xb9, 0x5c, 0x88, 0x9f, 0x9c, 0x0c, 0xfd, 0x1b, 0x06, 0x60, 0x7f, 0x7f, 0x9f, 0x6f, 0x2e, 0x53, 0x56, 0xbf, 0x07, 0x1a, 0x1a, 0x1a, 0xe8, 0x3c, 0xf2, 0xf3, 0xf3, 0x0b, 0x0b, 0x0b, 0x51, 0xa6, 0xe7, 0x26, 0x55, 0xca, 0xf9, 0x2d, 0x29, 0x29, 0x41, 0x58, 0x4e, 0x4e, 0x0e, 0x05, 0x7b, 0x3c, 0x1e, 0x39, 0x56, 0x51, 0x18, 0xf5, 0x01, 0x60, 0x5e, 0x29, 0x97, 0xd7, 0xeb, 0x5d, 0x5b, 0x5b, 0x43, 0xd9, 0x6e, 0x0f, 0xbf, 0xab, 0x46, 0x39, 0x89, 0xd3, 0xa5, 0xbb, 0x88, 0xbf, 0x97, 0xe2, 0x00, 0x13, 0xa9, 0xd5, 0x07, 0xd0, 0xdf, 0xdf, 0xbf, 0xba, 0xba, 0x8a, 0x85, 0xee, 0xed, 0xed, 0xc5, 0x5d, 0x8b, 0x4e, 0x4a, 0x4b, 0x23, 0x2f, 0x76, 0x78, 0x59, 0xe3, 0x4d, 0x4c, 0x3d, 0xf3, 0x65, 0xd4, 0xa0, 0x09, 0xd5, 0x53, 0x21, 0x10, 0x08, 0xf0, 0xbb, 0x54, 0x56, 0xf0, 0x2b, 0x73, 0xa9, 0x31, 0x58, 0x4d, 0x4d, 0x0d, 0x63, 0xc7, 0xab, 0x8a, 0x6e, 0x68, 0xd4, 0x14, 0x15, 0x15, 0x61, 0x29, 0x28, 0xac, 0xac, 0xac, 0x8c, 0x61, 0x98, 0x80, 0x2b, 0xed, 0xf8, 0xf8, 0x18, 0x37, 0x7a, 0x46, 0x46, 0x06, 0x55, 0xa2, 0x06, 0x4f, 0xd8, 0xac, 0xac, 0x2c, 0xda, 0xcd, 0xcc, 0xcc, 0xc4, 0xcb, 0x91, 0x39, 0x92, 0x29, 0x28, 0xae, 0x80, 0xd9, 0x4c, 0x4c, 0x1c, 0x0e, 0x47, 0x47, 0x47, 0x07, 0x26, 0x6f, 0x71, 0x71, 0x11, 0xd7, 0x40, 0x7d, 0x7d, 0xfd, 0xc8, 0xc8, 0x88, 0xd5, 0x6a, 0xa5, 0x53, 0xa1, 0x18, 0x2a, 0xb3, 0x5f, 0x54, 0xe2, 0x9c, 0xb0, 0x8b, 0x61, 0x53, 0x25, 0xde, 0xd3, 0xc8, 0xc0, 0xef, 0x52, 0x00, 0x33, 0x91, 0x23, 0x68, 0x7a, 0x56, 0xc1, 0x6d, 0xb7, 0xb0, 0xb0, 0x80, 0xbb, 0x10, 0x0f, 0x75, 0x39, 0xce, 0x92, 0x81, 0xd1, 0x14, 0x40, 0x32, 0x26, 0xa4, 0x94, 0x53, 0xf1, 0x12, 0x52, 0xea, 0x20, 0xd9, 0x78, 0x23, 0x80, 0x64, 0x67, 0x58, 0x8a, 0xdf, 0xa8, 0x80, 0x54, 0x86, 0x92, 0x3d, 0x6e, 0x54, 0x20, 0xd9, 0x19, 0x96, 0xe2, 0x37, 0x2a, 0x20, 0x95, 0xa1, 0x64, 0x8f, 0x1b, 0x15, 0x48, 0x76, 0x86, 0xa5, 0xf8, 0xff, 0x03, 0xf5, 0x1a, 0x5a, 0xe0, 0xcf, 0xeb, 0xd5, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; + +@implementation FLEXResources + + +#pragma mark - Images + +#define FLEXImage(base) (([[UIScreen mainScreen] scale] > 1.5) ? \ + [self imageWithBytesNoCopy:(void *)base##2x length:sizeof(base##2x) scale:2.0] : \ + [self imageWithBytesNoCopy:(void *)base length:sizeof(base) scale:1.0]) + +#define FLEXRetinaOnlyImage(base) ([self imageWithBytesNoCopy:(void *)(base) length:sizeof(base) scale:2.0]) + ++ (UIImage *)closeIcon +{ + return FLEXImage(FLEXCloseIcon); +} + ++ (UIImage *)dragHandle +{ + return FLEXImage(FLEXDragHandle); +} + ++ (UIImage *)globeIcon +{ + return FLEXImage(FLEXGlobeIcon); +} + ++ (UIImage *)hierarchyIndentPattern +{ + return FLEXImage(FLEXHierarchyIndentPattern); +} + ++ (UIImage *)listIcon +{ + return FLEXImage(FLEXListIcon); +} + ++ (UIImage *)moveIcon +{ + return FLEXImage(FLEXMoveIcon); +} + ++ (UIImage *)selectIcon +{ + return FLEXImage(FLEXSelectIcon); +} + ++ (UIImage *)jsonIcon +{ + return FLEXRetinaOnlyImage(FLEXJSONIcon2x); +} + ++ (UIImage *)textPlainIcon +{ + return FLEXRetinaOnlyImage(FLEXTextPlainIcon2x); +} + ++ (UIImage *)htmlIcon +{ + return FLEXRetinaOnlyImage(FLEXHTMLIcon2x); +} + ++ (UIImage *)audioIcon +{ + return FLEXRetinaOnlyImage(FLEXAudioIcon2x); +} + ++ (UIImage *)jsIcon +{ + return FLEXRetinaOnlyImage(FLEXJSIcon2x); +} + ++ (UIImage *)plistIcon +{ + return FLEXRetinaOnlyImage(FLEXPlistIcon2x); +} + ++ (UIImage *)textIcon +{ + return FLEXRetinaOnlyImage(FLEXTextIcon2x); +} + ++ (UIImage *)videoIcon +{ + return FLEXRetinaOnlyImage(FLEXVideoIcon2x); +} + ++ (UIImage *)xmlIcon +{ + return FLEXRetinaOnlyImage(FLEXXMLIcon2x); +} + ++ (UIImage *)binaryIcon +{ + return FLEXRetinaOnlyImage(FLEXBinaryIcon2x); +} + +#undef FLEXImage +#undef FLEXRetinaOnlyImage + + +#pragma mark - Helpers + ++ (UIImage *)imageWithBytesNoCopy:(void *)bytes length:(NSUInteger)length scale:(CGFloat)scale +{ + NSData *data = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:NO]; + return [UIImage imageWithData:data scale:scale]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.h new file mode 100755 index 0000000..e1e2ba3 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.h @@ -0,0 +1,59 @@ +// +// FLEXRuntimeUtility.h +// Flipboard +// +// Created by Ryan Olson on 6/8/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import +#import + +extern const unsigned int kFLEXNumberOfImplicitArgs; + +// See https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6 +extern NSString *const kFLEXUtilityAttributeTypeEncoding; +extern NSString *const kFLEXUtilityAttributeBackingIvar; +extern NSString *const kFLEXUtilityAttributeReadOnly; +extern NSString *const kFLEXUtilityAttributeCopy; +extern NSString *const kFLEXUtilityAttributeRetain; +extern NSString *const kFLEXUtilityAttributeNonAtomic; +extern NSString *const kFLEXUtilityAttributeCustomGetter; +extern NSString *const kFLEXUtilityAttributeCustomSetter; +extern NSString *const kFLEXUtilityAttributeDynamic; +extern NSString *const kFLEXUtilityAttributeWeak; +extern NSString *const kFLEXUtilityAttributeGarbageCollectable; +extern NSString *const kFLEXUtilityAttributeOldStyleTypeEncoding; + +#define FLEXEncodeClass(class) ("@\"" #class "\"") + +@interface FLEXRuntimeUtility : NSObject + +// Property Helpers ++ (NSString *)prettyNameForProperty:(objc_property_t)property; ++ (NSString *)typeEncodingForProperty:(objc_property_t)property; ++ (BOOL)isReadonlyProperty:(objc_property_t)property; ++ (SEL)setterSelectorForProperty:(objc_property_t)property; ++ (NSString *)fullDescriptionForProperty:(objc_property_t)property; ++ (id)valueForProperty:(objc_property_t)property onObject:(id)object; ++ (NSString *)descriptionForIvarOrPropertyValue:(id)value; ++ (void)tryAddPropertyWithName:(const char *)name attributes:(NSDictionary *)attributePairs toClass:(__unsafe_unretained Class)theClass; + +// Ivar Helpers ++ (NSString *)prettyNameForIvar:(Ivar)ivar; ++ (id)valueForIvar:(Ivar)ivar onObject:(id)object; ++ (void)setValue:(id)value forIvar:(Ivar)ivar onObject:(id)object; + +// Method Helpers ++ (NSString *)prettyNameForMethod:(Method)method isClassMethod:(BOOL)isClassMethod; ++ (NSArray *)prettyArgumentComponentsForMethod:(Method)method; + +// Method Calling/Field Editing ++ (id)performSelector:(SEL)selector onObject:(id)object withArguments:(NSArray *)arguments error:(NSError * __autoreleasing *)error; ++ (NSString *)editableJSONStringForObject:(id)object; ++ (id)objectValueFromEditableJSONString:(NSString *)string; ++ (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString; ++ (void)enumerateTypesInStructEncoding:(const char *)structEncoding usingBlock:(void (^)(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset))typeBlock; ++ (NSValue *)valueForPrimitivePointer:(void *)pointer objCType:(const char *)type; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.m new file mode 100755 index 0000000..52b951b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXRuntimeUtility.m @@ -0,0 +1,708 @@ +// +// FLEXRuntimeUtility.m +// Flipboard +// +// Created by Ryan Olson on 6/8/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import +#import "FLEXRuntimeUtility.h" + +// See https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6 +NSString *const kFLEXUtilityAttributeTypeEncoding = @"T"; +NSString *const kFLEXUtilityAttributeBackingIvar = @"V"; +NSString *const kFLEXUtilityAttributeReadOnly = @"R"; +NSString *const kFLEXUtilityAttributeCopy = @"C"; +NSString *const kFLEXUtilityAttributeRetain = @"&"; +NSString *const kFLEXUtilityAttributeNonAtomic = @"N"; +NSString *const kFLEXUtilityAttributeCustomGetter = @"G"; +NSString *const kFLEXUtilityAttributeCustomSetter = @"S"; +NSString *const kFLEXUtilityAttributeDynamic = @"D"; +NSString *const kFLEXUtilityAttributeWeak = @"W"; +NSString *const kFLEXUtilityAttributeGarbageCollectable = @"P"; +NSString *const kFLEXUtilityAttributeOldStyleTypeEncoding = @"t"; + +static NSString *const FLEXRuntimeUtilityErrorDomain = @"FLEXRuntimeUtilityErrorDomain"; +typedef NS_ENUM(NSInteger, FLEXRuntimeUtilityErrorCode) { + FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector = 0, + FLEXRuntimeUtilityErrorCodeInvocationFailed = 1, + FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch = 2 +}; + +// Arguments 0 and 1 are self and _cmd always +const unsigned int kFLEXNumberOfImplicitArgs = 2; + +@implementation FLEXRuntimeUtility + + +#pragma mark - Property Helpers (Public) + ++ (NSString *)prettyNameForProperty:(objc_property_t)property +{ + NSString *name = @(property_getName(property)); + NSString *encoding = [self typeEncodingForProperty:property]; + NSString *readableType = [self readableTypeForEncoding:encoding]; + return [self appendName:name toType:readableType]; +} + ++ (NSString *)typeEncodingForProperty:(objc_property_t)property +{ + NSDictionary *attributesDictionary = [self attributesDictionaryForProperty:property]; + return attributesDictionary[kFLEXUtilityAttributeTypeEncoding]; +} + ++ (BOOL)isReadonlyProperty:(objc_property_t)property +{ + return [[self attributesDictionaryForProperty:property] objectForKey:kFLEXUtilityAttributeReadOnly] != nil; +} + ++ (SEL)setterSelectorForProperty:(objc_property_t)property +{ + SEL setterSelector = NULL; + NSString *setterSelectorString = [[self attributesDictionaryForProperty:property] objectForKey:kFLEXUtilityAttributeCustomSetter]; + if (!setterSelectorString) { + NSString *propertyName = @(property_getName(property)); + setterSelectorString = [NSString stringWithFormat:@"set%@%@:", [[propertyName substringToIndex:1] uppercaseString], [propertyName substringFromIndex:1]]; + } + if (setterSelectorString) { + setterSelector = NSSelectorFromString(setterSelectorString); + } + return setterSelector; +} + ++ (NSString *)fullDescriptionForProperty:(objc_property_t)property +{ + NSDictionary *attributesDictionary = [self attributesDictionaryForProperty:property]; + NSMutableArray *attributesStrings = [NSMutableArray array]; + + // Atomicity + if (attributesDictionary[kFLEXUtilityAttributeNonAtomic]) { + [attributesStrings addObject:@"nonatomic"]; + } else { + [attributesStrings addObject:@"atomic"]; + } + + // Storage + if (attributesDictionary[kFLEXUtilityAttributeRetain]) { + [attributesStrings addObject:@"strong"]; + } else if (attributesDictionary[kFLEXUtilityAttributeCopy]) { + [attributesStrings addObject:@"copy"]; + } else if (attributesDictionary[kFLEXUtilityAttributeWeak]) { + [attributesStrings addObject:@"weak"]; + } else { + [attributesStrings addObject:@"assign"]; + } + + // Mutability + if (attributesDictionary[kFLEXUtilityAttributeReadOnly]) { + [attributesStrings addObject:@"readonly"]; + } else { + [attributesStrings addObject:@"readwrite"]; + } + + // Custom getter/setter + NSString *customGetter = attributesDictionary[kFLEXUtilityAttributeCustomGetter]; + NSString *customSetter = attributesDictionary[kFLEXUtilityAttributeCustomSetter]; + if (customGetter) { + [attributesStrings addObject:[NSString stringWithFormat:@"getter=%@", customGetter]]; + } + if (customSetter) { + [attributesStrings addObject:[NSString stringWithFormat:@"setter=%@", customSetter]]; + } + + NSString *attributesString = [attributesStrings componentsJoinedByString:@", "]; + NSString *shortName = [self prettyNameForProperty:property]; + + return [NSString stringWithFormat:@"@property (%@) %@", attributesString, shortName]; +} + ++ (id)valueForProperty:(objc_property_t)property onObject:(id)object +{ + NSString *customGetterString = nil; + char *customGetterName = property_copyAttributeValue(property, "G"); + if (customGetterName) { + customGetterString = @(customGetterName); + free(customGetterName); + } + + SEL getterSelector; + if ([customGetterString length] > 0) { + getterSelector = NSSelectorFromString(customGetterString); + } else { + NSString *propertyName = @(property_getName(property)); + getterSelector = NSSelectorFromString(propertyName); + } + + return [self performSelector:getterSelector onObject:object withArguments:nil error:NULL]; +} + ++ (NSString *)descriptionForIvarOrPropertyValue:(id)value +{ + NSString *description = nil; + + // Special case BOOL for better readability. + if ([value isKindOfClass:[NSValue class]]) { + const char *type = [value objCType]; + if (strcmp(type, @encode(BOOL)) == 0) { + BOOL boolValue = NO; + [value getValue:&boolValue]; + description = boolValue ? @"YES" : @"NO"; + } else if (strcmp(type, @encode(SEL)) == 0) { + SEL selector = NULL; + [value getValue:&selector]; + description = NSStringFromSelector(selector); + } + } + + if (!description) { + // Single line display - replace newlines and tabs with spaces. + description = [[value description] stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; + description = [description stringByReplacingOccurrencesOfString:@"\t" withString:@" "]; + } + + if (!description) { + description = @"nil"; + } + + return description; +} + ++ (void)tryAddPropertyWithName:(const char *)name attributes:(NSDictionary *)attributePairs toClass:(__unsafe_unretained Class)theClass +{ + objc_property_t property = class_getProperty(theClass, name); + if (!property) { + unsigned int totalAttributesCount = (unsigned int)[attributePairs count]; + objc_property_attribute_t *attributes = malloc(sizeof(objc_property_attribute_t) * totalAttributesCount); + if (attributes) { + unsigned int attributeIndex = 0; + for (NSString *attributeName in [attributePairs allKeys]) { + objc_property_attribute_t attribute; + attribute.name = [attributeName UTF8String]; + attribute.value = [attributePairs[attributeName] UTF8String]; + attributes[attributeIndex++] = attribute; + } + + class_addProperty(theClass, name, attributes, totalAttributesCount); + free(attributes); + } + } +} + + +#pragma mark - Ivar Helpers (Public) + ++ (NSString *)prettyNameForIvar:(Ivar)ivar +{ + const char *nameCString = ivar_getName(ivar); + NSString *name = nameCString ? @(nameCString) : nil; + const char *encodingCString = ivar_getTypeEncoding(ivar); + NSString *encoding = encodingCString ? @(encodingCString) : nil; + NSString *readableType = [self readableTypeForEncoding:encoding]; + return [self appendName:name toType:readableType]; +} + ++ (id)valueForIvar:(Ivar)ivar onObject:(id)object +{ + id value = nil; + const char *type = ivar_getTypeEncoding(ivar); +#ifdef __arm64__ + // See http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html + const char *name = ivar_getName(ivar); + if (type[0] == @encode(Class)[0] && strcmp(name, "isa") == 0) { + value = object_getClass(object); + } else +#endif + if (type[0] == @encode(id)[0] || type[0] == @encode(Class)[0]) { + value = object_getIvar(object, ivar); + } else { + ptrdiff_t offset = ivar_getOffset(ivar); + void *pointer = (__bridge void *)object + offset; + value = [self valueForPrimitivePointer:pointer objCType:type]; + } + return value; +} + ++ (void)setValue:(id)value forIvar:(Ivar)ivar onObject:(id)object +{ + const char *typeEncodingCString = ivar_getTypeEncoding(ivar); + if (typeEncodingCString[0] == '@') { + object_setIvar(object, ivar, value); + } else if ([value isKindOfClass:[NSValue class]]) { + // Primitive - unbox the NSValue. + NSValue *valueValue = (NSValue *)value; + + // Make sure that the box contained the correct type. + NSAssert(strcmp([valueValue objCType], typeEncodingCString) == 0, @"Type encoding mismatch (value: %s; ivar: %s) in setting ivar named: %s on object: %@", [valueValue objCType], typeEncodingCString, ivar_getName(ivar), object); + + NSUInteger bufferSize = 0; + @try { + // NSGetSizeAndAlignment barfs on type encoding for bitfields. + NSGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL); + } @catch (NSException *exception) { } + if (bufferSize > 0) { + void *buffer = calloc(bufferSize, 1); + [valueValue getValue:buffer]; + ptrdiff_t offset = ivar_getOffset(ivar); + void *pointer = (__bridge void *)object + offset; + memcpy(pointer, buffer, bufferSize); + free(buffer); + } + } +} + + +#pragma mark - Method Helpers (Public) + ++ (NSString *)prettyNameForMethod:(Method)method isClassMethod:(BOOL)isClassMethod +{ + NSString *selectorName = NSStringFromSelector(method_getName(method)); + NSString *methodTypeString = isClassMethod ? @"+" : @"-"; + char *returnType = method_copyReturnType(method); + NSString *readableReturnType = [self readableTypeForEncoding:@(returnType)]; + free(returnType); + NSString *prettyName = [NSString stringWithFormat:@"%@ (%@)", methodTypeString, readableReturnType]; + NSArray *components = [self prettyArgumentComponentsForMethod:method]; + if ([components count] > 0) { + prettyName = [prettyName stringByAppendingString:[components componentsJoinedByString:@" "]]; + } else { + prettyName = [prettyName stringByAppendingString:selectorName]; + } + + return prettyName; +} + ++ (NSArray *)prettyArgumentComponentsForMethod:(Method)method +{ + NSMutableArray *components = [NSMutableArray array]; + + NSString *selectorName = NSStringFromSelector(method_getName(method)); + NSArray *selectorComponents = [selectorName componentsSeparatedByString:@":"]; + unsigned int numberOfArguments = method_getNumberOfArguments(method); + + for (unsigned int argIndex = kFLEXNumberOfImplicitArgs; argIndex < numberOfArguments; argIndex++) { + char *argType = method_copyArgumentType(method, argIndex); + NSString *readableArgType = [self readableTypeForEncoding:@(argType)]; + free(argType); + NSString *prettyComponent = [NSString stringWithFormat:@"%@:(%@) ", [selectorComponents objectAtIndex:argIndex - kFLEXNumberOfImplicitArgs], readableArgType]; + [components addObject:prettyComponent]; + } + + return components; +} + + +#pragma mark - Method Calling/Field Editing (Public) + ++ (id)performSelector:(SEL)selector onObject:(id)object withArguments:(NSArray *)arguments error:(NSError * __autoreleasing *)error +{ + // Bail if the object won't respond to this selector. + if (![object respondsToSelector:selector]) { + if (error) { + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"%@ does not respond to the selector %@", object, NSStringFromSelector(selector)]}; + *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain code:FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector userInfo:userInfo]; + } + return nil; + } + + // Build the invocation + NSMethodSignature *methodSignature = [object methodSignatureForSelector:selector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + [invocation setSelector:selector]; + [invocation setTarget:object]; + [invocation retainArguments]; + + // Always self and _cmd + NSUInteger numberOfArguments = [methodSignature numberOfArguments]; + for (NSUInteger argumentIndex = kFLEXNumberOfImplicitArgs; argumentIndex < numberOfArguments; argumentIndex++) { + NSUInteger argumentsArrayIndex = argumentIndex - kFLEXNumberOfImplicitArgs; + id argumentObject = [arguments count] > argumentsArrayIndex ? arguments[argumentsArrayIndex] : nil; + + // NSNull in the arguments array can be passed as a placeholder to indicate nil. We only need to set the argument if it will be non-nil. + if (argumentObject && ![argumentObject isKindOfClass:[NSNull class]]) { + const char *typeEncodingCString = [methodSignature getArgumentTypeAtIndex:argumentIndex]; + if (typeEncodingCString[0] == @encode(id)[0] || typeEncodingCString[0] == @encode(Class)[0] || [self isTollFreeBridgedValue:argumentObject forCFType:typeEncodingCString]) { + // Object + [invocation setArgument:&argumentObject atIndex:argumentIndex]; + } else if (strcmp(typeEncodingCString, @encode(CGColorRef)) == 0 && [argumentObject isKindOfClass:[UIColor class]]) { + // Bridging UIColor to CGColorRef + CGColorRef colorRef = [argumentObject CGColor]; + [invocation setArgument:&colorRef atIndex:argumentIndex]; + } else if ([argumentObject isKindOfClass:[NSValue class]]) { + // Primitive boxed in NSValue + NSValue *argumentValue = (NSValue *)argumentObject; + + // Ensure that the type encoding on the NSValue matches the type encoding of the argument in the method signature + if (strcmp([argumentValue objCType], typeEncodingCString) != 0) { + if (error) { + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Type encoding mismatch for agrument at index %lu. Value type: %s; Method argument type: %s.", (unsigned long)argumentsArrayIndex, [argumentValue objCType], typeEncodingCString]}; + *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain code:FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch userInfo:userInfo]; + } + return nil; + } + + NSUInteger bufferSize = 0; + @try { + // NSGetSizeAndAlignment barfs on type encoding for bitfields. + NSGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL); + } @catch (NSException *exception) { } + + if (bufferSize > 0) { + void *buffer = calloc(bufferSize, 1); + [argumentValue getValue:buffer]; + [invocation setArgument:buffer atIndex:argumentIndex]; + free(buffer); + } + } + } + } + + // Try to invoke the invocation but guard against an exception being thrown. + BOOL successfullyInvoked = NO; + @try { + // Some methods are not fit to be called... + // Looking at you -[UIResponder(UITextInputAdditions) _caretRect] + [invocation invoke]; + successfullyInvoked = YES; + } @catch (NSException *exception) { + // Bummer... + if (error) { + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Exception thrown while performing selector %@ on object %@", NSStringFromSelector(selector), object]}; + *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain code:FLEXRuntimeUtilityErrorCodeInvocationFailed userInfo:userInfo]; + } + } + + // Retreive the return value and box if necessary. + id returnObject = nil; + if (successfullyInvoked) { + const char *returnType = [methodSignature methodReturnType]; + if (returnType[0] == @encode(id)[0] || returnType[0] == @encode(Class)[0]) { + __unsafe_unretained id objectReturnedFromMethod = nil; + [invocation getReturnValue:&objectReturnedFromMethod]; + returnObject = objectReturnedFromMethod; + } else if (returnType[0] != @encode(void)[0]) { + void *returnValue = malloc([methodSignature methodReturnLength]); + if (returnValue) { + [invocation getReturnValue:returnValue]; + returnObject = [self valueForPrimitivePointer:returnValue objCType:returnType]; + free(returnValue); + } + } + } + + return returnObject; +} + ++ (BOOL)isTollFreeBridgedValue:(id)value forCFType:(const char *)typeEncoding +{ + // See https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/Toll-FreeBridgin/Toll-FreeBridgin.html +#define CASE(cftype, foundationClass) \ + if(strcmp(typeEncoding, @encode(cftype)) == 0) { \ + return [value isKindOfClass:[foundationClass class]]; \ + } + + CASE(CFArrayRef, NSArray); + CASE(CFAttributedStringRef, NSAttributedString); + CASE(CFCalendarRef, NSCalendar); + CASE(CFCharacterSetRef, NSCharacterSet); + CASE(CFDataRef, NSData); + CASE(CFDateRef, NSDate); + CASE(CFDictionaryRef, NSDictionary); + CASE(CFErrorRef, NSError); + CASE(CFLocaleRef, NSLocale); + CASE(CFMutableArrayRef, NSMutableArray); + CASE(CFMutableAttributedStringRef, NSMutableAttributedString); + CASE(CFMutableCharacterSetRef, NSMutableCharacterSet); + CASE(CFMutableDataRef, NSMutableData); + CASE(CFMutableDictionaryRef, NSMutableDictionary); + CASE(CFMutableSetRef, NSMutableSet); + CASE(CFMutableStringRef, NSMutableString); + CASE(CFNumberRef, NSNumber); + CASE(CFReadStreamRef, NSInputStream); + CASE(CFRunLoopTimerRef, NSTimer); + CASE(CFSetRef, NSSet); + CASE(CFStringRef, NSString); + CASE(CFTimeZoneRef, NSTimeZone); + CASE(CFURLRef, NSURL); + CASE(CFWriteStreamRef, NSOutputStream); + +#undef CASE + + return NO; +} + ++ (NSString *)editableJSONStringForObject:(id)object +{ + NSString *editableDescription = nil; + + if (object) { + // This is a hack to use JSON serialization for our editable objects. + // NSJSONSerialization doesn't allow writing fragments - the top level object must be an array or dictionary. + // We always wrap the object inside an array and then strip the outer square braces off the final string. + NSArray *wrappedObject = @[object]; + if ([NSJSONSerialization isValidJSONObject:wrappedObject]) { + NSString *wrappedDescription = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:wrappedObject options:0 error:NULL] encoding:NSUTF8StringEncoding]; + editableDescription = [wrappedDescription substringWithRange:NSMakeRange(1, [wrappedDescription length] - 2)]; + } + } + + return editableDescription; +} + ++ (id)objectValueFromEditableJSONString:(NSString *)string +{ + id value = nil; + // nil for empty string/whitespace + if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0) { + value = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:NULL]; + } + return value; +} + ++ (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString +{ + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; + NSNumber *number = [formatter numberFromString:inputString]; + + // Make sure we box the number with the correct type encoding so it can be propperly unboxed later via getValue: + NSValue *value = nil; + if (strcmp(typeEncoding, @encode(char)) == 0) { + char primitiveValue = [number charValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(int)) == 0) { + int primitiveValue = [number intValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(short)) == 0) { + short primitiveValue = [number shortValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(long)) == 0) { + long primitiveValue = [number longValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(long long)) == 0) { + long long primitiveValue = [number longLongValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(unsigned char)) == 0) { + unsigned char primitiveValue = [number unsignedCharValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(unsigned int)) == 0) { + unsigned int primitiveValue = [number unsignedIntValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(unsigned short)) == 0) { + unsigned short primitiveValue = [number unsignedShortValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(unsigned long)) == 0) { + unsigned long primitiveValue = [number unsignedLongValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(unsigned long long)) == 0) { + unsigned long long primitiveValue = [number unsignedLongValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(float)) == 0) { + float primitiveValue = [number floatValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } else if (strcmp(typeEncoding, @encode(double)) == 0) { + double primitiveValue = [number doubleValue]; + value = [NSValue value:&primitiveValue withObjCType:typeEncoding]; + } + + return value; +} + ++ (void)enumerateTypesInStructEncoding:(const char *)structEncoding usingBlock:(void (^)(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset))typeBlock +{ + if (structEncoding && structEncoding[0] == '{') { + const char *equals = strchr(structEncoding, '='); + if (equals) { + const char *nameStart = structEncoding + 1; + NSString *structName = [@(structEncoding) substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart)]; + + NSUInteger fieldAlignment = 0; + NSUInteger structSize = 0; + @try { + // NSGetSizeAndAlignment barfs on type encoding for bitfields. + NSGetSizeAndAlignment(structEncoding, &structSize, &fieldAlignment); + } @catch (NSException *exception) { } + + if (structSize > 0) { + NSUInteger runningFieldIndex = 0; + NSUInteger runningFieldOffset = 0; + const char *typeStart = equals + 1; + while (*typeStart != '}') { + NSUInteger fieldSize = 0; + // If the struct type encoding was successfully handled by NSGetSizeAndAlignment above, we *should* be ok with the field here. + const char *nextTypeStart = NSGetSizeAndAlignment(typeStart, &fieldSize, NULL); + NSString *typeEncoding = [@(structEncoding) substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart)]; + typeBlock(structName, [typeEncoding UTF8String], [self readableTypeForEncoding:typeEncoding], runningFieldIndex, runningFieldOffset); + runningFieldOffset += fieldSize; + // Padding to keep propper alignment. __attribute((packed)) structs will break here. + // The type encoding is no different for packed structs, so it's not clear there's anything we can do for those. + if (runningFieldOffset % fieldAlignment != 0) { + runningFieldOffset += fieldAlignment - runningFieldOffset % fieldAlignment; + } + runningFieldIndex++; + typeStart = nextTypeStart; + } + } + } + } +} + + +#pragma mark - Internal Helpers + ++ (NSDictionary *)attributesDictionaryForProperty:(objc_property_t)property +{ + NSString *attributes = @(property_getAttributes(property)); + // Thanks to MAObjcRuntime for inspiration here. + NSArray *attributePairs = [attributes componentsSeparatedByString:@","]; + NSMutableDictionary *attributesDictionary = [NSMutableDictionary dictionaryWithCapacity:[attributePairs count]]; + for (NSString *attributePair in attributePairs) { + [attributesDictionary setObject:[attributePair substringFromIndex:1] forKey:[attributePair substringToIndex:1]]; + } + return attributesDictionary; +} + ++ (NSString *)appendName:(NSString *)name toType:(NSString *)type +{ + NSString *combined = nil; + if ([type characterAtIndex:[type length] - 1] == '*') { + combined = [type stringByAppendingString:name]; + } else { + combined = [type stringByAppendingFormat:@" %@", name]; + } + return combined; +} + ++ (NSString *)readableTypeForEncoding:(NSString *)encodingString +{ + if (!encodingString) { + return nil; + } + + // See https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + // class-dump has a much nicer and much more complete implementation for this task, but it is distributed under GPLv2 :/ + // See https://github.com/nygard/class-dump/blob/master/Source/CDType.m + // Warning: this method uses multiple middle returns and macros to cut down on boilerplate. + // The use of macros here was inspired by https://www.mikeash.com/pyblog/friday-qa-2013-02-08-lets-build-key-value-coding.html + const char *encodingCString = [encodingString UTF8String]; + + // Objects + if (encodingCString[0] == '@') { + NSString *class = [encodingString substringFromIndex:1]; + class = [class stringByReplacingOccurrencesOfString:@"\"" withString:@""]; + if ([class length] == 0 || [class isEqual:@"?"]) { + class = @"id"; + } else { + class = [class stringByAppendingString:@" *"]; + } + return class; + } + + // C Types +#define TRANSLATE(ctype) \ + if (strcmp(encodingCString, @encode(ctype)) == 0) { \ + return (NSString *)CFSTR(#ctype); \ + } + + // Order matters here since some of the cocoa types are typedefed to c types. + // We can't recover the exact mapping, but we choose to prefer the cocoa types. + // This is not an exhaustive list, but it covers the most common types + TRANSLATE(CGRect); + TRANSLATE(CGPoint); + TRANSLATE(CGSize); + TRANSLATE(UIEdgeInsets); + TRANSLATE(UIOffset); + TRANSLATE(NSRange); + TRANSLATE(CGAffineTransform); + TRANSLATE(CATransform3D); + TRANSLATE(CGColorRef); + TRANSLATE(CGPathRef); + TRANSLATE(CGContextRef); + TRANSLATE(NSInteger); + TRANSLATE(NSUInteger); + TRANSLATE(CGFloat); + TRANSLATE(BOOL); + TRANSLATE(int); + TRANSLATE(short); + TRANSLATE(long); + TRANSLATE(long long); + TRANSLATE(unsigned char); + TRANSLATE(unsigned int); + TRANSLATE(unsigned short); + TRANSLATE(unsigned long); + TRANSLATE(unsigned long long); + TRANSLATE(float); + TRANSLATE(double); + TRANSLATE(long double); + TRANSLATE(char *); + TRANSLATE(Class); + TRANSLATE(objc_property_t); + TRANSLATE(Ivar); + TRANSLATE(Method); + TRANSLATE(Category); + TRANSLATE(NSZone *); + TRANSLATE(SEL); + TRANSLATE(void); + +#undef TRANSLATE + + // Qualifier Prefixes + // Do this after the checks above since some of the direct translations (i.e. Method) contain a prefix. +#define RECURSIVE_TRANSLATE(prefix, formatString) \ + if (encodingCString[0] == prefix) { \ + NSString *recursiveType = [self readableTypeForEncoding:[encodingString substringFromIndex:1]]; \ + return [NSString stringWithFormat:formatString, recursiveType]; \ + } + + // If there's a qualifier prefix on the encoding, translate it and then + // recursively call this method with the rest of the encoding string. + RECURSIVE_TRANSLATE('^', @"%@ *"); + RECURSIVE_TRANSLATE('r', @"const %@"); + RECURSIVE_TRANSLATE('n', @"in %@"); + RECURSIVE_TRANSLATE('N', @"inout %@"); + RECURSIVE_TRANSLATE('o', @"out %@"); + RECURSIVE_TRANSLATE('O', @"bycopy %@"); + RECURSIVE_TRANSLATE('R', @"byref %@"); + RECURSIVE_TRANSLATE('V', @"oneway %@"); + RECURSIVE_TRANSLATE('b', @"bitfield(%@)"); + +#undef RECURSIVE_TRANSLATE + + // If we couldn't translate, just return the original encoding string + return encodingString; +} + ++ (NSValue *)valueForPrimitivePointer:(void *)pointer objCType:(const char *)type +{ + // CASE macro inspired by https://www.mikeash.com/pyblog/friday-qa-2013-02-08-lets-build-key-value-coding.html +#define CASE(ctype, selectorpart) \ + if(strcmp(type, @encode(ctype)) == 0) { \ + return [NSNumber numberWith ## selectorpart: *(ctype *)pointer]; \ + } + + CASE(BOOL, Bool); + CASE(unsigned char, UnsignedChar); + CASE(short, Short); + CASE(unsigned short, UnsignedShort); + CASE(int, Int); + CASE(unsigned int, UnsignedInt); + CASE(long, Long); + CASE(unsigned long, UnsignedLong); + CASE(long long, LongLong); + CASE(unsigned long long, UnsignedLongLong); + CASE(float, Float); + CASE(double, Double); + +#undef CASE + + NSValue *value = nil; + @try { + value = [NSValue valueWithBytes:pointer objCType:type]; + } @catch (NSException *exception) { + // Certain type encodings are not supported by valueWithBytes:objCType:. Just fail silently if an exception is thrown. + } + + return value; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.h new file mode 100755 index 0000000..850e036 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.h @@ -0,0 +1,52 @@ +// +// FLEXUtility.h +// Flipboard +// +// Created by Ryan Olson on 4/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import +#import +#import + +#define FLEXFloor(x) (floor([[UIScreen mainScreen] scale] * (x)) / [[UIScreen mainScreen] scale]) + +@interface FLEXUtility : NSObject + ++ (UIColor *)consistentRandomColorForObject:(id)object; ++ (NSString *)descriptionForView:(UIView *)view includingFrame:(BOOL)includeFrame; ++ (NSString *)stringForCGRect:(CGRect)rect; ++ (UIViewController *)viewControllerForView:(UIView *)view; ++ (UIViewController *)viewControllerForAncestralView:(UIView *)view; ++ (NSString *)detailDescriptionForView:(UIView *)view; ++ (UIImage *)circularImageWithColor:(UIColor *)color radius:(CGFloat)radius; ++ (UIColor *)scrollViewGrayColor; ++ (UIColor *)hierarchyIndentPatternColor; ++ (NSString *)applicationImageName; ++ (NSString *)applicationName; ++ (NSString *)safeDescriptionForObject:(id)object; ++ (UIFont *)defaultFontOfSize:(CGFloat)size; ++ (UIFont *)defaultTableViewCellLabelFont; ++ (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString; ++ (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask; ++ (NSString *)searchBarPlaceholderText; ++ (BOOL)isImagePathExtension:(NSString *)extension; ++ (UIImage *)thumbnailedImageWithMaxPixelDimension:(NSInteger)dimension fromImageData:(NSData *)data; ++ (NSString *)stringFromRequestDuration:(NSTimeInterval)duration; ++ (NSString *)statusCodeStringFromURLResponse:(NSURLResponse *)response; ++ (NSDictionary *)dictionaryFromQuery:(NSString *)query; ++ (NSString *)prettyJSONStringFromData:(NSData *)data; ++ (BOOL)isValidJSONData:(NSData *)data; ++ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData; + ++ (NSArray *)allWindows; + +// Swizzling utilities + ++ (SEL)swizzledSelectorForSelector:(SEL)selector; ++ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls; ++ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)class withBlock:(id)block swizzledSelector:(SEL)swizzledSelector; ++ (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.m new file mode 100755 index 0000000..5892a27 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/Utility/FLEXUtility.m @@ -0,0 +1,428 @@ +// +// FLEXUtility.m +// Flipboard +// +// Created by Ryan Olson on 4/18/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXUtility.h" +#import "FLEXResources.h" +#import +#import +#import + +@implementation FLEXUtility + ++ (UIColor *)consistentRandomColorForObject:(id)object +{ + CGFloat hue = (((NSUInteger)object >> 4) % 256) / 255.0; + return [UIColor colorWithHue:hue saturation:1.0 brightness:1.0 alpha:1.0]; +} + ++ (NSString *)descriptionForView:(UIView *)view includingFrame:(BOOL)includeFrame +{ + NSString *description = [[view class] description]; + + NSString *viewControllerDescription = [[[self viewControllerForView:view] class] description]; + if ([viewControllerDescription length] > 0) { + description = [description stringByAppendingFormat:@" (%@)", viewControllerDescription]; + } + + if (includeFrame) { + description = [description stringByAppendingFormat:@" %@", [self stringForCGRect:view.frame]]; + } + + if ([view.accessibilityLabel length] > 0) { + description = [description stringByAppendingFormat:@" · %@", view.accessibilityLabel]; + } + + return description; +} + ++ (NSString *)stringForCGRect:(CGRect)rect +{ + return [NSString stringWithFormat:@"{(%g, %g), (%g, %g)}", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height]; +} + ++ (UIViewController *)viewControllerForView:(UIView *)view +{ + UIViewController *viewController = nil; + SEL viewDelSel = NSSelectorFromString([NSString stringWithFormat:@"%@ewDelegate", @"_vi"]); + if ([view respondsToSelector:viewDelSel]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + viewController = [view performSelector:viewDelSel]; +#pragma clang diagnostic pop + } + return viewController; +} + ++ (UIViewController *)viewControllerForAncestralView:(UIView *)view{ + UIViewController *viewController = nil; + SEL viewDelSel = NSSelectorFromString([NSString stringWithFormat:@"%@ewControllerForAncestor", @"_vi"]); + if ([view respondsToSelector:viewDelSel]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + viewController = [view performSelector:viewDelSel]; +#pragma clang diagnostic pop + } + return viewController; +} + ++ (NSString *)detailDescriptionForView:(UIView *)view +{ + return [NSString stringWithFormat:@"frame %@", [self stringForCGRect:view.frame]]; +} + ++ (UIImage *)circularImageWithColor:(UIColor *)color radius:(CGFloat)radius +{ + CGFloat diameter = radius * 2.0; + UIGraphicsBeginImageContextWithOptions(CGSizeMake(diameter, diameter), NO, 0.0); + CGContextRef imageContext = UIGraphicsGetCurrentContext(); + CGContextSetFillColorWithColor(imageContext, [color CGColor]); + CGContextFillEllipseInRect(imageContext, CGRectMake(0, 0, diameter, diameter)); + UIImage *circularImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return circularImage; +} + ++ (UIColor *)scrollViewGrayColor +{ + return [UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:244.0/255.0 alpha:1.0]; +} + ++ (UIColor *)hierarchyIndentPatternColor +{ + static UIColor *patternColor = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + UIImage *indentationPatternImage = [FLEXResources hierarchyIndentPattern]; + patternColor = [UIColor colorWithPatternImage:indentationPatternImage]; + }); + return patternColor; +} + ++ (NSString *)applicationImageName +{ + return [NSBundle mainBundle].executablePath; +} + ++ (NSString *)applicationName +{ + return [FLEXUtility applicationImageName].lastPathComponent; +} + ++ (NSString *)safeDescriptionForObject:(id)object +{ + // Don't assume that we have an NSObject subclass. + // Check to make sure the object responds to the description methods. + NSString *description = nil; + if ([object respondsToSelector:@selector(debugDescription)]) { + description = [object debugDescription]; + } else if ([object respondsToSelector:@selector(description)]) { + description = [object description]; + } + return description; +} + ++ (UIFont *)defaultFontOfSize:(CGFloat)size +{ + return [UIFont fontWithName:@"HelveticaNeue" size:size]; +} + ++ (UIFont *)defaultTableViewCellLabelFont +{ + return [self defaultFontOfSize:12.0]; +} + ++ (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString +{ + static NSDictionary *escapingDictionary = nil; + static NSRegularExpression *regex = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + escapingDictionary = @{ @" " : @" ", + @">" : @">", + @"<" : @"<", + @"&" : @"&", + @"'" : @"'", + @"\"" : @""", + @"«" : @"«", + @"»" : @"»" + }; + regex = [NSRegularExpression regularExpressionWithPattern:@"(&|>|<|'|\"|«|»)" options:0 error:NULL]; + }); + + NSMutableString *mutableString = [originalString mutableCopy]; + + NSArray *matches = [regex matchesInString:mutableString options:0 range:NSMakeRange(0, [mutableString length])]; + for (NSTextCheckingResult *result in [matches reverseObjectEnumerator]) { + NSString *foundString = [mutableString substringWithRange:result.range]; + NSString *replacementString = escapingDictionary[foundString]; + if (replacementString) { + [mutableString replaceCharactersInRange:result.range withString:replacementString]; + } + } + + return [mutableString copy]; +} + ++ (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask +{ + NSArray *supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"]; + UIInterfaceOrientationMask supportedOrientationsMask = 0; + if ([supportedOrientations containsObject:@"UIInterfaceOrientationPortrait"]) { + supportedOrientationsMask |= UIInterfaceOrientationMaskPortrait; + } + if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskLandscapeRight"]) { + supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeRight; + } + if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskPortraitUpsideDown"]) { + supportedOrientationsMask |= UIInterfaceOrientationMaskPortraitUpsideDown; + } + if ([supportedOrientations containsObject:@"UIInterfaceOrientationLandscapeLeft"]) { + supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeLeft; + } + return supportedOrientationsMask; +} + ++ (NSString *)searchBarPlaceholderText +{ + return @"Filter"; +} + ++ (BOOL)isImagePathExtension:(NSString *)extension +{ + // https://developer.apple.com/library/ios/documentation/uikit/reference/UIImage_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006890-CH3-SW3 + return [@[@"jpg", @"jpeg", @"png", @"gif", @"tiff", @"tif"] containsObject:extension]; +} + ++ (UIImage *)thumbnailedImageWithMaxPixelDimension:(NSInteger)dimension fromImageData:(NSData *)data +{ + UIImage *thumbnail = nil; + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, 0); + if (imageSource) { + NSDictionary *options = @{ (__bridge id)kCGImageSourceCreateThumbnailWithTransform : @YES, + (__bridge id)kCGImageSourceCreateThumbnailFromImageAlways : @YES, + (__bridge id)kCGImageSourceThumbnailMaxPixelSize : @(dimension) }; + + CGImageRef scaledImageRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (__bridge CFDictionaryRef)options); + if (scaledImageRef) { + thumbnail = [UIImage imageWithCGImage:scaledImageRef]; + CFRelease(scaledImageRef); + } + CFRelease(imageSource); + } + return thumbnail; +} + ++ (NSString *)stringFromRequestDuration:(NSTimeInterval)duration +{ + NSString *string = @"0s"; + if (duration > 0.0) { + if (duration < 1.0) { + string = [NSString stringWithFormat:@"%dms", (int)(duration * 1000)]; + } else if (duration < 10.0) { + string = [NSString stringWithFormat:@"%.2fs", duration]; + } else { + string = [NSString stringWithFormat:@"%.1fs", duration]; + } + } + return string; +} + ++ (NSString *)statusCodeStringFromURLResponse:(NSURLResponse *)response +{ + NSString *httpResponseString = nil; + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + NSString *statusCodeDescription = nil; + if (httpResponse.statusCode == 200) { + // Prefer OK to the default "no error" + statusCodeDescription = @"OK"; + } else { + statusCodeDescription = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]; + } + httpResponseString = [NSString stringWithFormat:@"%ld %@", (long)httpResponse.statusCode, statusCodeDescription]; + } + return httpResponseString; +} + ++ (NSDictionary *)dictionaryFromQuery:(NSString *)query +{ + NSMutableDictionary *queryDictionary = [NSMutableDictionary dictionary]; + + // [a=1, b=2, c=3] + NSArray *queryComponents = [query componentsSeparatedByString:@"&"]; + for (NSString *keyValueString in queryComponents) { + // [a, 1] + NSArray *components = [keyValueString componentsSeparatedByString:@"="]; + if ([components count] == 2) { + NSString *key = [[components firstObject] stringByRemovingPercentEncoding]; + id value = [[components lastObject] stringByRemovingPercentEncoding]; + + // Handle multiple entries under the same key as an array + id existingEntry = queryDictionary[key]; + if (existingEntry) { + if ([existingEntry isKindOfClass:[NSArray class]]) { + value = [existingEntry arrayByAddingObject:value]; + } else { + value = @[existingEntry, value]; + } + } + + [queryDictionary setObject:value forKey:key]; + } + } + + return queryDictionary; +} + ++ (NSString *)prettyJSONStringFromData:(NSData *)data +{ + NSString *prettyString = nil; + + id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; + if ([NSJSONSerialization isValidJSONObject:jsonObject]) { + prettyString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding]; + // NSJSONSerialization escapes forward slashes. We want pretty json, so run through and unescape the slashes. + prettyString = [prettyString stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; + } else { + prettyString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } + + return prettyString; +} + ++ (BOOL)isValidJSONData:(NSData *)data +{ + return [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL] ? YES : NO; +} + +// Thanks to the following links for help with this method +// http://www.cocoanetics.com/2012/02/decompressing-files-into-memory/ +// https://github.com/nicklockwood/GZIP ++ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData +{ + NSData *inflatedData = nil; + NSUInteger compressedDataLength = [compressedData length]; + if (compressedDataLength > 0) { + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.avail_in = (uInt)compressedDataLength; + stream.next_in = (void *)[compressedData bytes]; + stream.total_out = 0; + stream.avail_out = 0; + + NSMutableData *mutableData = [NSMutableData dataWithLength:compressedDataLength * 1.5]; + if (inflateInit2(&stream, 15 + 32) == Z_OK) { + int status = Z_OK; + while (status == Z_OK) { + if (stream.total_out >= [mutableData length]) { + mutableData.length += compressedDataLength / 2; + } + stream.next_out = (uint8_t *)[mutableData mutableBytes] + stream.total_out; + stream.avail_out = (uInt)([mutableData length] - stream.total_out); + status = inflate(&stream, Z_SYNC_FLUSH); + } + if (inflateEnd(&stream) == Z_OK) { + if (status == Z_STREAM_END) { + mutableData.length = stream.total_out; + inflatedData = [mutableData copy]; + } + } + } + } + return inflatedData; +} + ++ (NSArray *)allWindows +{ + BOOL includeInternalWindows = YES; + BOOL onlyVisibleWindows = NO; + + NSArray *allWindowsComponents = @[@"al", @"lWindo", @"wsIncl", @"udingInt", @"ernalWin", @"dows:o", @"nlyVisi", @"bleWin", @"dows:"]; + SEL allWindowsSelector = NSSelectorFromString([allWindowsComponents componentsJoinedByString:@""]); + + NSMethodSignature *methodSignature = [[UIWindow class] methodSignatureForSelector:allWindowsSelector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + + invocation.target = [UIWindow class]; + invocation.selector = allWindowsSelector; + [invocation setArgument:&includeInternalWindows atIndex:2]; + [invocation setArgument:&onlyVisibleWindows atIndex:3]; + [invocation invoke]; + + __unsafe_unretained NSArray *windows = nil; + [invocation getReturnValue:&windows]; + return windows; +} + ++ (SEL)swizzledSelectorForSelector:(SEL)selector +{ + return NSSelectorFromString([NSString stringWithFormat:@"_flex_swizzle_%x_%@", arc4random(), NSStringFromSelector(selector)]); +} + ++ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls +{ + if ([cls instancesRespondToSelector:selector]) { + unsigned int numMethods = 0; + Method *methods = class_copyMethodList(cls, &numMethods); + + BOOL implementsSelector = NO; + for (int index = 0; index < numMethods; index++) { + SEL methodSelector = method_getName(methods[index]); + if (selector == methodSelector) { + implementsSelector = YES; + break; + } + } + + free(methods); + + if (!implementsSelector) { + return YES; + } + } + + return NO; +} + ++ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)class withBlock:(id)block swizzledSelector:(SEL)swizzledSelector +{ + // This method is only intended for swizzling methods that are know to exist on the class. + // Bail if that isn't the case. + Method originalMethod = class_getInstanceMethod(class, originalSelector); + if (!originalMethod) { + return; + } + + IMP implementation = imp_implementationWithBlock(block); + class_addMethod(class, swizzledSelector, implementation, method_getTypeEncoding(originalMethod)); + Method newMethod = class_getInstanceMethod(class, swizzledSelector); + method_exchangeImplementations(originalMethod, newMethod); +} + ++ (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock +{ + if ([self instanceRespondsButDoesNotImplementSelector:selector class:cls]) { + return; + } + + IMP implementation = imp_implementationWithBlock((id)([cls instancesRespondToSelector:selector] ? implementationBlock : undefinedBlock)); + + Method oldMethod = class_getInstanceMethod(cls, selector); + if (oldMethod) { + class_addMethod(cls, swizzledSelector, implementation, methodDescription.types); + + Method newMethod = class_getInstanceMethod(cls, swizzledSelector); + + method_exchangeImplementations(oldMethod, newMethod); + } else { + class_addMethod(cls, selector, implementation, methodDescription.types); + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.h new file mode 100755 index 0000000..52817c5 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.h @@ -0,0 +1,18 @@ +// +// FLEXHierarchyTableViewCell.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-02. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXHierarchyTableViewCell : UITableViewCell + +- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier; + +@property (nonatomic, assign) NSInteger viewDepth; +@property (nonatomic, strong) UIColor *viewColor; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.m new file mode 100755 index 0000000..50d3bec --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewCell.m @@ -0,0 +1,106 @@ +// +// FLEXHierarchyTableViewCell.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-02. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXHierarchyTableViewCell.h" +#import "FLEXUtility.h" + +@interface FLEXHierarchyTableViewCell () + +@property (nonatomic, strong) UIView *depthIndicatorView; +@property (nonatomic, strong) UIImageView *colorCircleImageView; + +@end + +@implementation FLEXHierarchyTableViewCell + +- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier +{ + return [self initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; +} + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.depthIndicatorView = [[UIView alloc] init]; + self.depthIndicatorView.backgroundColor = [FLEXUtility hierarchyIndentPatternColor]; + [self.contentView addSubview:self.depthIndicatorView]; + + UIImage *defaultCircleImage = [FLEXUtility circularImageWithColor:[UIColor blackColor] radius:5.0]; + self.colorCircleImageView = [[UIImageView alloc] initWithImage:defaultCircleImage]; + [self.contentView addSubview:self.colorCircleImageView]; + + self.textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0]; + self.detailTextLabel.font = [FLEXUtility defaultTableViewCellLabelFont]; + self.accessoryType = UITableViewCellAccessoryDetailButton; + } + return self; +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated +{ + [super setHighlighted:highlighted animated:animated]; + + // UITableViewCell changes all subviews in the contentView to backgroundColor = clearColor. + // We want to preserve the hierarchy background color when highlighted. + self.depthIndicatorView.backgroundColor = [FLEXUtility hierarchyIndentPatternColor]; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + [super setSelected:selected animated:animated]; + + // See setHighlighted above. + self.depthIndicatorView.backgroundColor = [FLEXUtility hierarchyIndentPatternColor]; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + const CGFloat kContentPadding = 10.0; + const CGFloat kDepthIndicatorWidthMultiplier = 4.0; + + CGRect depthIndicatorFrame = CGRectMake(kContentPadding, 0, self.viewDepth * kDepthIndicatorWidthMultiplier, self.contentView.bounds.size.height); + self.depthIndicatorView.frame = depthIndicatorFrame; + + CGRect circleFrame = self.colorCircleImageView.frame; + circleFrame.origin.x = CGRectGetMaxX(depthIndicatorFrame); + circleFrame.origin.y = self.textLabel.frame.origin.y + FLEXFloor((self.textLabel.frame.size.height - circleFrame.size.height) / 2.0); + self.colorCircleImageView.frame = circleFrame; + + CGRect textLabelFrame = self.textLabel.frame; + CGFloat textOriginX = CGRectGetMaxX(circleFrame) + 4.0; + textLabelFrame.origin.x = textOriginX; + textLabelFrame.size.width = CGRectGetMaxX(self.contentView.bounds) - kContentPadding - textOriginX; + self.textLabel.frame = textLabelFrame; + + CGRect detailTextLabelFrame = self.detailTextLabel.frame; + CGFloat detailOriginX = CGRectGetMaxX(depthIndicatorFrame); + detailTextLabelFrame.origin.x = detailOriginX; + detailTextLabelFrame.size.width = CGRectGetMaxX(self.contentView.bounds) - kContentPadding - detailOriginX; + self.detailTextLabel.frame = detailTextLabelFrame; +} + +- (void)setViewColor:(UIColor *)viewColor +{ + if (![_viewColor isEqual:viewColor]) { + _viewColor = viewColor; + self.colorCircleImageView.image = [FLEXUtility circularImageWithColor:viewColor radius:6.0]; + } +} + +- (void)setViewDepth:(NSInteger)viewDepth +{ + if (_viewDepth != viewDepth) { + _viewDepth = viewDepth; + [self setNeedsLayout]; + } +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.h new file mode 100755 index 0000000..e2e7e06 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.h @@ -0,0 +1,25 @@ +// +// FLEXHierarchyTableViewController.h +// Flipboard +// +// Created by Ryan Olson on 2014-05-01. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@protocol FLEXHierarchyTableViewControllerDelegate; + +@interface FLEXHierarchyTableViewController : UITableViewController + +- (id)initWithViews:(NSArray *)allViews viewsAtTap:(NSArray *)viewsAtTap selectedView:(UIView *)selectedView depths:(NSDictionary *)depthsForViews; + +@property (nonatomic, weak) id delegate; + +@end + +@protocol FLEXHierarchyTableViewControllerDelegate + +- (void)hierarchyViewController:(FLEXHierarchyTableViewController *)hierarchyViewController didFinishWithSelectedView:(UIView *)selectedView; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.m new file mode 100755 index 0000000..3075bd5 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXHierarchyTableViewController.m @@ -0,0 +1,207 @@ +// +// FLEXHierarchyTableViewController.m +// Flipboard +// +// Created by Ryan Olson on 2014-05-01. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXHierarchyTableViewController.h" +#import "FLEXUtility.h" +#import "FLEXHierarchyTableViewCell.h" +#import "FLEXObjectExplorerViewController.h" +#import "FLEXObjectExplorerFactory.h" + +static const NSInteger kFLEXHierarchyScopeViewsAtTapIndex = 0; +static const NSInteger kFLEXHierarchyScopeFullHierarchyIndex = 1; + +@interface FLEXHierarchyTableViewController () + +@property (nonatomic, strong) NSArray *allViews; +@property (nonatomic, strong) NSDictionary *depthsForViews; +@property (nonatomic, strong) NSArray *viewsAtTap; +@property (nonatomic, strong) UIView *selectedView; +@property (nonatomic, strong) NSArray *displayedViews; + +@property (nonatomic, strong) UISearchBar *searchBar; + +@end + +@implementation FLEXHierarchyTableViewController + +- (id)initWithViews:(NSArray *)allViews viewsAtTap:(NSArray *)viewsAtTap selectedView:(UIView *)selectedView depths:(NSDictionary *)depthsForViews +{ + self = [super initWithStyle:UITableViewStylePlain]; + if (self) { + self.allViews = allViews; + self.depthsForViews = depthsForViews; + self.viewsAtTap = viewsAtTap; + self.selectedView = selectedView; + + self.title = @"View Hierarchy"; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Preserve selection between presentations. + self.clearsSelectionOnViewWillAppear = NO; + // Done button. + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)]; + + // A little more breathing room. + self.tableView.rowHeight = 50.0; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + // Separator inset clashes with persistent cell selection. + [self.tableView setSeparatorInset:UIEdgeInsetsZero]; + + self.searchBar = [[UISearchBar alloc] init]; + self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText]; + self.searchBar.delegate = self; + if ([self showScopeBar]) { + self.searchBar.showsScopeBar = YES; + self.searchBar.scopeButtonTitles = @[@"Views at Tap", @"Full Hierarchy"]; + } + [self.searchBar sizeToFit]; + self.tableView.tableHeaderView = self.searchBar; + + [self updateDisplayedViews]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + [self trySelectCellForSelectedViewWithScrollPosition:UITableViewScrollPositionMiddle]; +} + + +#pragma mark Selection and Filtering Helpers + +- (void)trySelectCellForSelectedViewWithScrollPosition:(UITableViewScrollPosition)scrollPosition +{ + NSUInteger selectedViewIndex = [self.displayedViews indexOfObject:self.selectedView]; + if (selectedViewIndex != NSNotFound) { + NSIndexPath *selectedViewIndexPath = [NSIndexPath indexPathForRow:selectedViewIndex inSection:0]; + [self.tableView selectRowAtIndexPath:selectedViewIndexPath animated:YES scrollPosition:scrollPosition]; + } +} + +- (void)updateDisplayedViews +{ + NSArray *candidateViews = nil; + if ([self showScopeBar]) { + if (self.searchBar.selectedScopeButtonIndex == kFLEXHierarchyScopeViewsAtTapIndex) { + candidateViews = self.viewsAtTap; + } else if (self.searchBar.selectedScopeButtonIndex == kFLEXHierarchyScopeFullHierarchyIndex) { + candidateViews = self.allViews; + } + } else { + candidateViews = self.allViews; + } + + if ([self.searchBar.text length] > 0) { + self.displayedViews = [candidateViews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIView *candidateView, NSDictionary *bindings) { + NSString *title = [FLEXUtility descriptionForView:candidateView includingFrame:NO]; + NSString *candidateViewPointerAddress = [NSString stringWithFormat:@"%p", candidateView]; + BOOL matchedViewPointerAddress = [candidateViewPointerAddress rangeOfString:self.searchBar.text options:NSCaseInsensitiveSearch].location != NSNotFound; + BOOL matchedViewTitle = [title rangeOfString:self.searchBar.text options:NSCaseInsensitiveSearch].location != NSNotFound; + return matchedViewPointerAddress || matchedViewTitle; + }]]; + } else { + self.displayedViews = candidateViews; + } + + [self.tableView reloadData]; +} + +- (BOOL)showScopeBar +{ + return [self.viewsAtTap count] > 0; +} + +- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope +{ + [self updateDisplayedViews]; + + // If the search bar text field is active, don't scroll on selection because we may want to continue typing. + // Otherwise, scroll so that the selected cell is visible. + UITableViewScrollPosition scrollPosition = self.searchBar.isFirstResponder ? UITableViewScrollPositionNone : UITableViewScrollPositionMiddle; + [self trySelectCellForSelectedViewWithScrollPosition:scrollPosition]; +} + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText +{ + [self updateDisplayedViews]; + [self trySelectCellForSelectedViewWithScrollPosition:UITableViewScrollPositionNone]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; +} + + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.displayedViews count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + FLEXHierarchyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[FLEXHierarchyTableViewCell alloc] initWithReuseIdentifier:CellIdentifier]; + } + + UIView *view = self.displayedViews[indexPath.row]; + NSNumber *depth = [self.depthsForViews objectForKey:[NSValue valueWithNonretainedObject:view]]; + UIColor *viewColor = [FLEXUtility consistentRandomColorForObject:view]; + cell.textLabel.text = [FLEXUtility descriptionForView:view includingFrame:NO]; + cell.detailTextLabel.text = [FLEXUtility detailDescriptionForView:view]; + cell.viewColor = viewColor; + cell.viewDepth = [depth integerValue]; + if (view.isHidden || view.alpha < 0.01) { + cell.textLabel.textColor = [UIColor lightGrayColor]; + cell.detailTextLabel.textColor = [UIColor lightGrayColor]; + } else { + cell.textLabel.textColor = [UIColor blackColor]; + cell.detailTextLabel.textColor = [UIColor blackColor]; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + self.selectedView = self.displayedViews[indexPath.row]; + [self.delegate hierarchyViewController:self didFinishWithSelectedView:self.selectedView]; +} + +- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath +{ + UIView *drillInView = self.displayedViews[indexPath.row]; + FLEXObjectExplorerViewController *viewExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:drillInView]; + [self.navigationController pushViewController:viewExplorer animated:YES]; +} + + +#pragma mark - Button Actions + +- (void)donePressed:(id)sender +{ + [self.delegate hierarchyViewController:self didFinishWithSelectedView:self.selectedView]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.h new file mode 100755 index 0000000..60f021d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.h @@ -0,0 +1,15 @@ +// +// FLEXImagePreviewViewController.h +// Flipboard +// +// Created by Ryan Olson on 6/12/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import + +@interface FLEXImagePreviewViewController : UIViewController + +- (id)initWithImage:(UIImage *)image; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.m new file mode 100755 index 0000000..96cd99c --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/FLEX/ViewHierarchy/FLEXImagePreviewViewController.m @@ -0,0 +1,86 @@ +// +// FLEXImagePreviewViewController.m +// Flipboard +// +// Created by Ryan Olson on 6/12/14. +// Copyright (c) 2014 Flipboard. All rights reserved. +// + +#import "FLEXImagePreviewViewController.h" +#import "FLEXUtility.h" + +@interface FLEXImagePreviewViewController () + +@property (nonatomic, strong) UIImage *image; + +@property (nonatomic, strong) UIScrollView *scrollView; +@property (nonatomic, strong) UIImageView *imageView; + +@end + +@implementation FLEXImagePreviewViewController + +- (id)initWithImage:(UIImage *)image +{ + self = [super initWithNibName:nil bundle:nil]; + if (self) { + self.title = @"Preview"; + self.image = image; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.view.backgroundColor = [FLEXUtility scrollViewGrayColor]; + + self.imageView = [[UIImageView alloc] initWithImage:self.image]; + self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; + self.scrollView.delegate = self; + self.scrollView.backgroundColor = self.view.backgroundColor; + self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.scrollView addSubview:self.imageView]; + self.scrollView.contentSize = self.imageView.frame.size; + self.scrollView.minimumZoomScale = 1.0; + self.scrollView.maximumZoomScale = 2.0; + [self.view addSubview:self.scrollView]; + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Copy" style:UIBarButtonItemStylePlain target:self action:@selector(copyButtonPressed:)]; +} + +- (void)viewDidLayoutSubviews +{ + [self centerContentInScrollViewIfNeeded]; +} + +- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView +{ + return self.imageView; +} + +- (void)scrollViewDidZoom:(UIScrollView *)scrollView +{ + [self centerContentInScrollViewIfNeeded]; +} + +- (void)centerContentInScrollViewIfNeeded +{ + CGFloat horizontalInset = 0.0; + CGFloat verticalInset = 0.0; + if (self.scrollView.contentSize.width < self.scrollView.bounds.size.width) { + horizontalInset = (self.scrollView.bounds.size.width - self.scrollView.contentSize.width) / 2.0; + } + if (self.scrollView.contentSize.height < self.scrollView.bounds.size.height) { + verticalInset = (self.scrollView.bounds.size.height - self.scrollView.contentSize.height) / 2.0; + } + self.scrollView.contentInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset); +} + +- (void)copyButtonPressed:(id)sender +{ + [[UIPasteboard generalPasteboard] setImage:self.image]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.h new file mode 100755 index 0000000..e746095 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.h @@ -0,0 +1,15 @@ +// +// GVUserDefaults.h +// GVUserDefaults +// +// Created by Kevin Renskers on 18-12-12. +// Copyright (c) 2012 Gangverk. All rights reserved. +// + +#import + +@interface GVUserDefaults : NSObject + ++ (instancetype)standardUserDefaults; + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.m new file mode 100755 index 0000000..6454ae0 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/GVUserDefaults/GVUserDefaults.m @@ -0,0 +1,279 @@ +// +// GVUserDefaults.m +// GVUserDefaults +// +// Created by Kevin Renskers on 18-12-12. +// Copyright (c) 2012 Gangverk. All rights reserved. +// + +#import "GVUserDefaults.h" +#import + +@interface GVUserDefaults () +@property (strong, nonatomic) NSMutableDictionary *mapping; +@property (strong, nonatomic) NSUserDefaults *userDefaults; +@end + +@implementation GVUserDefaults + +enum TypeEncodings { + Char = 'c', + Bool = 'B', + Short = 's', + Int = 'i', + Long = 'l', + LongLong = 'q', + UnsignedChar = 'C', + UnsignedShort = 'S', + UnsignedInt = 'I', + UnsignedLong = 'L', + UnsignedLongLong = 'Q', + Float = 'f', + Double = 'd', + Object = '@' +}; + +- (NSUserDefaults *)userDefaults { + if (!_userDefaults) { + NSString *suiteName = nil; + if ([NSUserDefaults instancesRespondToSelector:@selector(initWithSuiteName:)]) { + suiteName = [self _suiteName]; + } + + if (suiteName && suiteName.length) { + _userDefaults = [[NSUserDefaults alloc] initWithSuiteName:suiteName]; + } else { + _userDefaults = [NSUserDefaults standardUserDefaults]; + } + } + + return _userDefaults; +} + +- (NSString *)defaultsKeyForPropertyNamed:(char const *)propertyName { + NSString *key = [NSString stringWithFormat:@"%s", propertyName]; + return [self _transformKey:key]; +} + +- (NSString *)defaultsKeyForSelector:(SEL)selector { + return [self.mapping objectForKey:NSStringFromSelector(selector)]; +} + +static long long longLongGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return [[self.userDefaults objectForKey:key] longLongValue]; +} + +static void longLongSetter(GVUserDefaults *self, SEL _cmd, long long value) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + NSNumber *object = [NSNumber numberWithLongLong:value]; + [self.userDefaults setObject:object forKey:key]; +} + +static bool boolGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return [self.userDefaults boolForKey:key]; +} + +static void boolSetter(GVUserDefaults *self, SEL _cmd, bool value) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + [self.userDefaults setBool:value forKey:key]; +} + +static int integerGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return (int)[self.userDefaults integerForKey:key]; +} + +static void integerSetter(GVUserDefaults *self, SEL _cmd, int value) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + [self.userDefaults setInteger:value forKey:key]; +} + +static float floatGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return [self.userDefaults floatForKey:key]; +} + +static void floatSetter(GVUserDefaults *self, SEL _cmd, float value) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + [self.userDefaults setFloat:value forKey:key]; +} + +static double doubleGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return [self.userDefaults doubleForKey:key]; +} + +static void doubleSetter(GVUserDefaults *self, SEL _cmd, double value) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + [self.userDefaults setDouble:value forKey:key]; +} + +static id objectGetter(GVUserDefaults *self, SEL _cmd) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + return [self.userDefaults objectForKey:key]; +} + +static void objectSetter(GVUserDefaults *self, SEL _cmd, id object) { + NSString *key = [self defaultsKeyForSelector:_cmd]; + if (object) { + [self.userDefaults setObject:object forKey:key]; + } else { + [self.userDefaults removeObjectForKey:key]; + } +} + +#pragma mark - Begin + ++ (instancetype)standardUserDefaults { + static dispatch_once_t pred; + static GVUserDefaults *sharedInstance = nil; + dispatch_once(&pred, ^{ sharedInstance = [[self alloc] init]; }); + return sharedInstance; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundeclared-selector" +#pragma GCC diagnostic ignored "-Warc-performSelector-leaks" + +- (instancetype)init { + self = [super init]; + if (self) { + SEL setupDefaultSEL = NSSelectorFromString([NSString stringWithFormat:@"%@pDefaults", @"setu"]); + if ([self respondsToSelector:setupDefaultSEL]) { + NSDictionary *defaults = [self performSelector:setupDefaultSEL]; + NSMutableDictionary *mutableDefaults = [NSMutableDictionary dictionaryWithCapacity:[defaults count]]; + for (NSString *key in defaults) { + id value = [defaults objectForKey:key]; + NSString *transformedKey = [self _transformKey:key]; + [mutableDefaults setObject:value forKey:transformedKey]; + } + [self.userDefaults registerDefaults:mutableDefaults]; + } + + [self generateAccessorMethods]; + } + + return self; +} + +- (NSString *)_transformKey:(NSString *)key { + if ([self respondsToSelector:@selector(transformKey:)]) { + return [self performSelector:@selector(transformKey:) withObject:key]; + } + + return key; +} + +- (NSString *)_suiteName { + // Backwards compatibility (v 1.0.0) + if ([self respondsToSelector:@selector(suitName)]) { + return [self performSelector:@selector(suitName)]; + } + + if ([self respondsToSelector:@selector(suiteName)]) { + return [self performSelector:@selector(suiteName)]; + } + + return nil; +} + +#pragma GCC diagnostic pop + +- (void)generateAccessorMethods { + unsigned int count = 0; + objc_property_t *properties = class_copyPropertyList([self class], &count); + + self.mapping = [NSMutableDictionary dictionary]; + + for (int i = 0; i < count; ++i) { + objc_property_t property = properties[i]; + const char *name = property_getName(property); + const char *attributes = property_getAttributes(property); + + char *getter = strstr(attributes, ",G"); + if (getter) { + getter = strdup(getter + 2); + getter = strsep(&getter, ","); + } else { + getter = strdup(name); + } + SEL getterSel = sel_registerName(getter); + free(getter); + + char *setter = strstr(attributes, ",S"); + if (setter) { + setter = strdup(setter + 2); + setter = strsep(&setter, ","); + } else { + asprintf(&setter, "set%c%s:", toupper(name[0]), name + 1); + } + SEL setterSel = sel_registerName(setter); + free(setter); + + NSString *key = [self defaultsKeyForPropertyNamed:name]; + [self.mapping setValue:key forKey:NSStringFromSelector(getterSel)]; + [self.mapping setValue:key forKey:NSStringFromSelector(setterSel)]; + + IMP getterImp = NULL; + IMP setterImp = NULL; + char type = attributes[1]; + switch (type) { + case Short: + case Long: + case LongLong: + case UnsignedChar: + case UnsignedShort: + case UnsignedInt: + case UnsignedLong: + case UnsignedLongLong: + getterImp = (IMP)longLongGetter; + setterImp = (IMP)longLongSetter; + break; + + case Bool: + case Char: + getterImp = (IMP)boolGetter; + setterImp = (IMP)boolSetter; + break; + + case Int: + getterImp = (IMP)integerGetter; + setterImp = (IMP)integerSetter; + break; + + case Float: + getterImp = (IMP)floatGetter; + setterImp = (IMP)floatSetter; + break; + + case Double: + getterImp = (IMP)doubleGetter; + setterImp = (IMP)doubleSetter; + break; + + case Object: + getterImp = (IMP)objectGetter; + setterImp = (IMP)objectSetter; + break; + + default: + free(properties); + [NSException raise:NSInternalInconsistencyException format:@"Unsupported type of property \"%s\" in class %@", name, self]; + break; + } + + char types[5]; + + snprintf(types, 4, "%c@:", type); + class_addMethod([self class], getterSel, getterImp, types); + + snprintf(types, 5, "v@:%c", type); + class_addMethod([self class], setterSel, setterImp, types); + } + + free(properties); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.h deleted file mode 100644 index 0e6dab0..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.h +++ /dev/null @@ -1,321 +0,0 @@ -// -// JSONModel.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -#import "JSONModelError.h" -#import "JSONValueTransformer.h" -#import "JSONKeyMapper.h" - -///////////////////////////////////////////////////////////////////////////////////////////// -#if TARGET_IPHONE_SIMULATOR -#define JMLog( s, ... ) NSLog( @"[%@:%d] %@", [[NSString stringWithUTF8String:__FILE__] \ -lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) -#else -#define JMLog( s, ... ) -#endif -///////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - Property Protocols -/** - * Protocol for defining properties in a JSON Model class that should not be considered at all - * neither while importing nor when exporting JSON. - * - * @property (strong, nonatomic) NSString<Ignore>* propertyName; - * - */ -@protocol Ignore -@end - -/** - * Protocol for defining optional properties in a JSON Model class. Use like below to define - * model properties that are not required to have values in the JSON input: - * - * @property (strong, nonatomic) NSString<Optional>* propertyName; - * - */ -@protocol Optional -@end - -/** - * Protocol for defining index properties in a JSON Model class. Use like below to define - * model properties that are considered the Model's identifier (id). - * - * @property (strong, nonatomic) NSString<Index>* propertyName; - * - */ -@protocol Index -@end - -/** - * Make all objects Optional compatible to avoid compiler warnings - */ -@interface NSObject(JSONModelPropertyCompatibility) -@end - -/** - * ConvertOnDemand enables lazy model initialization for NSArrays of models - * - * @property (strong, nonatomic) NSArray<JSONModel, ConvertOnDemand>* propertyName; - */ -@protocol ConvertOnDemand -@end - -/** - * Make all arrays ConvertOnDemand compatible to avoid compiler warnings - */ -@interface NSArray(JSONModelPropertyCompatibility) -@end - -///////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - JSONModel protocol -/** - * A protocol describing an abstract JSONModel class - * JSONModel conforms to this protocol, so it can use itself abstractly - */ -@protocol AbstractJSONModelProtocol - -@required - /** - * All JSONModel classes should implement initWithDictionary: - * - * For most classes the default initWithDictionary: inherited from JSONModel itself - * should suffice, but developers have the option ot also overwrite it if needed. - * - * @param dict a dictionary holding JSON objects, to be imported in the model. - * @param err an error or NULL - */ - -(instancetype)initWithDictionary:(NSDictionary*)dict error:(NSError**)err; - - -/** - * All JSONModel classes should implement initWithData:error: - * - * For most classes the default initWithData: inherited from JSONModel itself - * should suffice, but developers have the option ot also overwrite it if needed. - * - * @param data representing a JSON response (usually fetched from web), to be imported in the model. - * @param err an error or NULL - */ --(instancetype)initWithData:(NSData*)data error:(NSError**)error; - -/** - * All JSONModel classes should be able to export themselves as a dictionary of - * JSON compliant objects. - * - * For most classes the inherited from JSONModel default toDictionary implementation - * should suffice. - * - * @return NSDictionary dictionary of JSON compliant objects - * @exception JSONModelTypeNotAllowedException thrown when one of your model's custom class properties - * does not have matching transformer method in an JSONValueTransformer. - */ - -(NSDictionary*)toDictionary; - - /** - * Export a model class to a dictionary, including only given properties - * - * @param propertyNames the properties to export; if nil, all properties exported - * @return NSDictionary dictionary of JSON compliant objects - * @exception JSONModelTypeNotAllowedException thrown when one of your model's custom class properties - * does not have matching transformer method in an JSONValueTransformer. - */ - -(NSDictionary*)toDictionaryWithKeys:(NSArray*)propertyNames; -@end - -///////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - JSONModel interface -/** - * The JSONModel is an abstract model class, you should ot instantiate it directly, - * as it does not have any properties, and therefore cannot serve as a data model. - * Instead you should subclass it, and define the properties you want your data model - * to have as properties of your own class. - */ -@interface JSONModel : NSObject - -/** @name Creating and initializing models */ - - /** - * Create a new model instance and initialize it with the JSON from a text parameter. The method assumes UTF8 encoded input text. - * @param string JSON text data - * @param err an initialization error or nil - * @exception JSONModelTypeNotAllowedException thrown when unsported type is found in the incoming JSON, - * or a property type in your model is not supported by JSONValueTransformer and its categories - * @see initWithString:usingEncoding:error: for use of custom text encodings - */ - -(instancetype)initWithString:(NSString*)string error:(JSONModelError**)err; - - /** - * Create a new model instance and initialize it with the JSON from a text parameter using the given encoding. - * @param string JSON text data - * @param encoding the text encoding to use when parsing the string (see NSStringEncoding) - * @param err an initialization error or nil - * @exception JSONModelTypeNotAllowedException thrown when unsported type is found in the incoming JSON, - * or a property type in your model is not supported by JSONValueTransformer and its categories - */ - -(instancetype)initWithString:(NSString *)string usingEncoding:(NSStringEncoding)encoding error:(JSONModelError**)err; - - -(instancetype)initWithDictionary:(NSDictionary*)dict error:(NSError **)err; - - -(instancetype)initWithData:(NSData *)data error:(NSError **)error; - -/** @name Exporting model contents */ - - /** - * Export the whole object to a dictionary - * @return dictionary containing the data model - */ - -(NSDictionary*)toDictionary; - - /** - * Export the whole object to a JSON data text string - * @return JSON text describing the data model - */ - -(NSString*)toJSONString; - - /** - * Export the specified properties of the object to a dictionary - * @param propertyNames the properties to export; if nil, all properties exported - * @return dictionary containing the data model - */ - -(NSDictionary*)toDictionaryWithKeys:(NSArray*)propertyNames; - - /** - * Export the specified properties of the object to a JSON data text string - * @param propertyNames the properties to export; if nil, all properties exported - * @return JSON text describing the data model - */ - -(NSString*)toJSONStringWithKeys:(NSArray*)propertyNames; - -/** @name Batch methods */ - - /** - * If you have a list of dictionaries in a JSON feed, you can use this method to create an NSArray - * of model objects. Handy when importing JSON data lists. - * This method will loop over the input list and initialize a data model for every dictionary in the list. - * - * @param array list of dictionaries to be imported as models - * @return list of initialized data model objects - * @exception JSONModelTypeNotAllowedException thrown when unsported type is found in the incoming JSON, - * or a property type in your model is not supported by JSONValueTransformer and its categories - * @exception JSONModelInvalidDataException thrown when the input data does not include all required keys - * @see arrayOfDictionariesFromModels: - */ - +(NSMutableArray*)arrayOfModelsFromDictionaries:(NSArray*)array; - - +(NSMutableArray*)arrayOfModelsFromDictionaries:(NSArray*)array error:(NSError**)err; - - +(NSMutableArray*)arrayOfModelsFromData:(NSData*)data error:(NSError**)err; - - /** - * If you have an NSArray of data model objects, this method takes it in and outputs a list of the - * matching dictionaries. This method does the opposite of arrayOfObjectsFromDictionaries: - * @param array list of JSONModel objects - * @return a list of NSDictionary objects - * @exception JSONModelTypeNotAllowedException thrown when unsported type is found in the incoming JSON, - * or a property type in your model is not supported by JSONValueTransformer and its categories - * @see arrayOfModelsFromDictionaries: - */ - +(NSMutableArray*)arrayOfDictionariesFromModels:(NSArray*)array; - - - -/** @name Comparing models */ - - /** - * The name of the model's property, which is considered the model's unique identifier. - * You can define Index property by using the Index protocol: - * @property (strong, nonatomic) NSString<Index>* id; - */ - -(NSString*)indexPropertyName; - - /** - * Overriden NSObject method to compare model objects. Compares the <Index> property of the two models, - * if an index property is defined. - * @param object a JSONModel instance to compare to for equality - */ - -(BOOL)isEqual:(id)object; - - /** - * Comparision method, which uses the defined <Index> property of the two models, to compare them. - * If there isn't an index property throws an exception. If the Index property does not have a compare: method - * also throws an exception. NSString and NSNumber have compare: methods, and in case the Index property is - * a another custom class, the programmer should create a custom compare: method then. - * @param object a JSONModel instance to compare to - */ - -(NSComparisonResult)compare:(id)object; - -/** @name Validation */ - - /** - * Overwrite the validate method in your own models if you need to perform some custom validation over the model data. - * This method gets called at the very end of the JSONModel initializer, thus the model is in the state that you would - * get it back when initialzed. Check the values of any property that needs to be validated and if any invalid values - * are encountered return NO and set the error parameter to an NSError object. If the model is valid return YES. - * - * NB: Only setting the error parameter is not enough to fail the validation, you also need to return a NO value. - * - * @param error a pointer to an NSError object, to pass back an error if needed - * @return a BOOL result, showing whether the model data validates or not. You can use the convenience method - * [JSONModelError errorModelIsInvalid] to set the NSError param if the data fails your custom validation - */ --(BOOL)validate:(NSError**)error; - -/** @name Key mapping */ - /** - * Overwrite in your models if your property names don't match your JSON key names. - * Lookup JSONKeyMapper docs for more details. - */ -+(JSONKeyMapper*)keyMapper; - -/** - * Sets a key mapper which affects ALL the models in your project. Use this if you need only one mapper to work - * with your API. For example if you are using the [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase] it is more - * likely that you will need to use it with ALL of your models. - * NB: Custom key mappers take precendence over the global key mapper. - * @param globalKeyMapper a key mapper to apply to all models in your project. - * - * Lookup JSONKeyMapper docs for more details. - */ -+(void)setGlobalKeyMapper:(JSONKeyMapper*)globalKeyMapper; - -/** - * Indicates whether the property with the given name is Optional. - * To have a model with all of its properties being Optional just return YES. - * This method returns by default NO, since the default behaviour is to have all properties required. - * @param propertyName the name of the property - * @return a BOOL result indicating whether the property is optional - */ -+(BOOL)propertyIsOptional:(NSString*)propertyName; - -/** - * Indicates whether the property with the given name is Ignored. - * To have a model with all of its properties being Ignored just return YES. - * This method returns by default NO, since the default behaviour is to have all properties required. - * @param propertyName the name of the property - * @return a BOOL result indicating whether the property is ignored - */ -+(BOOL)propertyIsIgnored:(NSString*)propertyName; - -/** - * Merges values from the given dictionary into the model instance. - * @param dict dictionary with values - * @param useKeyMapping if YES the method will use the model's key mapper and the global key mapper, if NO - * it'll just try to match the dictionary keys to the model's properties - */ --(void)mergeFromDictionary:(NSDictionary*)dict useKeyMapping:(BOOL)useKeyMapping; - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.m deleted file mode 100644 index 0354ad0..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModel.m +++ /dev/null @@ -1,1294 +0,0 @@ -// -// JSONModel.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#if !__has_feature(objc_arc) -#error The JSONMOdel framework is ARC only, you can enable ARC on per file basis. -#endif - - -#import -#import - - -#import "JSONModel.h" -#import "JSONModelClassProperty.h" -#import "JSONModelArray.h" - -#pragma mark - associated objects names -static const char * kMapperObjectKey; -static const char * kClassPropertiesKey; -static const char * kClassRequiredPropertyNamesKey; -static const char * kIndexPropertyNameKey; - -#pragma mark - class static variables -static NSArray* allowedJSONTypes = nil; -static NSArray* allowedPrimitiveTypes = nil; -static JSONValueTransformer* valueTransformer = nil; -static Class JSONModelClass = NULL; - -#pragma mark - model cache -static JSONKeyMapper* globalKeyMapper = nil; - -#pragma mark - JSONModel implementation -@implementation JSONModel -{ - NSString* _description; -} - -#pragma mark - initialization methods - -+(void)load -{ - static dispatch_once_t once; - dispatch_once(&once, ^{ - // initialize all class static objects, - // which are common for ALL JSONModel subclasses - - @autoreleasepool { - allowedJSONTypes = @[ - [NSString class], [NSNumber class], [NSDecimalNumber class], [NSArray class], [NSDictionary class], [NSNull class], //immutable JSON classes - [NSMutableString class], [NSMutableArray class], [NSMutableDictionary class] //mutable JSON classes - ]; - - allowedPrimitiveTypes = @[ - @"BOOL", @"float", @"int", @"long", @"double", @"short", - //and some famous aliases - @"NSInteger", @"NSUInteger", - @"Block" - ]; - - valueTransformer = [[JSONValueTransformer alloc] init]; - - // This is quite strange, but I found the test isSubclassOfClass: (line ~291) to fail if using [JSONModel class]. - // somewhat related: https://stackoverflow.com/questions/6524165/nsclassfromstring-vs-classnamednsstring - // //; seems to break the unit tests - - // Using NSClassFromString instead of [JSONModel class], as this was breaking unit tests, see below - //http://stackoverflow.com/questions/21394919/xcode-5-unit-test-seeing-wrong-class - JSONModelClass = NSClassFromString(NSStringFromClass(self)); - } - }); -} - --(void)__setup__ -{ - //if first instance of this model, generate the property list - if (!objc_getAssociatedObject(self.class, &kClassPropertiesKey)) { - [self __inspectProperties]; - } - - //if there's a custom key mapper, store it in the associated object - id mapper = [[self class] keyMapper]; - if ( mapper && !objc_getAssociatedObject(self.class, &kMapperObjectKey) ) { - objc_setAssociatedObject( - self.class, - &kMapperObjectKey, - mapper, - OBJC_ASSOCIATION_RETAIN // This is atomic - ); - } -} - --(id)init -{ - self = [super init]; - if (self) { - //do initial class setup - [self __setup__]; - } - return self; -} - --(instancetype)initWithData:(NSData *)data error:(NSError *__autoreleasing *)err -{ - //check for nil input - if (!data) { - if (err) *err = [JSONModelError errorInputIsNil]; - return nil; - } - //read the json - JSONModelError* initError = nil; - id obj = [NSJSONSerialization JSONObjectWithData:data - options:kNilOptions - error:&initError]; - - if (initError) { - if (err) *err = [JSONModelError errorBadJSON]; - return nil; - } - - //init with dictionary - id objModel = [self initWithDictionary:obj error:&initError]; - if (initError && err) *err = initError; - return objModel; -} - --(id)initWithString:(NSString*)string error:(JSONModelError**)err -{ - JSONModelError* initError = nil; - id objModel = [self initWithString:string usingEncoding:NSUTF8StringEncoding error:&initError]; - if (initError && err) *err = initError; - return objModel; -} - --(id)initWithString:(NSString *)string usingEncoding:(NSStringEncoding)encoding error:(JSONModelError**)err -{ - //check for nil input - if (!string) { - if (err) *err = [JSONModelError errorInputIsNil]; - return nil; - } - - JSONModelError* initError = nil; - id objModel = [self initWithData:[string dataUsingEncoding:encoding] error:&initError]; - if (initError && err) *err = initError; - return objModel; - -} - --(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err -{ - //check for nil input - if (!dict) { - if (err) *err = [JSONModelError errorInputIsNil]; - return nil; - } - - //invalid input, just create empty instance - if (![dict isKindOfClass:[NSDictionary class]]) { - if (err) *err = [JSONModelError errorInvalidDataWithMessage:@"Attempt to initialize JSONModel object using initWithDictionary:error: but the dictionary parameter was not an 'NSDictionary'."]; - return nil; - } - - //create a class instance - self = [self init]; - if (!self) { - - //super init didn't succeed - if (err) *err = [JSONModelError errorModelIsInvalid]; - return nil; - } - - //check incoming data structure - if (![self __doesDictionary:dict matchModelWithKeyMapper:self.__keyMapper error:err]) { - return nil; - } - - //import the data from a dictionary - if (![self __importDictionary:dict withKeyMapper:self.__keyMapper validation:YES error:err]) { - return nil; - } - - //run any custom model validation - if (![self validate:err]) { - return nil; - } - - //model is valid! yay! - return self; -} - --(JSONKeyMapper*)__keyMapper -{ - //get the model key mapper - return objc_getAssociatedObject(self.class, &kMapperObjectKey); -} - --(BOOL)__doesDictionary:(NSDictionary*)dict matchModelWithKeyMapper:(JSONKeyMapper*)keyMapper error:(NSError**)err -{ - //check if all required properties are present - NSArray* incomingKeysArray = [dict allKeys]; - NSMutableSet* requiredProperties = [self __requiredPropertyNames]; - NSSet* incomingKeys = [NSSet setWithArray: incomingKeysArray]; - - //transform the key names, if neccessary - if (keyMapper || globalKeyMapper) { - - NSMutableSet* transformedIncomingKeys = [NSMutableSet setWithCapacity: requiredProperties.count]; - NSString* transformedName = nil; - - //loop over the required properties list - for (JSONModelClassProperty* property in [self __properties__]) { - - transformedName = (keyMapper||globalKeyMapper) ? [self __mapString:property.name withKeyMapper:keyMapper importing:YES] : property.name; - - //chek if exists and if so, add to incoming keys - id value; - @try { - value = [dict valueForKeyPath:transformedName]; - } - @catch (NSException *exception) { - value = dict[transformedName]; - } - - if (value) { - [transformedIncomingKeys addObject: property.name]; - } - } - - //overwrite the raw incoming list with the mapped key names - incomingKeys = transformedIncomingKeys; - } - - //check for missing input keys - if (![requiredProperties isSubsetOfSet:incomingKeys]) { - - //get a list of the missing properties - [requiredProperties minusSet:incomingKeys]; - - //not all required properties are in - invalid input - JMLog(@"Incoming data was invalid [%@ initWithDictionary:]. Keys missing: %@", self.class, requiredProperties); - - if (err) *err = [JSONModelError errorInvalidDataWithMissingKeys:requiredProperties]; - return NO; - } - - //not needed anymore - incomingKeys= nil; - requiredProperties= nil; - - return YES; -} - --(NSString*)__mapString:(NSString*)string withKeyMapper:(JSONKeyMapper*)keyMapper importing:(BOOL)importing -{ - if (keyMapper) { - //custom mapper - NSString* mappedName = [keyMapper convertValue:string isImportingToModel:importing]; - if (globalKeyMapper && [mappedName isEqualToString: string]) { - mappedName = [globalKeyMapper convertValue:string isImportingToModel:importing]; - } - string = mappedName; - } else if (globalKeyMapper) { - //global keymapper - string = [globalKeyMapper convertValue:string isImportingToModel:importing]; - } - - return string; -} - --(BOOL)__importDictionary:(NSDictionary*)dict withKeyMapper:(JSONKeyMapper*)keyMapper validation:(BOOL)validation error:(NSError**)err -{ - //loop over the incoming keys and set self's properties - for (JSONModelClassProperty* property in [self __properties__]) { - - //convert key name ot model keys, if a mapper is provided - NSString* jsonKeyPath = (keyMapper||globalKeyMapper) ? [self __mapString:property.name withKeyMapper:keyMapper importing:YES] : property.name; - //JMLog(@"keyPath: %@", jsonKeyPath); - - //general check for data type compliance - id jsonValue; - @try { - jsonValue = [dict valueForKeyPath: jsonKeyPath]; - } - @catch (NSException *exception) { - jsonValue = dict[jsonKeyPath]; - } - - //check for Optional properties - if (isNull(jsonValue)) { - //skip this property, continue with next property - if (property.isOptional || !validation) continue; - - if (err) { - //null value for required property - NSString* msg = [NSString stringWithFormat:@"Value of required model key %@ is null", property.name]; - JSONModelError* dataErr = [JSONModelError errorInvalidDataWithMessage:msg]; - *err = [dataErr errorByPrependingKeyPathComponent:property.name]; - } - return NO; - } - - Class jsonValueClass = [jsonValue class]; - BOOL isValueOfAllowedType = NO; - - for (Class allowedType in allowedJSONTypes) { - if ( [jsonValueClass isSubclassOfClass: allowedType] ) { - isValueOfAllowedType = YES; - break; - } - } - - if (isValueOfAllowedType==NO) { - //type not allowed - JMLog(@"Type %@ is not allowed in JSON.", NSStringFromClass(jsonValueClass)); - - if (err) { - NSString* msg = [NSString stringWithFormat:@"Type %@ is not allowed in JSON.", NSStringFromClass(jsonValueClass)]; - JSONModelError* dataErr = [JSONModelError errorInvalidDataWithMessage:msg]; - *err = [dataErr errorByPrependingKeyPathComponent:property.name]; - } - return NO; - } - - //check if there's matching property in the model - if (property) { - - // check for custom setter, than the model doesn't need to do any guessing - // how to read the property's value from JSON - if ([self __customSetValue:jsonValue forProperty:property]) { - //skip to next JSON key - continue; - }; - - // 0) handle primitives - if (property.type == nil && property.structName==nil) { - - //generic setter - if (jsonValue != [self valueForKey:property.name]) { - [self setValue:jsonValue forKey: property.name]; - } - - //skip directly to the next key - continue; - } - - // 0.5) handle nils - if (isNull(jsonValue)) { - if ([self valueForKey:property.name] != nil) { - [self setValue:nil forKey: property.name]; - } - continue; - } - - - // 1) check if property is itself a JSONModel - if ([self __isJSONModelSubClass:property.type]) { - - //initialize the property's model, store it - JSONModelError* initErr = nil; - id value = [[property.type alloc] initWithDictionary: jsonValue error:&initErr]; - - if (!value) { - //skip this property, continue with next property - if (property.isOptional || !validation) continue; - - // Propagate the error, including the property name as the key-path component - if((err != nil) && (initErr != nil)) - { - *err = [initErr errorByPrependingKeyPathComponent:property.name]; - } - return NO; - } - if (![value isEqual:[self valueForKey:property.name]]) { - [self setValue:value forKey: property.name]; - } - - //for clarity, does the same without continue - continue; - - } else { - - // 2) check if there's a protocol to the property - // ) might or not be the case there's a built in transofrm for it - if (property.protocol) { - - //JMLog(@"proto: %@", p.protocol); - jsonValue = [self __transform:jsonValue forProperty:property error:err]; - if (!jsonValue) { - if ((err != nil) && (*err == nil)) { - NSString* msg = [NSString stringWithFormat:@"Failed to transform value, but no error was set during transformation. (%@)", property]; - JSONModelError* dataErr = [JSONModelError errorInvalidDataWithMessage:msg]; - *err = [dataErr errorByPrependingKeyPathComponent:property.name]; - } - return NO; - } - } - - // 3.1) handle matching standard JSON types - if (property.isStandardJSONType && [jsonValue isKindOfClass: property.type]) { - - //mutable properties - if (property.isMutable) { - jsonValue = [jsonValue mutableCopy]; - } - - //set the property value - if (![jsonValue isEqual:[self valueForKey:property.name]]) { - [self setValue:jsonValue forKey: property.name]; - } - continue; - } - - // 3.3) handle values to transform - if ( - (![jsonValue isKindOfClass:property.type] && !isNull(jsonValue)) - || - //the property is mutable - property.isMutable - || - //custom struct property - property.structName - ) { - - // searched around the web how to do this better - // but did not find any solution, maybe that's the best idea? (hardly) - Class sourceClass = [JSONValueTransformer classByResolvingClusterClasses:[jsonValue class]]; - - //JMLog(@"to type: [%@] from type: [%@] transformer: [%@]", p.type, sourceClass, selectorName); - - //build a method selector for the property and json object classes - NSString* selectorName = [NSString stringWithFormat:@"%@From%@:", - (property.structName? property.structName : property.type), //target name - sourceClass]; //source name - SEL selector = NSSelectorFromString(selectorName); - - //check for custom transformer - BOOL foundCustomTransformer = NO; - if ([valueTransformer respondsToSelector:selector]) { - foundCustomTransformer = YES; - } else { - //try for hidden custom transformer - selectorName = [NSString stringWithFormat:@"__%@",selectorName]; - selector = NSSelectorFromString(selectorName); - if ([valueTransformer respondsToSelector:selector]) { - foundCustomTransformer = YES; - } - } - - //check if there's a transformer with that name - if (foundCustomTransformer) { - - //it's OK, believe me... -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - //transform the value - jsonValue = [valueTransformer performSelector:selector withObject:jsonValue]; -#pragma clang diagnostic pop - - if (![jsonValue isEqual:[self valueForKey:property.name]]) { - [self setValue:jsonValue forKey: property.name]; - } - - } else { - - // it's not a JSON data type, and there's no transformer for it - // if property type is not supported - that's a programmer mistaked -> exception - @throw [NSException exceptionWithName:@"Type not allowed" - reason:[NSString stringWithFormat:@"%@ type not supported for %@.%@", property.type, [self class], property.name] - userInfo:nil]; - return NO; - } - - } else { - // 3.4) handle "all other" cases (if any) - if (![jsonValue isEqual:[self valueForKey:property.name]]) { - [self setValue:jsonValue forKey: property.name]; - } - } - } - } - } - - return YES; -} - -#pragma mark - property inspection methods - --(BOOL)__isJSONModelSubClass:(Class)class -{ -// http://stackoverflow.com/questions/19883472/objc-nsobject-issubclassofclass-gives-incorrect-failure -#ifdef UNIT_TESTING - return [@"JSONModel" isEqualToString: NSStringFromClass([class superclass])]; -#else - return [class isSubclassOfClass:JSONModelClass]; -#endif -} - -//returns a set of the required keys for the model --(NSMutableSet*)__requiredPropertyNames -{ - //fetch the associated property names - NSMutableSet* classRequiredPropertyNames = objc_getAssociatedObject(self.class, &kClassRequiredPropertyNamesKey); - - if (!classRequiredPropertyNames) { - classRequiredPropertyNames = [NSMutableSet set]; - [[self __properties__] enumerateObjectsUsingBlock:^(JSONModelClassProperty* p, NSUInteger idx, BOOL *stop) { - if (!p.isOptional) [classRequiredPropertyNames addObject:p.name]; - }]; - - //persist the list - objc_setAssociatedObject( - self.class, - &kClassRequiredPropertyNamesKey, - classRequiredPropertyNames, - OBJC_ASSOCIATION_RETAIN // This is atomic - ); - } - return classRequiredPropertyNames; -} - -//returns a list of the model's properties --(NSArray*)__properties__ -{ - //fetch the associated object - NSDictionary* classProperties = objc_getAssociatedObject(self.class, &kClassPropertiesKey); - if (classProperties) return [classProperties allValues]; - - //if here, the class needs to inspect itself - [self __setup__]; - - //return the property list - classProperties = objc_getAssociatedObject(self.class, &kClassPropertiesKey); - return [classProperties allValues]; -} - -//inspects the class, get's a list of the class properties --(void)__inspectProperties -{ - //JMLog(@"Inspect class: %@", [self class]); - - NSMutableDictionary* propertyIndex = [NSMutableDictionary dictionary]; - - //temp variables for the loops - Class class = [self class]; - NSScanner* scanner = nil; - NSString* propertyType = nil; - - // inspect inherited properties up to the JSONModel class - while (class != [JSONModel class]) { - //JMLog(@"inspecting: %@", NSStringFromClass(class)); - - unsigned int propertyCount; - objc_property_t *properties = class_copyPropertyList(class, &propertyCount); - - //loop over the class properties - for (unsigned int i = 0; i < propertyCount; i++) { - - JSONModelClassProperty* p = [[JSONModelClassProperty alloc] init]; - - //get property name - objc_property_t property = properties[i]; - const char *propertyName = property_getName(property); - p.name = @(propertyName); - - //JMLog(@"property: %@", p.name); - - //get property attributes - const char *attrs = property_getAttributes(property); - NSString* propertyAttributes = @(attrs); - NSArray* attributeItems = [propertyAttributes componentsSeparatedByString:@","]; - - //ignore read-only properties - if ([attributeItems containsObject:@"R"]) { - continue; //to next property - } - - //check for 64b BOOLs - if ([propertyAttributes hasPrefix:@"Tc,"]) { - //mask BOOLs as structs so they can have custom convertors - p.structName = @"BOOL"; - } - - scanner = [NSScanner scannerWithString: propertyAttributes]; - - //JMLog(@"attr: %@", [NSString stringWithCString:attrs encoding:NSUTF8StringEncoding]); - [scanner scanUpToString:@"T" intoString: nil]; - [scanner scanString:@"T" intoString:nil]; - - //check if the property is an instance of a class - if ([scanner scanString:@"@\"" intoString: &propertyType]) { - - [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\"<"] - intoString:&propertyType]; - - //JMLog(@"type: %@", propertyClassName); - p.type = NSClassFromString(propertyType); - p.isMutable = ([propertyType rangeOfString:@"Mutable"].location != NSNotFound); - p.isStandardJSONType = [allowedJSONTypes containsObject:p.type]; - - //read through the property protocols - while ([scanner scanString:@"<" intoString:NULL]) { - - NSString* protocolName = nil; - - [scanner scanUpToString:@">" intoString: &protocolName]; - - if ([protocolName isEqualToString:@"Optional"]) { - p.isOptional = YES; - } else if([protocolName isEqualToString:@"Index"]) { - p.isIndex = YES; - objc_setAssociatedObject( - self.class, - &kIndexPropertyNameKey, - p.name, - OBJC_ASSOCIATION_RETAIN // This is atomic - ); - } else if([protocolName isEqualToString:@"ConvertOnDemand"]) { - p.convertsOnDemand = YES; - } else if([protocolName isEqualToString:@"Ignore"]) { - p = nil; - } else { - p.protocol = protocolName; - } - - [scanner scanString:@">" intoString:NULL]; - } - - } - //check if the property is a structure - else if ([scanner scanString:@"{" intoString: &propertyType]) { - [scanner scanCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] - intoString:&propertyType]; - - p.isStandardJSONType = NO; - p.structName = propertyType; - - } - //the property must be a primitive - else { - - //the property contains a primitive data type - [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@","] - intoString:&propertyType]; - - //get the full name of the primitive type - propertyType = valueTransformer.primitivesNames[propertyType]; - - if (![allowedPrimitiveTypes containsObject:propertyType]) { - - //type not allowed - programmer mistaked -> exception - @throw [NSException exceptionWithName:@"JSONModelProperty type not allowed" - reason:[NSString stringWithFormat:@"Property type of %@.%@ is not supported by JSONModel.", self.class, p.name] - userInfo:nil]; - } - - } - - NSString *nsPropertyName = @(propertyName); - if([[self class] propertyIsOptional:nsPropertyName]){ - p.isOptional = YES; - } - - if([[self class] propertyIsIgnored:nsPropertyName]){ - p = nil; - } - - //few cases where JSONModel will ignore properties automatically - if ([propertyType isEqualToString:@"Block"]) { - p = nil; - } - - //add the property object to the temp index - if (p && ![propertyIndex objectForKey:p.name]) { - [propertyIndex setValue:p forKey:p.name]; - } - } - - free(properties); - - //ascend to the super of the class - //(will do that until it reaches the root class - JSONModel) - class = [class superclass]; - } - - //finally store the property index in the static property index - objc_setAssociatedObject( - self.class, - &kClassPropertiesKey, - [propertyIndex copy], - OBJC_ASSOCIATION_RETAIN // This is atomic - ); -} - -#pragma mark - built-in transformer methods -//few built-in transformations --(id)__transform:(id)value forProperty:(JSONModelClassProperty*)property error:(NSError**)err -{ - Class protocolClass = NSClassFromString(property.protocol); - if (!protocolClass) { - - //no other protocols on arrays and dictionaries - //except JSONModel classes - if ([value isKindOfClass:[NSArray class]]) { - @throw [NSException exceptionWithName:@"Bad property protocol declaration" - reason:[NSString stringWithFormat:@"<%@> is not allowed JSONModel property protocol, and not a JSONModel class.", property.protocol] - userInfo:nil]; - } - return value; - } - - //if the protocol is actually a JSONModel class - if ([self __isJSONModelSubClass:protocolClass]) { - - //check if it's a list of models - if ([property.type isSubclassOfClass:[NSArray class]]) { - - // Expecting an array, make sure 'value' is an array - if(![[value class] isSubclassOfClass:[NSArray class]]) - { - if(err != nil) - { - NSString* mismatch = [NSString stringWithFormat:@"Property '%@' is declared as NSArray<%@>* but the corresponding JSON value is not a JSON Array.", property.name, property.protocol]; - JSONModelError* typeErr = [JSONModelError errorInvalidDataWithTypeMismatch:mismatch]; - *err = [typeErr errorByPrependingKeyPathComponent:property.name]; - } - return nil; - } - - if (property.convertsOnDemand) { - //on demand conversion - value = [[JSONModelArray alloc] initWithArray:value modelClass:[protocolClass class]]; - - } else { - //one shot conversion - JSONModelError* arrayErr = nil; - value = [[protocolClass class] arrayOfModelsFromDictionaries:value error:&arrayErr]; - if((err != nil) && (arrayErr != nil)) - { - *err = [arrayErr errorByPrependingKeyPathComponent:property.name]; - return nil; - } - } - } - - //check if it's a dictionary of models - if ([property.type isSubclassOfClass:[NSDictionary class]]) { - - // Expecting a dictionary, make sure 'value' is a dictionary - if(![[value class] isSubclassOfClass:[NSDictionary class]]) - { - if(err != nil) - { - NSString* mismatch = [NSString stringWithFormat:@"Property '%@' is declared as NSDictionary<%@>* but the corresponding JSON value is not a JSON Object.", property.name, property.protocol]; - JSONModelError* typeErr = [JSONModelError errorInvalidDataWithTypeMismatch:mismatch]; - *err = [typeErr errorByPrependingKeyPathComponent:property.name]; - } - return nil; - } - - NSMutableDictionary* res = [NSMutableDictionary dictionary]; - - for (NSString* key in [value allKeys]) { - JSONModelError* initErr = nil; - id obj = [[[protocolClass class] alloc] initWithDictionary:value[key] error:&initErr]; - if (obj == nil) - { - // Propagate the error, including the property name as the key-path component - if((err != nil) && (initErr != nil)) - { - initErr = [initErr errorByPrependingKeyPathComponent:key]; - *err = [initErr errorByPrependingKeyPathComponent:property.name]; - } - return nil; - } - [res setValue:obj forKey:key]; - } - value = [NSDictionary dictionaryWithDictionary:res]; - } - } - - return value; -} - -//built-in reverse transormations (export to JSON compliant objects) --(id)__reverseTransform:(id)value forProperty:(JSONModelClassProperty*)property -{ - Class protocolClass = NSClassFromString(property.protocol); - if (!protocolClass) return value; - - //if the protocol is actually a JSONModel class - if ([self __isJSONModelSubClass:protocolClass]) { - - //check if should export list of dictionaries - if (property.type == [NSArray class] || property.type == [NSMutableArray class]) { - NSMutableArray* tempArray = [NSMutableArray arrayWithCapacity: [(NSArray*)value count] ]; - for (NSObject* model in (NSArray*)value) { - if ([model respondsToSelector:@selector(toDictionary)]) { - [tempArray addObject: [model toDictionary]]; - } else - [tempArray addObject: model]; - } - return [tempArray copy]; - } - - //check if should export dictionary of dictionaries - if (property.type == [NSDictionary class] || property.type == [NSMutableDictionary class]) { - NSMutableDictionary* res = [NSMutableDictionary dictionary]; - for (NSString* key in [(NSDictionary*)value allKeys]) { - id model = value[key]; - [res setValue: [model toDictionary] forKey: key]; - } - return [NSDictionary dictionaryWithDictionary:res]; - } - } - - return value; -} - -#pragma mark - custom transformations --(BOOL)__customSetValue:(id)value forProperty:(JSONModelClassProperty*)property -{ - if (property.setterType == kNotInspected) { - //check for a custom property setter method - NSString* ucfirstName = [property.name stringByReplacingCharactersInRange:NSMakeRange(0,1) - withString:[[property.name substringToIndex:1] uppercaseString]]; - NSString* selectorName = [NSString stringWithFormat:@"set%@With%@:", ucfirstName, - [JSONValueTransformer classByResolvingClusterClasses:[value class]] - ]; - - SEL customPropertySetter = NSSelectorFromString(selectorName); - - //check if there's a custom selector like this - if (![self respondsToSelector: customPropertySetter]) { - property.setterType = kNo; - return NO; - } - - //cache the custom setter selector - property.setterType = kCustom; - property.customSetter = customPropertySetter; - } - - if (property.setterType==kCustom) { - //call the custom setter - //https://github.com/steipete - ((void (*) (id, SEL, id))objc_msgSend)(self, property.customSetter, value); - return YES; - } - - return NO; -} - --(BOOL)__customGetValue:(id*)value forProperty:(JSONModelClassProperty*)property -{ - if (property.getterType == kNotInspected) { - //check for a custom property getter method - NSString* ucfirstName = [property.name stringByReplacingCharactersInRange: NSMakeRange(0,1) - withString: [[property.name substringToIndex:1] uppercaseString]]; - NSString* selectorName = [NSString stringWithFormat:@"JSONObjectFor%@", ucfirstName]; - - SEL customPropertyGetter = NSSelectorFromString(selectorName); - if (![self respondsToSelector: customPropertyGetter]) { - property.getterType = kNo; - return NO; - } - - property.getterType = kCustom; - property.customGetter = customPropertyGetter; - - } - - if (property.getterType==kCustom) { - //call the custom getter - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - *value = [self performSelector:property.customGetter]; - #pragma clang diagnostic pop - return YES; - } - - return NO; -} - -#pragma mark - persistance --(void)__createDictionariesForKeyPath:(NSString*)keyPath inDictionary:(NSMutableDictionary**)dict -{ - //find if there's a dot left in the keyPath - NSUInteger dotLocation = [keyPath rangeOfString:@"."].location; - if (dotLocation==NSNotFound) return; - - //inspect next level - NSString* nextHierarchyLevelKeyName = [keyPath substringToIndex: dotLocation]; - NSDictionary* nextLevelDictionary = (*dict)[nextHierarchyLevelKeyName]; - - if (nextLevelDictionary==nil) { - //create non-existing next level here - nextLevelDictionary = [NSMutableDictionary dictionary]; - } - - //recurse levels - [self __createDictionariesForKeyPath:[keyPath substringFromIndex: dotLocation+1] - inDictionary:&nextLevelDictionary ]; - - //create the hierarchy level - [*dict setValue:nextLevelDictionary forKeyPath: nextHierarchyLevelKeyName]; -} - --(NSDictionary*)toDictionary -{ - return [self toDictionaryWithKeys:nil]; -} - --(NSString*)toJSONString -{ - return [self toJSONStringWithKeys:nil]; -} - -//exports the model as a dictionary of JSON compliant objects --(NSDictionary*)toDictionaryWithKeys:(NSArray*)propertyNames -{ - NSArray* properties = [self __properties__]; - NSMutableDictionary* tempDictionary = [NSMutableDictionary dictionaryWithCapacity:properties.count]; - - id value; - - //loop over all properties - for (JSONModelClassProperty* p in properties) { - - //skip if unwanted - if (propertyNames != nil && ![propertyNames containsObject:p.name]) - continue; - - //fetch key and value - NSString* keyPath = (self.__keyMapper||globalKeyMapper) ? [self __mapString:p.name withKeyMapper:self.__keyMapper importing:YES] : p.name; - value = [self valueForKey: p.name]; - - //JMLog(@"toDictionary[%@]->[%@] = '%@'", p.name, keyPath, value); - - if ([keyPath rangeOfString:@"."].location != NSNotFound) { - //there are sub-keys, introduce dictionaries for them - [self __createDictionariesForKeyPath:keyPath inDictionary:&tempDictionary]; - } - - //check for custom getter - if ([self __customGetValue:&value forProperty:p]) { - //custom getter, all done - [tempDictionary setValue:value forKeyPath:keyPath]; - continue; - } - - //export nil when they are not optional values as JSON null, so that the structure of the exported data - //is still valid if it's to be imported as a model again - if (isNull(value)) { - - if (p.isOptional) - { - [tempDictionary removeObjectForKey:keyPath]; - } - else - { - [tempDictionary setValue:[NSNull null] forKeyPath:keyPath]; - } - continue; - } - - //check if the property is another model - if ([value isKindOfClass:JSONModelClass]) { - - //recurse models - value = [(JSONModel*)value toDictionary]; - [tempDictionary setValue:value forKeyPath: keyPath]; - - //for clarity - continue; - - } else { - - // 1) check for built-in transformation - if (p.protocol) { - value = [self __reverseTransform:value forProperty:p]; - } - - // 2) check for standard types OR 2.1) primitives - if (p.structName==nil && (p.isStandardJSONType || p.type==nil)) { - - //generic get value - [tempDictionary setValue:value forKeyPath: keyPath]; - - continue; - } - - // 3) try to apply a value transformer - if (YES) { - - //create selector from the property's class name - NSString* selectorName = [NSString stringWithFormat:@"%@From%@:", @"JSONObject", p.type?p.type:p.structName]; - SEL selector = NSSelectorFromString(selectorName); - - BOOL foundCustomTransformer = NO; - if ([valueTransformer respondsToSelector:selector]) { - foundCustomTransformer = YES; - } else { - //try for hidden transformer - selectorName = [NSString stringWithFormat:@"__%@",selectorName]; - selector = NSSelectorFromString(selectorName); - if ([valueTransformer respondsToSelector:selector]) { - foundCustomTransformer = YES; - } - } - - //check if there's a transformer declared - if (foundCustomTransformer) { - - //it's OK, believe me... -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - value = [valueTransformer performSelector:selector withObject:value]; -#pragma clang diagnostic pop - - [tempDictionary setValue:value forKeyPath: keyPath]; - - } else { - - //in this case most probably a custom property was defined in a model - //but no default reverse transofrmer for it - @throw [NSException exceptionWithName:@"Value transformer not found" - reason:[NSString stringWithFormat:@"[JSONValueTransformer %@] not found", selectorName] - userInfo:nil]; - return nil; - } - } - } - } - - return [tempDictionary copy]; -} - -//exports model to a dictionary and then to a JSON string --(NSString*)toJSONStringWithKeys:(NSArray*)propertyNames -{ - NSData* jsonData = nil; - NSError* jsonError = nil; - - @try { - NSDictionary* dict = [self toDictionaryWithKeys:propertyNames]; - jsonData = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&jsonError]; - } - @catch (NSException *exception) { - //this should not happen in properly design JSONModel - //usually means there was no reverse transformer for a custom property - JMLog(@"EXCEPTION: %@", exception.description); - return nil; - } - - return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; -} - -#pragma mark - import/export of lists -//loop over an NSArray of JSON objects and turn them into models -+(NSMutableArray*)arrayOfModelsFromDictionaries:(NSArray*)array -{ - return [self arrayOfModelsFromDictionaries:array error:nil]; -} - -+(NSMutableArray*)arrayOfModelsFromData:(NSData *)data error:(NSError *__autoreleasing *)err -{ - id json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:err]; - if (!json || ![json isKindOfClass:[NSArray class]]) return nil; - - return [self arrayOfModelsFromDictionaries:json error:err]; -} - -// Same as above, but with error reporting -+(NSMutableArray*)arrayOfModelsFromDictionaries:(NSArray*)array error:(NSError**)err -{ - //bail early - if (isNull(array)) return nil; - - //parse dictionaries to objects - NSMutableArray* list = [NSMutableArray arrayWithCapacity: [array count]]; - - for (id d in array) - { - if ([d isKindOfClass:NSDictionary.class]) - { - JSONModelError* initErr = nil; - id obj = [[self alloc] initWithDictionary:d error:&initErr]; - if (obj == nil) - { - // Propagate the error, including the array index as the key-path component - if((err != nil) && (initErr != nil)) - { - NSString* path = [NSString stringWithFormat:@"[%lu]", (unsigned long)list.count]; - *err = [initErr errorByPrependingKeyPathComponent:path]; - } - return nil; - } - - [list addObject: obj]; - } else if ([d isKindOfClass:NSArray.class]) - { - [list addObjectsFromArray:[self arrayOfModelsFromDictionaries:d error:err]]; - } else - { - // This is very bad - } - - } - - return list; -} - -//loop over NSArray of models and export them to JSON objects -+(NSMutableArray*)arrayOfDictionariesFromModels:(NSArray*)array -{ - //bail early - if (isNull(array)) return nil; - - //convert to dictionaries - NSMutableArray* list = [NSMutableArray arrayWithCapacity: [array count]]; - - for (id object in array) { - - id obj = [object toDictionary]; - if (!obj) return nil; - - [list addObject: obj]; - } - return list; -} - -//loop over NSArray of models and export them to JSON objects with specific properties -+(NSMutableArray*)arrayOfDictionariesFromModels:(NSArray*)array propertyNamesToExport:(NSArray*)propertyNamesToExport; -{ - //bail early - if (isNull(array)) return nil; - - //convert to dictionaries - NSMutableArray* list = [NSMutableArray arrayWithCapacity: [array count]]; - - for (id object in array) { - - id obj = [object toDictionaryWithKeys:propertyNamesToExport]; - if (!obj) return nil; - - [list addObject: obj]; - } - return list; -} - -#pragma mark - custom comparison methods --(NSString*)indexPropertyName -{ - //custom getter for an associated object - return objc_getAssociatedObject(self.class, &kIndexPropertyNameKey); -} - --(BOOL)isEqual:(id)object -{ - //bail early if different classes - if (![object isMemberOfClass:[self class]]) return NO; - - if (self.indexPropertyName) { - //there's a defined ID property - id objectId = [object valueForKey: self.indexPropertyName]; - return [[self valueForKey: self.indexPropertyName] isEqual:objectId]; - } - - //default isEqual implementation - return [super isEqual:object]; -} - --(NSComparisonResult)compare:(id)object -{ - if (self.indexPropertyName) { - id objectId = [object valueForKey: self.indexPropertyName]; - if ([objectId respondsToSelector:@selector(compare:)]) { - return [[self valueForKey:self.indexPropertyName] compare:objectId]; - } - } - - //on purpose postponing the asserts for speed optimization - //these should not happen anyway in production conditions - NSAssert(self.indexPropertyName, @"Can't compare models with no property"); - NSAssert1(NO, @"The property of %@ is not comparable class.", [self class]); - return kNilOptions; -} - -- (NSUInteger)hash -{ - if (self.indexPropertyName) { - return [self.indexPropertyName hash]; - } - - return [super hash]; -} - -#pragma mark - custom data validation --(BOOL)validate:(NSError**)error -{ - return YES; -} - -#pragma mark - custom recursive description -//custom description method for debugging purposes --(NSString*)description -{ - NSMutableString* text = [NSMutableString stringWithFormat:@"<%@> \n", [self class]]; - - for (JSONModelClassProperty *p in [self __properties__]) { - - id value = ([p.name isEqualToString:@"description"])?self->_description:[self valueForKey:p.name]; - NSString* valueDescription = (value)?[value description]:@""; - - if (p.isStandardJSONType && ![value respondsToSelector:@selector(count)] && [valueDescription length]>60 && !p.convertsOnDemand) { - - //cap description for longer values - valueDescription = [NSString stringWithFormat:@"%@...", [valueDescription substringToIndex:59]]; - } - valueDescription = [valueDescription stringByReplacingOccurrencesOfString:@"\n" withString:@"\n "]; - [text appendFormat:@" [%@]: %@\n", p.name, valueDescription]; - } - - [text appendFormat:@"", [self class]]; - return text; -} - -#pragma mark - key mapping -+(JSONKeyMapper*)keyMapper -{ - return nil; -} - -+(void)setGlobalKeyMapper:(JSONKeyMapper*)globalKeyMapperParam -{ - globalKeyMapper = globalKeyMapperParam; -} - -+(BOOL)propertyIsOptional:(NSString*)propertyName -{ - return NO; -} - -+(BOOL)propertyIsIgnored:(NSString *)propertyName -{ - return NO; -} - -#pragma mark - working with incomplete models --(void)mergeFromDictionary:(NSDictionary*)dict useKeyMapping:(BOOL)useKeyMapping -{ - [self __importDictionary:dict withKeyMapper:(useKeyMapping)? self.__keyMapper:nil validation:NO error:nil]; -} - -#pragma mark - NSCopying, NSCoding --(instancetype)copyWithZone:(NSZone *)zone -{ - return [NSKeyedUnarchiver unarchiveObjectWithData: - [NSKeyedArchiver archivedDataWithRootObject:self] - ]; -} - --(instancetype)initWithCoder:(NSCoder *)decoder -{ - NSString* json = [decoder decodeObjectForKey:@"json"]; - - self = [self initWithString:json error:nil]; - return self; -} - --(void)encodeWithCoder:(NSCoder *)encoder -{ - [encoder encodeObject:self.toJSONString forKey:@"json"]; -} - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.h deleted file mode 100644 index e858ad7..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// JSONModelArray.h -// -// @version 0.8.0 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -/** - * **Don't make instances of JSONModelArray yourself, except you know what you are doing.** - * - * You get automatically JSONModelArray instances, when you declare a convert on demand property, like so: - * - * @property (strong, nonatomic) NSArray<JSONModel, ConvertOnDemand>* list; - * - * The class stores its contents as they come from JSON, and upon the first request - * of each of the objects stored in the array, it'll be converted to the target model class. - * Thus saving time upon the very first model creation. - */ -@interface JSONModelArray : NSObject - -/** - * Don't make instances of JSONModelArray yourself, except you know what you are doing. - * - * @param array an array of NSDictionary objects - * @param cls the JSONModel sub-class you'd like the NSDictionaries to be converted to on demand - */ -- (id)initWithArray:(NSArray *)array modelClass:(Class)cls; - -- (id)objectAtIndex:(NSUInteger)index; -- (id)objectAtIndexedSubscript:(NSUInteger)index; -- (void)forwardInvocation:(NSInvocation *)anInvocation; -- (NSUInteger)count; -- (id)firstObject; -- (id)lastObject; - -/** - * Looks up the array's contents and tries to find a JSONModel object - * with matching index property value to the indexValue param. - * - * Will return nil if no matching model is found. Will return nil if there's no index property - * defined on the models found in the array (will sample the first object, assuming the array - * contains homogenous collection of objects) - * - * @param indexValue the id value to search for - * @return the found model or nil - */ -- (id)modelWithIndexValue:(id)indexValue; - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.m deleted file mode 100644 index 88eddc7..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelArray.m +++ /dev/null @@ -1,145 +0,0 @@ -// -// JSONModelArray.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModelArray.h" -#import "JSONModel.h" - -@implementation JSONModelArray -{ - NSMutableArray* _storage; - Class _targetClass; -} - --(id)initWithArray:(NSArray *)array modelClass:(Class)cls -{ - self = [super init]; - - if (self) { - _storage = [NSMutableArray arrayWithArray:array]; - _targetClass = cls; - } - return self; -} - --(id)firstObject -{ - return [self objectAtIndex:0]; -} - --(id)lastObject -{ - return [self objectAtIndex:_storage.count - 1]; -} - --(id)objectAtIndex:(NSUInteger)index -{ - return [self objectAtIndexedSubscript:index]; -} - --(id)objectAtIndexedSubscript:(NSUInteger)index -{ - id object = _storage[index]; - if (![object isMemberOfClass:_targetClass]) { - NSError* err = nil; - object = [[_targetClass alloc] initWithDictionary:object error:&err]; - if (object) { - _storage[index] = object; - } - } - return object; -} - --(void)forwardInvocation:(NSInvocation *)anInvocation -{ - [anInvocation invokeWithTarget:_storage]; -} - --(id)forwardingTargetForSelector:(SEL)selector -{ - static NSArray* overridenMethods = nil; - if (!overridenMethods) overridenMethods = @[@"initWithArray:modelClass:",@"objectAtIndex:",@"objectAtIndexedSubscript:", @"count",@"modelWithIndexValue:",@"description",@"mutableCopy",@"firstObject",@"lastObject",@"countByEnumeratingWithState:objects:count:"]; - if ([overridenMethods containsObject:NSStringFromSelector(selector)]) { - return self; - } - return _storage; -} - --(NSUInteger)count -{ - return _storage.count; -} - --(id)modelWithIndexValue:(id)indexValue -{ - if (self.count==0) return nil; - if (![_storage[0] indexPropertyName]) return nil; - - for (JSONModel* model in _storage) { - if ([[model valueForKey:model.indexPropertyName] isEqual:indexValue]) { - return model; - } - } - - return nil; -} - --(id)mutableCopy -{ - //it's already mutable - return self; -} - -#pragma mark - description --(NSString*)description -{ - NSMutableString* res = [NSMutableString stringWithFormat:@"\n", [_targetClass description]]; - for (id m in _storage) { - [res appendString: [m description]]; - [res appendString: @",\n"]; - } - [res appendFormat:@"\n"]; - return res; -} - --(NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state - objects:(id __unsafe_unretained [])stackbuf - count:(NSUInteger)stackbufLength -{ - NSUInteger count = 0; - - unsigned long countOfItemsAlreadyEnumerated = state->state; - - if (countOfItemsAlreadyEnumerated == 0) { - state->mutationsPtr = &state->extra[0]; - } - - if (countOfItemsAlreadyEnumerated < [self count]) { - state->itemsPtr = stackbuf; - while ((countOfItemsAlreadyEnumerated < [self count]) && (count < stackbufLength)) { - stackbuf[count] = [self objectAtIndex:countOfItemsAlreadyEnumerated]; - countOfItemsAlreadyEnumerated++; - count++; - } - } else { - count = 0; - } - - state->state = countOfItemsAlreadyEnumerated; - - return count; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.h deleted file mode 100644 index 7e47070..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// JSONModelClassProperty.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -enum kCustomizationTypes { - kNotInspected = 0, - kCustom, - kNo - }; - -typedef enum kCustomizationTypes PropertySetterType; -typedef enum kCustomizationTypes PropertyGetterType; - -/** - * **You do not need to instantiate this class yourself.** This class is used internally by JSONModel - * to inspect the declared properties of your model class. - * - * Class to contain the information, representing a class property - * It features the property's name, type, whether it's a required property, - * and (optionally) the class protocol - */ -@interface JSONModelClassProperty : NSObject - -/** The name of the declared property (not the ivar name) */ -@property (copy, nonatomic) NSString* name; - -/** A property class type */ -@property (assign, nonatomic) Class type; - -/** Struct name if a struct */ -@property (strong, nonatomic) NSString* structName; - -/** The name of the protocol the property conforms to (or nil) */ -@property (copy, nonatomic) NSString* protocol; - -/** If YES, it can be missing in the input data, and the input would be still valid */ -@property (assign, nonatomic) BOOL isOptional; - -/** If YES - don't call any transformers on this property's value */ -@property (assign, nonatomic) BOOL isStandardJSONType; - -/** If YES - create a mutable object for the value of the property */ -@property (assign, nonatomic) BOOL isMutable; - -/** If YES - create models on demand for the array members */ -@property (assign, nonatomic) BOOL convertsOnDemand; - -/** If YES - the value of this property determines equality to other models */ -@property (assign, nonatomic) BOOL isIndex; - -/** The status of property getter introspection in a model */ -@property (assign, nonatomic) PropertyGetterType getterType; - -/** a custom getter for this property, found in the owning model */ -@property (assign, nonatomic) SEL customGetter; - -/** The status of property setter introspection in a model */ -@property (assign, nonatomic) PropertySetterType setterType; - -/** a custom setter for this property, found in the owning model */ -@property (assign, nonatomic) SEL customSetter; - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.m deleted file mode 100644 index 0fe9158..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelClassProperty.m +++ /dev/null @@ -1,48 +0,0 @@ -// -// JSONModelClassProperty.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModelClassProperty.h" - -@implementation JSONModelClassProperty - --(NSString*)description -{ - //build the properties string for the current class property - NSMutableArray* properties = [NSMutableArray arrayWithCapacity:8]; - - if (self.isIndex) [properties addObject:@"Index"]; - if (self.isOptional) [properties addObject:@"Optional"]; - if (self.isMutable) [properties addObject:@"Mutable"]; - if (self.convertsOnDemand) [properties addObject:@"ConvertOnDemand"]; - if (self.isStandardJSONType) [properties addObject:@"Standard JSON type"]; - if (self.customSetter) [properties addObject:[NSString stringWithFormat: @"Setter = %@", NSStringFromSelector(self.customSetter)]]; - if (self.customGetter) [properties addObject:[NSString stringWithFormat: @"Getter = %@", NSStringFromSelector(self.customGetter)]]; - - NSString* propertiesString = @""; - if (properties.count>0) { - propertiesString = [NSString stringWithFormat:@"(%@)", [properties componentsJoinedByString:@", "]]; - } - - //return the name, type and additional properties - return [NSString stringWithFormat:@"@property %@%@ %@ %@", - self.type?[NSString stringWithFormat:@"%@*",self.type]:(self.structName?self.structName:@"primitive"), - self.protocol?[NSString stringWithFormat:@"<%@>", self.protocol]:@"", - self.name, - propertiesString - ]; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.h deleted file mode 100644 index 36f41ef..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.h +++ /dev/null @@ -1,112 +0,0 @@ -// -// JSONModelError.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -///////////////////////////////////////////////////////////////////////////////////////////// -typedef NS_ENUM(int, kJSONModelErrorTypes) -{ - kJSONModelErrorInvalidData = 1, - kJSONModelErrorBadResponse = 2, - kJSONModelErrorBadJSON = 3, - kJSONModelErrorModelIsInvalid = 4, - kJSONModelErrorNilInput = 5 -}; - -///////////////////////////////////////////////////////////////////////////////////////////// -/** The domain name used for the JSONModelError instances */ -extern NSString* const JSONModelErrorDomain; - -/** - * If the model JSON input misses keys that are required, check the - * userInfo dictionary of the JSONModelError instance you get back - - * under the kJSONModelMissingKeys key you will find a list of the - * names of the missing keys. - */ -extern NSString* const kJSONModelMissingKeys; - -/** - * If JSON input has a different type than expected by the model, check the - * userInfo dictionary of the JSONModelError instance you get back - - * under the kJSONModelTypeMismatch key you will find a description - * of the mismatched types. - */ -extern NSString* const kJSONModelTypeMismatch; - -/** - * If an error occurs in a nested model, check the userInfo dictionary of - * the JSONModelError instance you get back - under the kJSONModelKeyPath - * key you will find key-path at which the error occurred. - */ -extern NSString* const kJSONModelKeyPath; - -///////////////////////////////////////////////////////////////////////////////////////////// -/** - * Custom NSError subclass with shortcut methods for creating - * the common JSONModel errors - */ -@interface JSONModelError : NSError - -@property (strong, nonatomic) NSHTTPURLResponse* httpResponse; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 - */ -+(id)errorInvalidDataWithMessage:(NSString*)message; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 - * @param keys a set of field names that were required, but not found in the input - */ -+(id)errorInvalidDataWithMissingKeys:(NSSet*)keys; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 - * @param A description of the type mismatch that was encountered. - */ -+(id)errorInvalidDataWithTypeMismatch:(NSString*)mismatchDescription; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorBadResponse = 2 - */ -+(id)errorBadResponse; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorBadJSON = 3 - */ -+(id)errorBadJSON; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorModelIsInvalid = 4 - */ -+(id)errorModelIsInvalid; - -/** - * Creates a JSONModelError instance with code kJSONModelErrorNilInput = 5 - */ -+(id)errorInputIsNil; - -/** - * Creates a new JSONModelError with the same values plus information about the key-path of the error. - * Properties in the new error object are the same as those from the receiver, - * except that a new key kJSONModelKeyPath is added to the userInfo dictionary. - * This key contains the component string parameter. If the key is already present - * then the new error object has the component string prepended to the existing value. - */ -- (instancetype)errorByPrependingKeyPathComponent:(NSString*)component; - -///////////////////////////////////////////////////////////////////////////////////////////// -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.m deleted file mode 100644 index de80446..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModel/JSONModelError.m +++ /dev/null @@ -1,93 +0,0 @@ -// -// JSONModelError.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModelError.h" - -NSString* const JSONModelErrorDomain = @"JSONModelErrorDomain"; -NSString* const kJSONModelMissingKeys = @"kJSONModelMissingKeys"; -NSString* const kJSONModelTypeMismatch = @"kJSONModelTypeMismatch"; -NSString* const kJSONModelKeyPath = @"kJSONModelKeyPath"; - -@implementation JSONModelError - -+(id)errorInvalidDataWithMessage:(NSString*)message -{ - message = [NSString stringWithFormat:@"Invalid JSON data: %@", message]; - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorInvalidData - userInfo:@{NSLocalizedDescriptionKey:message}]; -} - -+(id)errorInvalidDataWithMissingKeys:(NSSet *)keys -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorInvalidData - userInfo:@{NSLocalizedDescriptionKey:@"Invalid JSON data. Required JSON keys are missing from the input. Check the error user information.",kJSONModelMissingKeys:[keys allObjects]}]; -} - -+(id)errorInvalidDataWithTypeMismatch:(NSString*)mismatchDescription -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorInvalidData - userInfo:@{NSLocalizedDescriptionKey:@"Invalid JSON data. The JSON type mismatches the expected type. Check the error user information.",kJSONModelTypeMismatch:mismatchDescription}]; -} - -+(id)errorBadResponse -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorBadResponse - userInfo:@{NSLocalizedDescriptionKey:@"Bad network response. Probably the JSON URL is unreachable."}]; -} - -+(id)errorBadJSON -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorBadJSON - userInfo:@{NSLocalizedDescriptionKey:@"Malformed JSON. Check the JSONModel data input."}]; -} - -+(id)errorModelIsInvalid -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorModelIsInvalid - userInfo:@{NSLocalizedDescriptionKey:@"Model does not validate. The custom validation for the input data failed."}]; -} - -+(id)errorInputIsNil -{ - return [JSONModelError errorWithDomain:JSONModelErrorDomain - code:kJSONModelErrorNilInput - userInfo:@{NSLocalizedDescriptionKey:@"Initializing model with nil input object."}]; -} - -- (instancetype)errorByPrependingKeyPathComponent:(NSString*)component -{ - // Create a mutable copy of the user info so that we can add to it and update it - NSMutableDictionary* userInfo = [self.userInfo mutableCopy]; - - // Create or update the key-path - NSString* existingPath = userInfo[kJSONModelKeyPath]; - NSString* separator = [existingPath hasPrefix:@"["] ? @"" : @"."; - NSString* updatedPath = (existingPath == nil) ? component : [component stringByAppendingFormat:@"%@%@", separator, existingPath]; - userInfo[kJSONModelKeyPath] = updatedPath; - - // Create the new error - return [JSONModelError errorWithDomain:self.domain - code:self.code - userInfo:[NSDictionary dictionaryWithDictionary:userInfo]]; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.h deleted file mode 100644 index d4e18da..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// NSArray+JSONModel.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - - -#import -#import "JSONModel.h" - -/** - * Exposes invisible JSONModelArray methods - */ -@interface NSArray(JSONModel) - -/** - * Looks up the array's contents and tries to find a JSONModel object - * with matching index property value to the indexValue param. - * - * Will return nil if no matching model is found. Will return nil if there's no index property - * defined on the models found in the array (will sample the first object, assuming the array - * contains homogenous collection of objects) - * - * @param indexValue the id value to search for - * @return the found model or nil - * @exception NSException throws exception if you call this method on an instance, which is not actually a JSONModelArray - */ -- (id)modelWithIndexValue:(id)indexValue; - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.m deleted file mode 100644 index 41475a4..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelCategories/NSArray+JSONModel.m +++ /dev/null @@ -1,28 +0,0 @@ -// -// NSArray+JSONModel.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - - -#import "NSArray+JSONModel.h" - -@implementation NSArray(JSONModel) - -- (id)modelWithIndexValue:(id)indexValue -{ - NSAssert(NO, @"call modelWithIndexValue: on a ConvertOnDemand property, which is defined like that: @property (strong, nonatomic) NSArray* list;"); - return nil; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelLib.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelLib.h deleted file mode 100644 index b8f5a17..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelLib.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// JSONModelLib.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -//JSONModel transformations -#import "JSONValueTransformer.h" -#import "JSONKeyMapper.h" - -//basic JSONModel classes -#import "JSONModelError.h" -#import "JSONModelClassProperty.h" -#import "JSONModel.h" - -//network classes -#import "JSONHTTPClient.h" -#import "JSONModel+networking.h" -#import "JSONAPI.h" - -//models array -#import "NSArray+JSONModel.h" -#import "JSONModelArray.h" \ No newline at end of file diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.h deleted file mode 100644 index dd27aa2..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.h +++ /dev/null @@ -1,90 +0,0 @@ -// -// JSONAPI.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import -#import "JSONHTTPClient.h" - -///////////////////////////////////////////////////////////////////////////////////////////// - -/** - * @discussion Class for working with JSON APIs. It builds upon the JSONHTTPClient class - * and facilitates making requests to the same web host. Also features helper - * method for making calls to a JSON RPC service - */ -@interface JSONAPI : NSObject - -///////////////////////////////////////////////////////////////////////////////////////////// - -/** @name Configuring the API */ -/** - * Sets the API url - * @param base the API url as a string - */ -+(void)setAPIBaseURLWithString:(NSString*)base; - -/** - * Sets the default content type for the requests/responses - * @param ctype The content-type as a string. Some possible types, - * depending on the service: application/json, text/json, x-application/javascript, etc. - */ -+(void)setContentType:(NSString*)ctype; - -///////////////////////////////////////////////////////////////////////////////////////////// - -/** @name Making GET API requests */ -/** - * Makes an asynchronious GET request to the API - * @param path the URL path to add to the base API URL for this HTTP call - * @param params the variables to pass to the API - * @param completeBlock a JSONObjectBlock block to execute upon completion - */ -+(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; - -///////////////////////////////////////////////////////////////////////////////////////////// - -/** @name Making POST API requests */ -/** - * Makes a POST request to the API - * @param path the URL path to add to the base API URL for this HTTP call - * @param params the variables to pass to the API - * @param completeBlock a JSONObjectBlock block to execute upon completion - */ -+(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; - -///////////////////////////////////////////////////////////////////////////////////////////// - -/** @name JSON RPC methods */ -/** - * Makes an asynchronious JSON RPC request to the API. Read more: http://www.jsonrpc.org - * @param method the HTTP method name; GET or POST only - * @param args the list of arguments to pass to the API - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)rpcWithMethodName:(NSString*)method andArguments:(NSArray*)args completion:(JSONObjectBlock)completeBlock; - -/** @name JSON RPC (2.0) request method */ -/** - * Makes an asynchronious JSON RPC 2.0 request to the API. Read more: http://www.jsonrpc.org - * @param method the HTTP method name; GET or POST only - * @param params the params to pass to the API - an NSArray or an NSDictionary, - * depending whether you're using named or unnamed parameters - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)rpc2WithMethodName:(NSString*)method andParams:(id)params completion:(JSONObjectBlock)completeBlock; - -///////////////////////////////////////////////////////////////////////////////////////////// - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.m deleted file mode 100644 index 212803d..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONAPI.m +++ /dev/null @@ -1,152 +0,0 @@ -// -// JSONAPI.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONAPI.h" - -#pragma mark - helper error model class -@interface JSONAPIRPCErrorModel: JSONModel -@property (assign, nonatomic) int code; -@property (strong, nonatomic) NSString* message; -@property (strong, nonatomic) id data; -@end - -#pragma mark - static variables - -static JSONAPI* sharedInstance = nil; -static long jsonRpcId = 0; - -#pragma mark - JSONAPI() private interface - -@interface JSONAPI () -@property (strong, nonatomic) NSString* baseURLString; -@end - -#pragma mark - JSONAPI implementation - -@implementation JSONAPI - -#pragma mark - initialize - -+(void)initialize -{ - static dispatch_once_t once; - dispatch_once(&once, ^{ - sharedInstance = [[JSONAPI alloc] init]; - }); -} - -#pragma mark - api config methods - -+(void)setAPIBaseURLWithString:(NSString*)base -{ - sharedInstance.baseURLString = base; -} - -+(void)setContentType:(NSString*)ctype -{ - [JSONHTTPClient setRequestContentType: ctype]; -} - -#pragma mark - GET methods -+(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock -{ - NSString* fullURL = [NSString stringWithFormat:@"%@%@", sharedInstance.baseURLString, path]; - - [JSONHTTPClient getJSONFromURLWithString: fullURL params:params completion:^(NSDictionary *json, JSONModelError *e) { - completeBlock(json, e); - }]; -} - -#pragma mark - POST methods -+(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock -{ - NSString* fullURL = [NSString stringWithFormat:@"%@%@", sharedInstance.baseURLString, path]; - - [JSONHTTPClient postJSONFromURLWithString: fullURL params:params completion:^(NSDictionary *json, JSONModelError *e) { - completeBlock(json, e); - }]; -} - -#pragma mark - RPC methods -+(void)__rpcRequestWithObject:(id)jsonObject completion:(JSONObjectBlock)completeBlock -{ - - NSData* jsonRequestData = [NSJSONSerialization dataWithJSONObject:jsonObject - options:kNilOptions - error:nil]; - NSString* jsonRequestString = [[NSString alloc] initWithData:jsonRequestData encoding: NSUTF8StringEncoding]; - - NSAssert(sharedInstance.baseURLString, @"API base URL not set"); - [JSONHTTPClient postJSONFromURLWithString: sharedInstance.baseURLString - bodyString: jsonRequestString - completion:^(NSDictionary *json, JSONModelError* e) { - - if (completeBlock) { - //handle the rpc response - NSDictionary* result = json[@"result"]; - - if (!result) { - JSONAPIRPCErrorModel* error = [[JSONAPIRPCErrorModel alloc] initWithDictionary:json[@"error"] error:nil]; - if (error) { - //custom server error - if (!error.message) error.message = @"Generic json rpc error"; - e = [JSONModelError errorWithDomain:JSONModelErrorDomain - code:error.code - userInfo: @{ NSLocalizedDescriptionKey : error.message}]; - } else { - //generic error - e = [JSONModelError errorBadResponse]; - } - } - - //invoke the callback - completeBlock(result, e); - } - }]; -} - -+(void)rpcWithMethodName:(NSString*)method andArguments:(NSArray*)args completion:(JSONObjectBlock)completeBlock -{ - NSAssert(method, @"No method specified"); - if (!args) args = @[]; - - [self __rpcRequestWithObject:@{ - //rpc 1.0 - @"id": @(++jsonRpcId), - @"params": args, - @"method": method - } completion:completeBlock]; -} - -+(void)rpc2WithMethodName:(NSString*)method andParams:(id)params completion:(JSONObjectBlock)completeBlock -{ - NSAssert(method, @"No method specified"); - if (!params) params = @[]; - - [self __rpcRequestWithObject:@{ - //rpc 2.0 - @"jsonrpc": @"2.0", - @"id": @(++jsonRpcId), - @"params": params, - @"method": method - } completion:completeBlock]; -} - -@end - -#pragma mark - helper rpc error model class implementation -@implementation JSONAPIRPCErrorModel -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.h deleted file mode 100644 index f946c78..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.h +++ /dev/null @@ -1,184 +0,0 @@ -// -// JSONModelHTTPClient.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModel.h" - -#pragma mark - definitions - -/** - * HTTP Request methods - */ -extern NSString* const kHTTPMethodGET; -extern NSString* const kHTTPMethodPOST; - -/** - * Content-type strings - */ -extern NSString* const kContentTypeAutomatic; -extern NSString* const kContentTypeJSON; -extern NSString* const kContentTypeWWWEncoded; - -/** - * A block type to handle incoming JSON object and an error. - * You pass it to methods which fetch JSON asynchroniously. When the operation is finished - * you receive back the fetched JSON (or nil) and an error (or nil) - * - * @param json object derived from a JSON string - * @param err JSONModelError or nil - */ -typedef void (^JSONObjectBlock)(id json, JSONModelError* err); - -///////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - configuration methods - -/** - * @discussion A very thin HTTP client that can do GET and POST HTTP requests. - * It fetches only JSON data and also deserializes it using NSJSONSerialization. - */ -@interface JSONHTTPClient : NSObject - -///////////////////////////////////////////////////////////////////////////////////////////// - - -/** @name HTTP Client configuration */ -/** - * Returns a modifyable dictionary of the client's default HTTP headers. - * @result A mutable dictionary of pairs - HTTP header names and values. - * @discussion You can use the result to modify the http client headers like so: - *
- * NSMutableDictionary* headers = [JSONHTTPClient requestHeaders];
- * headers[@"APIToken"] = @"MySecretTokenValue";
- * 
- */ -+(NSMutableDictionary*)requestHeaders; - -/** - * Sets the default encoding of the request body. - * See NSStringEncoding for a list of supported encodings - * @param encoding text encoding constant - */ -+(void)setDefaultTextEncoding:(NSStringEncoding)encoding; - -/** - * Sets the policies for caching HTTP data - * See NSURLRequestCachePolicy for a list of the pre-defined policies - * @param policy the caching policy - */ -+(void)setCachingPolicy:(NSURLRequestCachePolicy)policy; - -/** - * Sets the timeout for network calls - * @param seconds the amount of seconds to wait before considering the call failed - */ -+(void)setTimeoutInSeconds:(int)seconds; - -/** - * A method to enable/disable automatic network indicator showing. - * Set to YES by default. - * @param doesControlIndicator if YES, the library shows and hides the - * system network indicator automatically on begin and end of - * network operations - */ -+(void)setControlsNetworkIndicator:(BOOL)doesControlIndicator; - -/** - * A method to set the default conent type of the request body - * By default the content type is set to kContentTypeAutomatic - * which checks the body request and decides between "application/json" - * and "application/x-www-form-urlencoded" - */ -+(void)setRequestContentType:(NSString*)contentTypeString; - -///////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - GET asynchronious JSON calls - -/** @name Making asynchronious HTTP requests */ -/** - * Makes GET request to the given URL address and fetches a JSON response. - * @param urlString the URL as a string - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)getJSONFromURLWithString:(NSString*)urlString completion:(JSONObjectBlock)completeBlock; - -/** - * Makes GET request to the given URL address and fetches a JSON response. Sends the params as a query string variables. - * @param urlString the URL as a string - * @param params a dictionary of key / value pairs to be send as variables to the request - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)getJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; - -/** - * Makes a request to the given URL address and fetches a JSON response. - * @param urlString the URL as a string - * @param method the method of the request as a string - * @param params a dictionary of key / value pairs to be send as variables to the request - * @param bodyString the body of the POST request as a string - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary*)params orBodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock; - -/** - * Makes a request to the given URL address and fetches a JSON response. - * @param urlString the URL as a string - * @param method the method of the request as a string - * @param params a dictionary of key / value pairs to be send as variables to the request - * @param bodyString the body of the POST request as a string - * @param headers the headers to set on the request - overrides those in +requestHeaders - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary*)params orBodyString:(NSString*)bodyString headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock; - -/** - * Makes a request to the given URL address and fetches a JSON response. - * @param urlString the URL as a string - * @param method the method of the request as a string - * @param params a dictionary of key / value pairs to be send as variables to the request - * @param bodyData the body of the POST request as raw binary data - * @param headers the headers to set on the request - overrides those in +requestHeaders - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary *)params orBodyData:(NSData*)bodyData headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock; - -///////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - POST synchronious JSON calls - -/** - * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body. - * @param urlString the URL as a string - * @param params a dictionary of key / value pairs to be send as variables to the request - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)postJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; - -/** - * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body. - * @param urlString the URL as a string - * @param bodyString the body of the POST request as a string - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)postJSONFromURLWithString:(NSString*)urlString bodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock; - -/** - * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body. - * @param urlString the URL as a string - * @param bodyData the body of the POST request as an NSData object - * @param completeBlock JSONObjectBlock to execute upon completion - */ -+(void)postJSONFromURLWithString:(NSString*)urlString bodyData:(NSData*)bodyData completion:(JSONObjectBlock)completeBlock; - - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.m deleted file mode 100644 index b5e5d26..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONHTTPClient.m +++ /dev/null @@ -1,390 +0,0 @@ -// -// JSONModelHTTPClient.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONHTTPClient.h" - -#pragma mark - constants -NSString* const kHTTPMethodGET = @"GET"; -NSString* const kHTTPMethodPOST = @"POST"; - -NSString* const kContentTypeAutomatic = @"jsonmodel/automatic"; -NSString* const kContentTypeJSON = @"application/json"; -NSString* const kContentTypeWWWEncoded = @"application/x-www-form-urlencoded"; - -#pragma mark - static variables - -/** - * Defaults for HTTP requests - */ -static NSStringEncoding defaultTextEncoding = NSUTF8StringEncoding; -static NSURLRequestCachePolicy defaultCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; - -static int defaultTimeoutInSeconds = 60; - -/** - * Whether the iPhone net indicator automatically shows when making requests - */ -static BOOL doesControlIndicator = YES; - -/** - * Custom HTTP headers to send over with *each* request - */ -static NSMutableDictionary* requestHeaders = nil; - -/** - * Default request content type - */ -static NSString* requestContentType = nil; - -#pragma mark - implementation -@implementation JSONHTTPClient - -#pragma mark - initialization -+(void)initialize -{ - static dispatch_once_t once; - dispatch_once(&once, ^{ - requestHeaders = [NSMutableDictionary dictionary]; - requestContentType = kContentTypeAutomatic; - }); -} - -#pragma mark - configuration methods -+(NSMutableDictionary*)requestHeaders -{ - return requestHeaders; -} - -+(void)setDefaultTextEncoding:(NSStringEncoding)encoding -{ - defaultTextEncoding = encoding; -} - -+(void)setCachingPolicy:(NSURLRequestCachePolicy)policy -{ - defaultCachePolicy = policy; -} - -+(void)setTimeoutInSeconds:(int)seconds -{ - defaultTimeoutInSeconds = seconds; -} - -+(void)setControlsNetworkIndicator:(BOOL)does -{ - doesControlIndicator = does; -} - -+(void)setRequestContentType:(NSString*)contentTypeString -{ - requestContentType = contentTypeString; -} - -#pragma mark - helper methods -+(NSString*)contentTypeForRequestString:(NSString*)requestString -{ - //fetch the charset name from the default string encoding - NSString* contentType = requestContentType; - - if (requestString.length>0 && [contentType isEqualToString:kContentTypeAutomatic]) { - //check for "eventual" JSON array or dictionary - NSString* firstAndLastChar = [NSString stringWithFormat:@"%@%@", - [requestString substringToIndex:1], - [requestString substringFromIndex: requestString.length -1] - ]; - - if ([firstAndLastChar isEqualToString:@"{}"] || [firstAndLastChar isEqualToString:@"[]"]) { - //guessing for a JSON request - contentType = kContentTypeJSON; - } else { - //fallback to www form encoded params - contentType = kContentTypeWWWEncoded; - } - } - - //type is set, just add charset - NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); - return [NSString stringWithFormat:@"%@; charset=%@", contentType, charset]; -} - -+(NSString*)urlEncode:(id)value -{ - //make sure param is a string - if ([value isKindOfClass:[NSNumber class]]) { - value = [(NSNumber*)value stringValue]; - } - - NSAssert([value isKindOfClass:[NSString class]], @"request parameters can be only of NSString or NSNumber classes. '%@' is of class %@.", value, [value class]); - - return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( - NULL, - (__bridge CFStringRef) value, - NULL, - (CFStringRef)@"!*'();:@&=+$,/?%#[]", - kCFStringEncodingUTF8)); -} - -#pragma mark - networking worker methods -+(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method requestBody:(NSData*)bodyData headers:(NSDictionary*)headers etag:(NSString**)etag error:(JSONModelError**)err -{ - //turn on network indicator - if (doesControlIndicator) dispatch_async(dispatch_get_main_queue(), ^{[self setNetworkIndicatorVisible:YES];}); - - NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url - cachePolicy: defaultCachePolicy - timeoutInterval: defaultTimeoutInSeconds]; - [request setHTTPMethod:method]; - - if ([requestContentType isEqualToString:kContentTypeAutomatic]) { - //automatic content type - if (bodyData) { - NSString *bodyString = [[NSString alloc] initWithData:bodyData encoding:NSUTF8StringEncoding]; - [request setValue: [self contentTypeForRequestString: bodyString] forHTTPHeaderField:@"Content-type"]; - } - } else { - //user set content type - [request setValue: requestContentType forHTTPHeaderField:@"Content-type"]; - } - - //add all the custom headers defined - for (NSString* key in [requestHeaders allKeys]) { - [request setValue:requestHeaders[key] forHTTPHeaderField:key]; - } - - //add the custom headers - for (NSString* key in [headers allKeys]) { - [request setValue:headers[key] forHTTPHeaderField:key]; - } - - if (bodyData) { - [request setHTTPBody: bodyData]; - [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)bodyData.length] forHTTPHeaderField:@"Content-Length"]; - } - - //prepare output - NSHTTPURLResponse* response = nil; - - //fire the request - NSData *responseData = [NSURLConnection sendSynchronousRequest: request - returningResponse: &response - error: err]; - //convert an NSError to a JSONModelError - if (*err != nil) { - NSError* errObj = *err; - *err = [JSONModelError errorWithDomain:errObj.domain code:errObj.code userInfo:errObj.userInfo]; - } - - //turn off network indicator - if (doesControlIndicator) dispatch_async(dispatch_get_main_queue(), ^{[self setNetworkIndicatorVisible:NO];}); - - //if not OK status set the err to a JSONModelError instance - if (response.statusCode >= 300 || response.statusCode < 200) { - //create a new error - if (*err==nil) *err = [JSONModelError errorBadResponse]; - } - - //if there was an error, include the HTTP response and return - if (*err) { - //assign the response to the JSONModel instance - [*err setHttpResponse: [response copy]]; - - //empty respone, return nil instead - if ([responseData length]<1) { - return nil; - } - } - - //return the data fetched from web - return responseData; -} - -+(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method params:(NSDictionary*)params headers:(NSDictionary*)headers etag:(NSString**)etag error:(JSONModelError**)err -{ - //create the request body - NSMutableString* paramsString = nil; - - if (params) { - //build a simple url encoded param string - paramsString = [NSMutableString stringWithString:@""]; - for (NSString* key in [[params allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [paramsString appendFormat:@"%@=%@&", key, [self urlEncode:params[key]] ]; - } - if ([paramsString hasSuffix:@"&"]) { - paramsString = [[NSMutableString alloc] initWithString: [paramsString substringToIndex: paramsString.length-1]]; - } - } - - //set the request params - if ([method isEqualToString:kHTTPMethodGET] && params) { - - //add GET params to the query string - url = [NSURL URLWithString:[NSString stringWithFormat: @"%@%@%@", - [url absoluteString], - [url query] ? @"&" : @"?", - paramsString - ]]; - } - - //call the more general synq request method - return [self syncRequestDataFromURL: url - method: method - requestBody: [method isEqualToString:kHTTPMethodPOST]?[paramsString dataUsingEncoding:NSUTF8StringEncoding]:nil - headers: headers - etag: etag - error: err]; -} - -#pragma mark - Async network request -+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary*)params orBodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString - method:method - params:params - orBodyString:bodyString - headers:nil - completion:completeBlock]; -} - -+(void)JSONFromURLWithString:(NSString *)urlString method:(NSString *)method params:(NSDictionary *)params orBodyString:(NSString *)bodyString headers:(NSDictionary *)headers completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString - method:method - params:params - orBodyData:[bodyString dataUsingEncoding:NSUTF8StringEncoding] - headers:headers - completion:completeBlock]; -} - -+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary *)params orBodyData:(NSData*)bodyData headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock -{ - NSDictionary* customHeaders = headers; - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - - id jsonObject = nil; - JSONModelError* error = nil; - NSData* responseData = nil; - NSString* etag = nil; - - @try { - if (bodyData) { - responseData = [self syncRequestDataFromURL: [NSURL URLWithString:urlString] - method: method - requestBody: bodyData - headers: customHeaders - etag: &etag - error: &error]; - } else { - responseData = [self syncRequestDataFromURL: [NSURL URLWithString:urlString] - method: method - params: params - headers: customHeaders - etag: &etag - error: &error]; - } - } - @catch (NSException *exception) { - error = [JSONModelError errorBadResponse]; - } - - //step 3: if there's no response so far, return a basic error - if (!responseData && !jsonObject) { - //check for false response, but no network error - error = [JSONModelError errorBadResponse]; - } - - //step 4: if there's a response at this and no errors, convert to object - if (error==nil && jsonObject==nil) { - // Note: it is possible to have a valid response with empty response data (204 No Content). - // So only create the JSON object if there is some response data. - if(responseData.length > 0) - { - //convert to an object - jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; - } - } - //step 4.5: cover an edge case in which meaningful content is return along an error HTTP status code - else if (error && responseData && jsonObject==nil) { - //try to get the JSON object, while preserving the origianl error object - jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]; - } - - //step 5: invoke the complete block - dispatch_async(dispatch_get_main_queue(), ^{ - if (completeBlock) { - completeBlock(jsonObject, error); - } - }); - }); -} - -#pragma mark - request aliases -+(void)getJSONFromURLWithString:(NSString*)urlString completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString method:kHTTPMethodGET - params:nil - orBodyString:nil completion:^(id json, JSONModelError* e) { - if (completeBlock) completeBlock(json, e); - }]; -} - -+(void)getJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString method:kHTTPMethodGET - params:params - orBodyString:nil completion:^(id json, JSONModelError* e) { - if (completeBlock) completeBlock(json, e); - }]; -} - -+(void)postJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString method:kHTTPMethodPOST - params:params - orBodyString:nil completion:^(id json, JSONModelError* e) { - if (completeBlock) completeBlock(json, e); - }]; - -} - -+(void)postJSONFromURLWithString:(NSString*)urlString bodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString method:kHTTPMethodPOST - params:nil - orBodyString:bodyString completion:^(id json, JSONModelError* e) { - if (completeBlock) completeBlock(json, e); - }]; -} - -+(void)postJSONFromURLWithString:(NSString*)urlString bodyData:(NSData*)bodyData completion:(JSONObjectBlock)completeBlock -{ - [self JSONFromURLWithString:urlString method:kHTTPMethodPOST - params:nil - orBodyString:[[NSString alloc] initWithData:bodyData encoding:defaultTextEncoding] - completion:^(id json, JSONModelError* e) { - if (completeBlock) completeBlock(json, e); - }]; -} - -#pragma mark - iOS UI helper -+(void)setNetworkIndicatorVisible:(BOOL)isVisible -{ -#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:isVisible]; -#endif -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.h deleted file mode 100644 index 88e329e..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// JSONModel+networking.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModel.h" -#import "JSONHTTPClient.h" - -typedef void (^JSONModelBlock)(id model, JSONModelError* err); - -/** - * The JSONModel(networking) class category adds networking to JSONModel. - * It adds initFromURLWithString: initializer, which makes a GET http request - * to the URL given and initializes the model with the returned JSON. - * Use #import "JSONModel+networking.h" to import networking capabilities. - */ -@interface JSONModel(Networking) - -@property (assign, nonatomic) BOOL isLoading; -/** @name Asynchroniously create a model over the network */ -/** - * Asynchroniously create a model over the network. Create a new model instance and initialize it with the JSON fetched from the given URL - * @param urlString the absolute URL address of the JSON feed as a string - * @param completeBlock JSONModelBlock executed upon completion. The JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* e); the first parameter is the initialized model or nil, - * and second parameter holds the model initialization error, if any - */ --(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock; - -/** - * Asynchronously gets the contents of a URL and constructs a JSONModel object from the response. - * The constructed JSONModel object passed as the first parameter to the completion block will be of the same - * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel. - * @param urlString The absolute URL of the JSON resource, as a string - * @param completeBlock The block to be called upon completion. - * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err); - * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error; - * The second parameter is the initialization error, if any. - */ -+ (void)getModelFromURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock; - -/** - * Asynchronously posts a JSONModel object (as JSON) to a URL and constructs a JSONModel object from the response. - * The constructed JSONModel object passed as the first parameter to the completion block will be of the same - * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel. - * @param post A JSONModel object that will be converted to JSON and sent as the POST data to the HTTP request. - * @param urlString The absolute URL of the JSON resource, as a string - * @param completeBlock The block to be called upon completion. - * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err); - * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error; - * The second parameter is the initialization error, if any. - */ -+ (void)postModel:(JSONModel*)post toURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock; - - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.m deleted file mode 100644 index 7d4d1ff..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelNetworking/JSONModel+networking.m +++ /dev/null @@ -1,109 +0,0 @@ -// -// JSONModel+networking.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONModel+networking.h" -#import "JSONHTTPClient.h" - -BOOL _isLoading; - -@implementation JSONModel(Networking) - -@dynamic isLoading; - --(BOOL)isLoading -{ - return _isLoading; -} - --(void)setIsLoading:(BOOL)isLoading -{ - _isLoading = isLoading; -} - --(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock -{ - id placeholder = [super init]; - __block id blockSelf = self; - - if (placeholder) { - //initialization - self.isLoading = YES; - - [JSONHTTPClient getJSONFromURLWithString:urlString - completion:^(NSDictionary *json, JSONModelError* e) { - - JSONModelError* initError = nil; - blockSelf = [self initWithDictionary:json error:&initError]; - - if (completeBlock) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ - completeBlock(blockSelf, e?e:initError ); - }); - } - - self.isLoading = NO; - - }]; - } - return placeholder; -} - -+ (void)getModelFromURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock -{ - [JSONHTTPClient getJSONFromURLWithString:urlString - completion:^(NSDictionary* jsonDict, JSONModelError* err) - { - JSONModel* model = nil; - - if(err == nil) - { - model = [[self alloc] initWithDictionary:jsonDict error:&err]; - } - - if(completeBlock != nil) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - completeBlock(model, err); - }); - } - }]; -} - -+ (void)postModel:(JSONModel*)post toURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock -{ - [JSONHTTPClient postJSONFromURLWithString:urlString - bodyString:[post toJSONString] - completion:^(NSDictionary* jsonDict, JSONModelError* err) - { - JSONModel* model = nil; - - if(err == nil) - { - model = [[self alloc] initWithDictionary:jsonDict error:&err]; - } - - if(completeBlock != nil) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - completeBlock(model, err); - }); - } - }]; -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.h deleted file mode 100644 index 75822c6..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// JSONKeyMapper.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import - -typedef NSString* (^JSONModelKeyMapBlock)(NSString* keyName); - -/** - * **You won't need to create or store instances of this class yourself.** If you want your model - * to have different property names than the JSON feed keys, look below on how to - * make your model use a key mapper. - * - * For example if you consume JSON from twitter - * you get back underscore_case style key names. For example: - * - *
"profile_sidebar_border_color": "0094C2",
- * "profile_background_tile": false,
- * - * To comply with Obj-C accepted camelCase property naming for your classes, - * you need to provide mapping between JSON keys and ObjC property names. - * - * In your model overwrite the +(JSONKeyMapper*)keyMapper method and provide a JSONKeyMapper - * instance to convert the key names for your model. - * - * If you need custom mapping it's as easy as: - *
- * +(JSONKeyMapper*)keyMapper {
- *   return [[JSONKeyMapper alloc] initWithDictionary:@{@"crazy_JSON_name":@"myCamelCaseName"}];
- * }
- * 
- * In case you want to handle underscore_case, **use the predefined key mapper**, like so: - *
- * +(JSONKeyMapper*)keyMapper {
- *   return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
- * }
- * 
- */ -@interface JSONKeyMapper : NSObject - -/** @name Name convertors */ -/** Block, which takes in a JSON key and converts it to the corresponding property name */ -@property (readonly, nonatomic) JSONModelKeyMapBlock JSONToModelKeyBlock; - -/** Block, which takes in a property name and converts it to the corresponding JSON key name */ -@property (readonly, nonatomic) JSONModelKeyMapBlock modelToJSONKeyBlock; - -/** Combined convertor method -* @param value the source name -* @param importing YES invokes JSONToModelKeyBlock, NO - modelToJSONKeyBlock -* @return JSONKeyMapper instance -*/ --(NSString*)convertValue:(NSString*)value isImportingToModel:(BOOL)importing; - -/** @name Creating a key mapper */ - -/** - * Creates a JSONKeyMapper instance, based on the two blocks you provide this initializer. - * The two parameters take in a JSONModelKeyMapBlock block: - *
NSString* (^JSONModelKeyMapBlock)(NSString* keyName)
- * The block takes in a string and returns the transformed (if at all) string. - * @param toModel transforms JSON key name to your model property name - * @param toJSON transforms your model property name to a JSON key - */ --(instancetype)initWithJSONToModelBlock:(JSONModelKeyMapBlock)toModel - modelToJSONBlock:(JSONModelKeyMapBlock)toJSON; - -/** - * Creates a JSONKeyMapper instance, based on the mapping you provide - * in the map parameter. Use the JSON key names as keys, your JSONModel - * property names as values. - * @param map map dictionary, in the format:
@{@"crazy_JSON_name":@"myCamelCaseName"}
- * @return JSONKeyMapper instance - */ --(instancetype)initWithDictionary:(NSDictionary*)map; - -/** - * Creates a JSONKeyMapper, which converts underscore_case to camelCase and vice versa. - */ -+(instancetype)mapperFromUnderscoreCaseToCamelCase; - -+(instancetype)mapperFromUpperCaseToLowerCase; -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.m deleted file mode 100644 index c3007da..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONKeyMapper.m +++ /dev/null @@ -1,174 +0,0 @@ -// -// JSONKeyMapper.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONKeyMapper.h" - -@interface JSONKeyMapper() -@property (nonatomic, strong) NSMutableDictionary *toModelMap; -@property (nonatomic, strong) NSMutableDictionary *toJSONMap; -@end - -@implementation JSONKeyMapper - --(instancetype)init -{ - self = [super init]; - if (self) { - //initialization - self.toModelMap = [NSMutableDictionary dictionary]; - self.toJSONMap = [NSMutableDictionary dictionary]; - } - return self; -} - --(instancetype)initWithJSONToModelBlock:(JSONModelKeyMapBlock)toModel - modelToJSONBlock:(JSONModelKeyMapBlock)toJSON -{ - self = [self init]; - - if (self) { - __weak JSONKeyMapper *myself = self; - //the json to model convertion block - _JSONToModelKeyBlock = ^NSString*(NSString* keyName) { - - //try to return cached transformed key - if (myself.toModelMap[keyName]) return myself.toModelMap[keyName]; - - //try to convert the key, and store in the cache - NSString* result = toModel(keyName); - myself.toModelMap[keyName] = result; - return result; - }; - - _modelToJSONKeyBlock = ^NSString*(NSString* keyName) { - - //try to return cached transformed key - if (myself.toJSONMap[keyName]) return myself.toJSONMap[keyName]; - - //try to convert the key, and store in the cache - NSString* result = toJSON(keyName); - myself.toJSONMap[keyName] = result; - return result; - - }; - - } - - return self; -} - --(instancetype)initWithDictionary:(NSDictionary*)map -{ - self = [super init]; - if (self) { - //initialize - - NSMutableDictionary* userToModelMap = [NSMutableDictionary dictionaryWithDictionary: map]; - NSMutableDictionary* userToJSONMap = [NSMutableDictionary dictionaryWithObjects:map.allKeys forKeys:map.allValues]; - - _JSONToModelKeyBlock = ^NSString*(NSString* keyName) { - NSString* result = [userToModelMap valueForKeyPath: keyName]; - return result?result:keyName; - }; - - _modelToJSONKeyBlock = ^NSString*(NSString* keyName) { - NSString* result = [userToJSONMap valueForKeyPath: keyName]; - return result?result:keyName; - }; - } - - return self; -} - --(NSString*)convertValue:(NSString*)value isImportingToModel:(BOOL)importing -{ - return !importing?_JSONToModelKeyBlock(value):_modelToJSONKeyBlock(value); -} - -+(instancetype)mapperFromUnderscoreCaseToCamelCase -{ - JSONModelKeyMapBlock toModel = ^ NSString* (NSString* keyName) { - - //bail early if no transformation required - if ([keyName rangeOfString:@"_"].location==NSNotFound) return keyName; - - //derive camel case out of underscore case - NSString* camelCase = [keyName capitalizedString]; - camelCase = [camelCase stringByReplacingOccurrencesOfString:@"_" withString:@""]; - camelCase = [camelCase stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[camelCase substringToIndex:1] lowercaseString] ]; - - return camelCase; - }; - - JSONModelKeyMapBlock toJSON = ^ NSString* (NSString* keyName) { - - NSMutableString* result = [NSMutableString stringWithString:keyName]; - NSRange upperCharRange = [result rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]; - - //handle upper case chars - while ( upperCharRange.location!=NSNotFound) { - - NSString* lowerChar = [[result substringWithRange:upperCharRange] lowercaseString]; - [result replaceCharactersInRange:upperCharRange - withString:[NSString stringWithFormat:@"_%@", lowerChar]]; - upperCharRange = [result rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]; - } - - //handle numbers - NSRange digitsRange = [result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]]; - while ( digitsRange.location!=NSNotFound) { - - NSRange digitsRangeEnd = [result rangeOfString:@"\\D" options:NSRegularExpressionSearch range:NSMakeRange(digitsRange.location, result.length-digitsRange.location)]; - if (digitsRangeEnd.location == NSNotFound) { - //spands till the end of the key name - digitsRangeEnd = NSMakeRange(result.length, 1); - } - - NSRange replaceRange = NSMakeRange(digitsRange.location, digitsRangeEnd.location - digitsRange.location); - NSString* digits = [result substringWithRange:replaceRange]; - - [result replaceCharactersInRange:replaceRange withString:[NSString stringWithFormat:@"_%@", digits]]; - digitsRange = [result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet] options:kNilOptions range:NSMakeRange(digitsRangeEnd.location+1, result.length-digitsRangeEnd.location-1)]; - } - - return result; - }; - - return [[self alloc] initWithJSONToModelBlock:toModel - modelToJSONBlock:toJSON]; - -} - -+(instancetype)mapperFromUpperCaseToLowerCase -{ - JSONModelKeyMapBlock toModel = ^ NSString* (NSString* keyName) { - NSString*lowercaseString = [keyName lowercaseString]; - return lowercaseString; - }; - - JSONModelKeyMapBlock toJSON = ^ NSString* (NSString* keyName) { - - NSString *uppercaseString = [keyName uppercaseString]; - - return uppercaseString; - }; - - return [[self alloc] initWithJSONToModelBlock:toModel - modelToJSONBlock:toJSON]; - -} - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.h deleted file mode 100644 index 8c40ce8..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.h +++ /dev/null @@ -1,230 +0,0 @@ -// -// JSONValueTransformer.h -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import -#import "JSONModelArray.h" - -///////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - extern definitons -/** - * Boolean function to check for null values. Handy when you need to both check - * for nil and [NSNUll null] - */ -extern BOOL isNull(id value); - -///////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - JSONValueTransformer interface -/** - * **You don't need to call methods of this class manually.** - * - * Class providing methods to transform values from one class to another. - * You are given a number of built-in transformers, but you are encouraged to - * extend this class with your own categories to add further value transformers. - * Just few examples of what can you add to JSONValueTransformer: hex colors in JSON to UIColor, - * hex numbers in JSON to NSNumber model properties, base64 encoded strings in JSON to UIImage properties, and more. - * - * The class is invoked by JSONModel while transforming incoming - * JSON types into your target class property classes, and vice versa. - * One static copy is create and store in the JSONModel class scope. - */ -@interface JSONValueTransformer : NSObject - -@property (strong, nonatomic, readonly) NSDictionary* primitivesNames; - -/** @name Resolving cluster class names */ -/** - * This method returns the ubmrella class for any standard class cluster members. - * For example returns NSString when given as input NSString, NSMutableString, __CFString and __CFConstantString - * The method currently looksup a pre-defined list. - * @param sourceClass the class to get the umrella class for - * @return Class - */ -+(Class)classByResolvingClusterClasses:(Class)sourceClass; - -#pragma mark - NSMutableString <-> NSString -/** @name Transforming to Mutable copies */ -/** - * Trasnforms a string value to a mutable string value - * @param string incoming string - * @return mutable string - */ --(NSMutableString*)NSMutableStringFromNSString:(NSString*)string; - -#pragma mark - NSMutableArray <-> NSArray -/** - * Trasnforms an array to a mutable array - * @param array incoming array - * @return mutable array - */ --(NSMutableArray*)NSMutableArrayFromNSArray:(NSArray*)array; - -#pragma mark - NS(Mutable)Array <- JSONModelArray -/** - * Trasnforms an array to a JSONModelArray - * @param array incoming array - * @return JSONModelArray - */ --(NSArray*)NSArrayFromJSONModelArray:(JSONModelArray*)array; --(NSMutableArray*)NSMutableArrayFromJSONModelArray:(JSONModelArray*)array; - -#pragma mark - NSMutableDictionary <-> NSDictionary -/** - * Trasnforms a dictionary to a mutable dictionary - * @param dict incoming dictionary - * @return mutable dictionary - */ --(NSMutableDictionary*)NSMutableDictionaryFromNSDictionary:(NSDictionary*)dict; - -#pragma mark - NSSet <-> NSArray -/** @name Transforming Sets */ -/** - * Transforms an array to a set - * @param array incoming array - * @return set with the array's elements - */ --(NSSet*)NSSetFromNSArray:(NSArray*)array; - -/** - * Transforms an array to a mutable set - * @param array incoming array - * @return mutable set with the array's elements - */ --(NSMutableSet*)NSMutableSetFromNSArray:(NSArray*)array; - -/** - * Transforms a set to an array - * @param set incoming set - * @return an array with the set's elements - */ --(NSArray*)JSONObjectFromNSSet:(NSSet*)set; - -/** - * Transforms a mutable set to an array - * @param set incoming mutable set - * @return an array with the set's elements - */ --(NSArray*)JSONObjectFromNSMutableSet:(NSMutableSet*)set; - -#pragma mark - BOOL <-> number/string -/** @name Transforming JSON types */ -/** - * Transforms a number object to a bool number object - * @param number the number to convert - * @return the resulting number - */ --(NSNumber*)BOOLFromNSNumber:(NSNumber*)number; - -/** - * Transforms a number object to a bool number object - * @param string the string value to convert, "0" converts to NO, everything else to YES - * @return the resulting number - */ --(NSNumber*)BOOLFromNSString:(NSString*)string; - -/** - * Transforms a BOOL value to a bool number object - * @param number an NSNumber value coming from the model - * @return the result number - */ --(NSNumber*)JSONObjectFromBOOL:(NSNumber*)number; - -#pragma mark - string <-> number -/** - * Transforms a string object to a number object - * @param string the string to convert - * @return the resulting number - */ --(NSNumber*)NSNumberFromNSString:(NSString*)string; - -/** - * Transforms a number object to a string object - * @param number the number to convert - * @return the resulting string - */ --(NSString*)NSStringFromNSNumber:(NSNumber*)number; - -/** - * Transforms a string object to a nsdecimalnumber object - * @param string the string to convert - * @return the resulting number - */ --(NSDecimalNumber*)NSDecimalNumberFromNSString:(NSString*)string; - -/** - * Transforms a nsdecimalnumber object to a string object - * @param number the number to convert - * @return the resulting string - */ --(NSString*)NSStringFromNSDecimalNumber:(NSDecimalNumber*)number; - - -#pragma mark - string <-> url -/** @name Transforming URLs */ -/** - * Transforms a string object to an NSURL object - * @param string the string to convert - * @return the resulting url object - */ --(NSURL*)NSURLFromNSString:(NSString*)string; - -/** - * Transforms an NSURL object to a string - * @param url the url object to convert - * @return the resulting string - */ --(NSString*)JSONObjectFromNSURL:(NSURL*)url; - -#pragma mark - string <-> time zone - -/** @name Transforming NSTimeZone */ -/** - * Transforms a string object to an NSTimeZone object - * @param string the string to convert - * @return the resulting NSTimeZone object - */ -- (NSTimeZone *)NSTimeZoneFromNSString:(NSString*)string; - -/** - * Transforms an NSTimeZone object to a string - * @param timeZone the time zone object to convert - * @return the resulting string - */ -- (NSString *)JSONObjectFromNSTimeZone:(NSTimeZone *)timeZone; - -#pragma mark - string <-> date -/** @name Transforming Dates */ -/** - * The following two methods are not public. This way if there is a category on converting - * dates it'll override them. If there isn't a category the default methods found in the .m - * file will be invoked. If these are public a warning is produced at the point of overriding - * them in a category, so they have to stay hidden here. - */ - -//-(NSDate*)NSDateFromNSString:(NSString*)string; -//-(NSString*)JSONObjectFromNSDate:(NSDate*)date; - -#pragma mark - number <-> date - -/** - * Transforms a number to an NSDate object - * @param number the number to convert - * @return the resulting date - */ -- (NSDate*)NSDateFromNSNumber:(NSNumber*)number; - -@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.m deleted file mode 100644 index 2a37f8d..0000000 --- a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSONModel/JSONModelTransformations/JSONValueTransformer.m +++ /dev/null @@ -1,270 +0,0 @@ -// -// JSONValueTransformer.m -// -// @version 1.0.2 -// @author Marin Todorov, http://www.touch-code-magazine.com -// - -// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd. -// This code is distributed under the terms and conditions of the MIT license. -// -// 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. -// -// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense - -#import "JSONValueTransformer.h" -#import "JSONModelArray.h" - -#pragma mark - functions -extern BOOL isNull(id value) -{ - if (!value) return YES; - if ([value isKindOfClass:[NSNull class]]) return YES; - - return NO; -} - -static NSDateFormatter *_dateFormatter; - -@implementation JSONValueTransformer - --(id)init -{ - self = [super init]; - if (self) { - _primitivesNames = @{@"f":@"float", @"i":@"int", @"d":@"double", @"l":@"long", @"c":@"BOOL", @"s":@"short", @"q":@"long", - //and some famos aliases of primitive types - // BOOL is now "B" on iOS __LP64 builds - @"I":@"NSInteger", @"Q":@"NSUInteger", @"B":@"BOOL", - - @"@?":@"Block"}; - } - return self; -} - -+(Class)classByResolvingClusterClasses:(Class)sourceClass -{ - //check for all variations of strings - if ([sourceClass isSubclassOfClass:[NSString class]]) { - return [NSString class]; - } - - //check for all variations of numbers - if ([sourceClass isSubclassOfClass:[NSNumber class]]) { - return [NSNumber class]; - } - - //check for all variations of dictionaries - if ([sourceClass isSubclassOfClass:[NSArray class]]) { - return [NSArray class]; - } - - //check for all variations of arrays - if ([sourceClass isSubclassOfClass:[NSDictionary class]]) { - return [NSDictionary class]; - } - - //check for all variations of dates - if ([sourceClass isSubclassOfClass:[NSDate class]]) { - return [NSDate class]; - } - - //no cluster parent class found - return sourceClass; -} - -#pragma mark - NSMutableString <-> NSString --(NSMutableString*)NSMutableStringFromNSString:(NSString*)string -{ - return [NSMutableString stringWithString:string]; -} - -#pragma mark - NSMutableArray <-> NSArray --(NSMutableArray*)NSMutableArrayFromNSArray:(NSArray*)array -{ - if ([array isKindOfClass:[JSONModelArray class]]) { - //it's a jsonmodelarray already, just return it - return (id)array; - } - - return [NSMutableArray arrayWithArray:array]; -} - -#pragma mark - NS(Mutable)Array <- JSONModelArray --(NSArray*)NSArrayFromJSONModelArray:(JSONModelArray*)array -{ - return (NSMutableArray*)array; -} - --(NSMutableArray*)NSMutableArrayFromJSONModelArray:(JSONModelArray*)array -{ - return (NSMutableArray*)array; -} - - -#pragma mark - NSMutableDictionary <-> NSDictionary --(NSMutableDictionary*)NSMutableDictionaryFromNSDictionary:(NSDictionary*)dict -{ - return [NSMutableDictionary dictionaryWithDictionary:dict]; -} - -#pragma mark - NSSet <-> NSArray --(NSSet*)NSSetFromNSArray:(NSArray*)array -{ - return [NSSet setWithArray:array]; -} - --(NSMutableSet*)NSMutableSetFromNSArray:(NSArray*)array -{ - return [NSMutableSet setWithArray:array]; -} - --(id)JSONObjectFromNSSet:(NSSet*)set -{ - return [set allObjects]; -} - --(id)JSONObjectFromNSMutableSet:(NSMutableSet*)set -{ - return [set allObjects]; -} - -// -// 0 converts to NO, everything else converts to YES -// - -#pragma mark - BOOL <-> number/string --(NSNumber*)BOOLFromNSNumber:(NSNumber*)number -{ - if (isNull(number)) return [NSNumber numberWithBool:NO]; - return [NSNumber numberWithBool: number.intValue==0?NO:YES]; -} - --(NSNumber*)BOOLFromNSString:(NSString*)string -{ - if (string != nil && - ([string caseInsensitiveCompare:@"true"] == NSOrderedSame || - [string caseInsensitiveCompare:@"yes"] == NSOrderedSame)) { - return [NSNumber numberWithBool:YES]; - } - return [NSNumber numberWithBool: ([string intValue]==0)?NO:YES]; -} - --(NSNumber*)JSONObjectFromBOOL:(NSNumber*)number -{ - return [NSNumber numberWithBool: number.intValue==0?NO:YES]; -} - -#pragma mark - string/number <-> float --(float)floatFromObject:(id)obj -{ - return [obj floatValue]; -} - --(float)floatFromNSString:(NSString*)string -{ - return [self floatFromObject:string]; -} - --(float)floatFromNSNumber:(NSNumber*)number -{ - return [self floatFromObject:number]; -} - --(NSNumber*)NSNumberFromfloat:(float)f -{ - return [NSNumber numberWithFloat:f]; -} - -#pragma mark - string <-> number --(NSNumber*)NSNumberFromNSString:(NSString*)string -{ - return [NSNumber numberWithFloat: [string doubleValue]]; -} - --(NSString*)NSStringFromNSNumber:(NSNumber*)number -{ - return [number stringValue]; -} - --(NSDecimalNumber*)NSDecimalNumberFromNSString:(NSString*)string -{ - return [NSDecimalNumber decimalNumberWithString:string]; -} - --(NSString*)NSStringFromNSDecimalNumber:(NSDecimalNumber*)number -{ - return [number stringValue]; -} - -#pragma mark - string <-> url --(NSURL*)NSURLFromNSString:(NSString*)string -{ - return [NSURL URLWithString:string]; -} - --(NSString*)JSONObjectFromNSURL:(NSURL*)url -{ - return [url absoluteString]; -} - -#pragma mark - string <-> date --(NSDateFormatter*)importDateFormatter -{ - static dispatch_once_t once; - static NSDateFormatter* dateFormatter; - dispatch_once(&once, ^{ - dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HHmmssZZZ"]; - }); - return dateFormatter; -} - --(NSDate*)__NSDateFromNSString:(NSString*)string -{ - string = [string stringByReplacingOccurrencesOfString:@":" withString:@""]; // this is such an ugly code, is this the only way? - return [self.importDateFormatter dateFromString: string]; -} - --(NSString*)__JSONObjectFromNSDate:(NSDate*)date -{ - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"]; - return [dateFormatter stringFromDate:date]; -} - -#pragma mark - number <-> date -- (NSDate*)NSDateFromNSNumber:(NSNumber*)number -{ - return [NSDate dateWithTimeIntervalSince1970:number.doubleValue]; -} - -#pragma mark - string <-> NSTimeZone - -- (NSTimeZone *)NSTimeZoneFromNSString:(NSString *)string { - return [NSTimeZone timeZoneWithName:string]; -} - -- (id)JSONObjectFromNSTimeZone:(NSTimeZone *)timeZone { - return [timeZone name]; -} - -#pragma mark - hidden transform for empty dictionaries -//https://github.com/icanzilb/JSONModel/issues/163 --(NSDictionary*)__NSDictionaryFromNSArray:(NSArray*)array -{ - if (array.count==0) return @{}; - return (id)array; -} - --(NSMutableDictionary*)__NSMutableDictionaryFromNSArray:(NSArray*)array -{ - if (array.count==0) return [[self __NSDictionaryFromNSArray:array] mutableCopy]; - return (id)array; -} - -@end diff --git a/Pods/JSPatch/JSPatch/JPEngine.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JPEngine.h old mode 100644 new mode 100755 similarity index 100% rename from Pods/JSPatch/JSPatch/JPEngine.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JPEngine.h diff --git a/Pods/JSPatch/JSPatch/JPEngine.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JPEngine.m old mode 100644 new mode 100755 similarity index 96% rename from Pods/JSPatch/JSPatch/JPEngine.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JPEngine.m index fc2570e..bc0a8ee --- a/Pods/JSPatch/JSPatch/JPEngine.m +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JPEngine.m @@ -122,7 +122,7 @@ + (void)jp_fixMethodSignature static NSObject *_nullObj; static NSObject *_nilObj; static NSMutableDictionary *_registeredStruct; -static NSString *_currInvokeSuperClsName; +static NSMutableDictionary *_currInvokeSuperClsName; static char *kPropAssociatedObjectKey; static BOOL _autoConvert; static BOOL _convertOCNumberToString; @@ -138,7 +138,7 @@ + (void)jp_fixMethodSignature static NSMutableDictionary *_protocolTypeEncodeDict; static NSMutableArray *_pointersToRelease; -void (^_exceptionBlock)(NSString *log) = ^void(NSString *log) { +static void (^_exceptionBlock)(NSString *log) = ^void(NSString *log) { NSCAssert(NO, log); }; @@ -288,6 +288,7 @@ + (void)startEngine _JSMethodSignatureLock = [[NSLock alloc] init]; _JSMethodForwardCallLock = [[NSRecursiveLock alloc] init]; _registeredStruct = [[NSMutableDictionary alloc] init]; + _currInvokeSuperClsName = [[NSMutableDictionary alloc] init]; #if TARGET_OS_IPHONE [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; @@ -332,7 +333,7 @@ + (JSValue *)_evaluateScript:(NSString *)script withSourceURL:(NSURL *)resourceU if (!_regex) { _regex = [NSRegularExpression regularExpressionWithPattern:_regexStr options:0 error:nil]; } - NSString *formatedScript = [NSString stringWithFormat:@";(function(){try{%@}catch(e){_OC_catch(e.message, e.stack)}})();", [_regex stringByReplacingMatchesInString:script options:0 range:NSMakeRange(0, script.length) withTemplate:_replaceStr]]; + NSString *formatedScript = [NSString stringWithFormat:@";(function(){try{\n%@\n}catch(e){_OC_catch(e.message, e.stack)}})();", [_regex stringByReplacingMatchesInString:script options:0 range:NSMakeRange(0, script.length) withTemplate:_replaceStr]]; @try { if ([_context respondsToSelector:@selector(evaluateScript:withSourceURL:)]) { return [_context evaluateScript:formatedScript withSourceURL:resourceURL]; @@ -612,8 +613,8 @@ static void addMethodToProtocol(Protocol* protocol, NSString *selectorName, NSSt static JSValue *getJSFunctionInObjectHierachy(id slf, NSString *selectorName) { Class cls = object_getClass(slf); - if (_currInvokeSuperClsName) { - cls = NSClassFromString(_currInvokeSuperClsName); + if (_currInvokeSuperClsName[selectorName]) { + cls = NSClassFromString(_currInvokeSuperClsName[selectorName]); selectorName = [selectorName stringByReplacingOccurrencesOfString:@"_JPSUPER_" withString:@"_JP"]; } JSValue *func = _JSOverideMethods[cls][selectorName]; @@ -746,13 +747,13 @@ static void JPForwardInvocation(__unsafe_unretained id assignSlf, SEL selector, } } - if (_currInvokeSuperClsName) { - Class cls = NSClassFromString(_currInvokeSuperClsName); + if (_currInvokeSuperClsName[selectorName]) { + Class cls = NSClassFromString(_currInvokeSuperClsName[selectorName]); NSString *tmpSelectorName = [[selectorName stringByReplacingOccurrencesOfString:@"_JPSUPER_" withString:@"_JP"] stringByReplacingOccurrencesOfString:@"SUPER_" withString:@"_JP"]; if (!_JSOverideMethods[cls][tmpSelectorName]) { NSString *ORIGSelectorName = [selectorName stringByReplacingOccurrencesOfString:@"SUPER_" withString:@"ORIG"]; [argList removeObjectAtIndex:0]; - id retObj = callSelector(_currInvokeSuperClsName, ORIGSelectorName, [JSValue valueWithObject:argList inContext:_context], [JSValue valueWithObject:@{@"__obj": slf, @"__realClsName": @""} inContext:_context], NO); + id retObj = callSelector(_currInvokeSuperClsName[selectorName], ORIGSelectorName, [JSValue valueWithObject:argList inContext:_context], [JSValue valueWithObject:@{@"__obj": slf, @"__realClsName": @""} inContext:_context], NO); id __autoreleasing ret = formatJSToOC([JSValue valueWithObject:retObj inContext:_context]); [invocation setReturnValue:&ret]; return; @@ -985,7 +986,7 @@ static void overrideMethod(Class cls, NSString *selectorName, JSValue *function, _initJPOverideMethods(cls); _JSOverideMethods[cls][JPSelectorName] = function; - // Replace the original secltor at last, preventing threading issus when + // Replace the original selector at last, preventing threading issus when // the selector get called during the execution of `overrideMethod` class_replaceMethod(cls, selector, msgForwardIMP, typeDescription); } @@ -1196,9 +1197,9 @@ static id callSelector(NSString *className, NSString *selectorName, JSValue *arg } } - if (superClassName) _currInvokeSuperClsName = superClassName; + if (superClassName) _currInvokeSuperClsName[selectorName] = superClassName; [invocation invoke]; - if (superClassName) _currInvokeSuperClsName = nil; + if (superClassName) [_currInvokeSuperClsName removeObjectForKey:selectorName]; if ([_markArray count] > 0) { for (JPBoxing *box in _markArray) { void *pointer = [box unboxPointer]; @@ -1314,16 +1315,16 @@ static id callSelector(NSString *className, NSString *selectorName, JSValue *arg return nil; } -id (*new_msgSend1)(id, SEL, id,...) = (id (*)(id, SEL, id,...)) objc_msgSend; -id (*new_msgSend2)(id, SEL, id, id,...) = (id (*)(id, SEL, id, id,...)) objc_msgSend; -id (*new_msgSend3)(id, SEL, id, id, id,...) = (id (*)(id, SEL, id, id, id,...)) objc_msgSend; -id (*new_msgSend4)(id, SEL, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id,...)) objc_msgSend; -id (*new_msgSend5)(id, SEL, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id,...)) objc_msgSend; -id (*new_msgSend6)(id, SEL, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,...)) objc_msgSend; -id (*new_msgSend7)(id, SEL, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,id,...)) objc_msgSend; -id (*new_msgSend8)(id, SEL, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id,...)) objc_msgSend; -id (*new_msgSend9)(id, SEL, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, ...)) objc_msgSend; -id (*new_msgSend10)(id, SEL, id, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, id,...)) objc_msgSend; +static id (*new_msgSend1)(id, SEL, id,...) = (id (*)(id, SEL, id,...)) objc_msgSend; +static id (*new_msgSend2)(id, SEL, id, id,...) = (id (*)(id, SEL, id, id,...)) objc_msgSend; +static id (*new_msgSend3)(id, SEL, id, id, id,...) = (id (*)(id, SEL, id, id, id,...)) objc_msgSend; +static id (*new_msgSend4)(id, SEL, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id,...)) objc_msgSend; +static id (*new_msgSend5)(id, SEL, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id,...)) objc_msgSend; +static id (*new_msgSend6)(id, SEL, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,...)) objc_msgSend; +static id (*new_msgSend7)(id, SEL, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,id,...)) objc_msgSend; +static id (*new_msgSend8)(id, SEL, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id,...)) objc_msgSend; +static id (*new_msgSend9)(id, SEL, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, ...)) objc_msgSend; +static id (*new_msgSend10)(id, SEL, id, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, id,...)) objc_msgSend; static id invokeVariableParameterMethod(NSMutableArray *origArgumentsList, NSMethodSignature *methodSignature, id sender, SEL selector) { @@ -1396,7 +1397,10 @@ static id genCallbackBlock(JSValue *jsVal) { #define BLK_TRAITS_ARG(_idx, _paramName) \ if (_idx < argTypes.count) { \ - if (blockTypeIsObject(trim(argTypes[_idx]))) { \ + NSString *argType = trim(argTypes[_idx]); \ + if (blockTypeIsSCalarPointer(argType)) { \ + [list addObject:formatOCToJS([JPBoxing boxPointer:_paramName])]; \ + } else if (blockTypeIsObject(trim(argTypes[_idx]))) { \ [list addObject:formatOCToJS((__bridge id)_paramName)]; \ } else { \ [list addObject:formatOCToJS([NSNumber numberWithLongLong:(long long)_paramName])]; \ @@ -1596,6 +1600,15 @@ static BOOL blockTypeIsObject(NSString *typeString) return [typeString rangeOfString:@"*"].location != NSNotFound || [typeString isEqualToString:@"id"]; } +static BOOL blockTypeIsSCalarPointer(NSString *typeString) +{ + NSUInteger location = [typeString rangeOfString:@"*"].location; + NSString *typeWithoutAsterisk = trim([typeString stringByReplacingOccurrencesOfString:@"*" withString:@""]); + + return (location == typeString.length-1 && + !NSClassFromString(typeWithoutAsterisk)); +} + static NSString *convertJPSelectorString(NSString *selectorString) { NSString *tmpJSMethodName = [selectorString stringByReplacingOccurrencesOfString:@"__" withString:@"-"]; diff --git a/Pods/JSPatch/JSPatch/JSPatch.js b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JSPatch.js old mode 100644 new mode 100755 similarity index 88% rename from Pods/JSPatch/JSPatch/JSPatch.js rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JSPatch.js index b49f6ef..26b8be6 --- a/Pods/JSPatch/JSPatch/JSPatch.js +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JSPatch/JSPatch.js @@ -84,28 +84,6 @@ var global = this slf.__isSuper = 0; return _ocCls[clsName][methodType][methodName].bind(slf) } - - if (slf.__obj && _ocCls[clsName]['props'][methodName]) { - if (!slf.__ocProps) { - var props = _OC_getCustomProps(slf.__obj) - if (!props) { - props = {} - _OC_setCustomProps(slf.__obj, props) - } - slf.__ocProps = props; - } - var c = methodName.charCodeAt(3); - if (methodName.length > 3 && methodName.substr(0,3) == 'set' && c >= 65 && c <= 90) { - return function(val) { - var propName = methodName[3].toLowerCase() + methodName.substr(4) - slf.__ocProps[propName] = val - } - } else { - return function(){ - return slf.__ocProps[methodName] - } - } - } } return function(){ @@ -200,6 +178,36 @@ var global = this } } + var _propertiesGetFun = function(name){ + var slf = this; + if (!slf.__ocProps) { + var props = _OC_getCustomProps(slf.__obj) + if (!props) { + props = {} + _OC_setCustomProps(slf.__obj, props) + } + slf.__ocProps = props; + } + return function(){ + return slf.__ocProps[name]; + }; + } + + var _propertiesSetFun = function(name){ + var slf = this; + if (!slf.__ocProps) { + var props = _OC_getCustomProps(slf.__obj) + if (!props) { + props = {} + _OC_setCustomProps(slf.__obj, props) + } + slf.__ocProps = props; + } + return function(jval){ + slf.__ocProps[name] = jval; + }; + } + global.defineClass = function(declaration, properties, instMethods, clsMethods) { var newInstMethods = {}, newClsMethods = {} if (!(properties instanceof Array)) { @@ -208,6 +216,18 @@ var global = this properties = null } + if (properties) { + properties.forEach(function(name){ + if (!instMethods[name]) { + instMethods[name] = _propertiesGetFun(name); + } + var nameOfSet = "set"+ name.substr(0,1).toUpperCase() + name.substr(1); + if (!instMethods[nameOfSet]) { + instMethods[nameOfSet] = _propertiesSetFun(name); + } + }); + } + var realClsName = declaration.split(':')[0].trim() _formatDefineMethods(instMethods, newInstMethods, realClsName) @@ -220,7 +240,6 @@ var global = this _ocCls[className] = { instMethods: {}, clsMethods: {}, - props: {} } if (superCls.length && _ocCls[superCls]) { @@ -230,20 +249,11 @@ var global = this for (var funcName in _ocCls[superCls]['clsMethods']) { _ocCls[className]['clsMethods'][funcName] = _ocCls[superCls]['clsMethods'][funcName] } - if (_ocCls[superCls]['props']) { - _ocCls[className]['props'] = JSON.parse(JSON.stringify(_ocCls[superCls]['props'])); - } } _setupJSMethod(className, instMethods, 1, realClsName) _setupJSMethod(className, clsMethods, 0, realClsName) - if (properties) { - properties.forEach(function(o){ - _ocCls[className]['props'][o] = 1 - _ocCls[className]['props']['set' + o.substr(0,1).toUpperCase() + o.substr(1)] = 1 - }) - } return require(className) } diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/AFDownloadRequestOperation/AFDownloadRequestOperation.m diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaBaseRequest.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/JiaBaseRequest.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaBaseRequest.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/JiaBaseRequest.h diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaBaseRequest.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/JiaBaseRequest.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaCore/JiaCoreHelper/JiaBaseRequest.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/JiaBaseRequest.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBaseRequest.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBaseRequest.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBaseRequest.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBaseRequest.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBaseRequest.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBaseRequest.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBaseRequest.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBaseRequest.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequest.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequest.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequest.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequest.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequest.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequest.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequest.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequest.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKBatchRequestAgent.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequest.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequest.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequest.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequest.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequest.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequest.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequest.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequest.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequestAgent.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequestAgent.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequestAgent.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequestAgent.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequestAgent.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequestAgent.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKChainRequestAgent.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKChainRequestAgent.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetwork.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetwork.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetwork.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetwork.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkAgent.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkAgent.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkAgent.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkAgent.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkAgent.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkAgent.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkAgent.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkAgent.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkConfig.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkConfig.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkConfig.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkConfig.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkConfig.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkConfig.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkConfig.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkConfig.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkPrivate.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkPrivate.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkPrivate.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkPrivate.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkPrivate.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkPrivate.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKNetworkPrivate.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKNetworkPrivate.m diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKRequest.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKRequest.h similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKRequest.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKRequest.h diff --git a/jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKRequest.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKRequest.m similarity index 100% rename from jiaModuleDemo/BaseModule/JiaNewWork/YTKNetwork/YTKRequest.m rename to jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/JiaNewWork/YTKNetwork/YTKRequest.m diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.h new file mode 100755 index 0000000..f042ed7 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.h @@ -0,0 +1,206 @@ +// +// YYCache.h +// YYCache +// +// Created by ibireme on 15/2/13. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +#if __has_include() +FOUNDATION_EXPORT double YYCacheVersionNumber; +FOUNDATION_EXPORT const unsigned char YYCacheVersionString[]; +#import +#import +#import +#elif __has_include() +#import +#import +#import +#else +#import "YYMemoryCache.h" +#import "YYDiskCache.h" +#import "YYKVStorage.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + + +/** + `YYCache` is a thread safe key-value cache. + + It use `YYMemoryCache` to store objects in a small and fast memory cache, + and use `YYDiskCache` to persisting objects to a large and slow disk cache. + See `YYMemoryCache` and `YYDiskCache` for more information. + */ +@interface YYCache : NSObject + +/** The name of the cache, readonly. */ +@property (copy, readonly) NSString *name; + +/** The underlying memory cache. see `YYMemoryCache` for more information.*/ +@property (strong, readonly) YYMemoryCache *memoryCache; + +/** The underlying disk cache. see `YYDiskCache` for more information.*/ +@property (strong, readonly) YYDiskCache *diskCache; + +/** + Create a new instance with the specified name. + Multiple instances with the same name will make the cache unstable. + + @param name The name of the cache. It will create a dictionary with the name in + the app's caches dictionary for disk cache. Once initialized you should not + read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ +- (nullable instancetype)initWithName:(NSString *)name; + +/** + Create a new instance with the specified path. + Multiple instances with the same name will make the cache unstable. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ +- (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; + +/** + Convenience Initializers + Create a new instance with the specified name. + Multiple instances with the same name will make the cache unstable. + + @param name The name of the cache. It will create a dictionary with the name in + the app's caches dictionary for disk cache. Once initialized you should not + read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ ++ (nullable instancetype)cacheWithName:(NSString *)name; + +/** + Convenience Initializers + Create a new instance with the specified path. + Multiple instances with the same name will make the cache unstable. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ ++ (nullable instancetype)cacheWithPath:(NSString *)path; + +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + Returns a boolean value that indicates whether a given key is in cache. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the value. If nil, just return NO. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(NSString *)key; + +/** + Returns a boolean value with the block that indicates whether a given key is in cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return NO. + @param block A block which will be invoked in background queue when finished. + */ +- (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block; + +/** + Returns the value associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the value. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable id)objectForKey:(NSString *)key; + +/** + Returns the value associated with a given key. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return nil. + @param block A block which will be invoked in background queue when finished. + */ +- (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id object))block; + +/** + Sets the value of the specified key in the cache. + This method may blocks the calling thread until file write finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param key The key with which to associate the value. If nil, this method has no effect. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key; + +/** + Sets the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param block A block which will be invoked in background queue when finished. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block; + +/** + Removes the value of the specified key in the cache. + This method may blocks the calling thread until file delete finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + */ +- (void)removeObjectForKey:(NSString *)key; + +/** + Removes the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block; + +/** + Empties the cache. + This method may blocks the calling thread until file delete finished. + */ +- (void)removeAllObjects; + +/** + Empties the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeAllObjectsWithBlock:(void(^)(void))block; + +/** + Empties the cache with block. + This method returns immediately and executes the clear operation with block in background. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + +@end + +NS_ASSUME_NONNULL_END diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.m new file mode 100755 index 0000000..e6cdcba --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYCache.m @@ -0,0 +1,139 @@ +// +// YYCache.m +// YYCache +// +// Created by ibireme on 15/2/13. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYCache.h" +#import "YYMemoryCache.h" +#import "YYDiskCache.h" + +@implementation YYCache + +- (instancetype) init { + NSLog(@"Use \"initWithName\" or \"initWithPath\" to create YYCache instance."); + return [self initWithPath:@""]; +} + +- (instancetype)initWithName:(NSString *)name { + if (name.length == 0) return nil; + NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; + NSString *path = [cacheFolder stringByAppendingPathComponent:name]; + return [self initWithPath:path]; +} + +- (instancetype)initWithPath:(NSString *)path { + if (path.length == 0) return nil; + YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path]; + if (!diskCache) return nil; + NSString *name = [path lastPathComponent]; + YYMemoryCache *memoryCache = [YYMemoryCache new]; + memoryCache.name = name; + + self = [super init]; + _name = name; + _diskCache = diskCache; + _memoryCache = memoryCache; + return self; +} + ++ (instancetype)cacheWithName:(NSString *)name { + return [[self alloc] initWithName:name]; +} + ++ (instancetype)cacheWithPath:(NSString *)path { + return [[self alloc] initWithPath:path]; +} + +- (BOOL)containsObjectForKey:(NSString *)key { + return [_memoryCache containsObjectForKey:key] || [_diskCache containsObjectForKey:key]; +} + +- (void)containsObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key, BOOL contains))block { + if (!block) return; + + if ([_memoryCache containsObjectForKey:key]) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + block(key, YES); + }); + } else { + [_diskCache containsObjectForKey:key withBlock:block]; + } +} + +- (id)objectForKey:(NSString *)key { + id object = [_memoryCache objectForKey:key]; + if (!object) { + object = [_diskCache objectForKey:key]; + if (object) { + [_memoryCache setObject:object forKey:key]; + } + } + return object; +} + +- (void)objectForKey:(NSString *)key withBlock:(void (^)(NSString *key, id object))block { + if (!block) return; + id object = [_memoryCache objectForKey:key]; + if (object) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + block(key, object); + }); + } else { + [_diskCache objectForKey:key withBlock:^(NSString *key, id object) { + if (object && ![_memoryCache objectForKey:key]) { + [_memoryCache setObject:object forKey:key]; + } + block(key, object); + }]; + } +} + +- (void)setObject:(id)object forKey:(NSString *)key { + [_memoryCache setObject:object forKey:key]; + [_diskCache setObject:object forKey:key]; +} + +- (void)setObject:(id)object forKey:(NSString *)key withBlock:(void (^)(void))block { + [_memoryCache setObject:object forKey:key]; + [_diskCache setObject:object forKey:key withBlock:block]; +} + +- (void)removeObjectForKey:(NSString *)key { + [_memoryCache removeObjectForKey:key]; + [_diskCache removeObjectForKey:key]; +} + +- (void)removeObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key))block { + [_memoryCache removeObjectForKey:key]; + [_diskCache removeObjectForKey:key withBlock:block]; +} + +- (void)removeAllObjects { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjects]; +} + +- (void)removeAllObjectsWithBlock:(void(^)(void))block { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjectsWithBlock:block]; +} + +- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjectsWithProgressBlock:progress endBlock:end]; + +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name]; + else return [NSString stringWithFormat:@"<%@: %p>", self.class, self]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.h new file mode 100755 index 0000000..dd193e4 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.h @@ -0,0 +1,412 @@ +// +// YYDiskCache.h +// YYCache +// +// Created by ibireme on 15/2/11. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYDiskCache is a thread-safe cache that stores key-value pairs backed by SQLite + and file system (similar to NSURLCache's disk cache). + + YYDiskCache has these features: + + * It use LRU (least-recently-used) to remove objects. + * It can be controlled by cost, count, and age. + * It can be configured to automatically evict objects when there's no free disk space. + * It can automatically decide the storage type (sqlite/file) for each object to get + better performance. + + You may compile the latest version of sqlite and ignore the libsqlite3.dylib in + iOS system to get 2x~4x speed up. + */ +@interface YYDiskCache : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +/** The name of the cache. Default is nil. */ +@property (nullable, copy) NSString *name; + +/** The path of the cache (read-only). */ +@property (readonly) NSString *path; + +/** + If the object's data size (in bytes) is larger than this value, then object will + be stored as a file, otherwise the object will be stored in sqlite. + + 0 means all objects will be stored as separated files, NSUIntegerMax means all + objects will be stored in sqlite. + + The default value is 20480 (20KB). + */ +@property (readonly) NSUInteger inlineThreshold; + +/** + If this block is not nil, then the block will be used to archive object instead + of NSKeyedArchiver. You can use this block to support the objects which do not + conform to the `NSCoding` protocol. + + The default value is nil. + */ +@property (nullable, copy) NSData *(^customArchiveBlock)(id object); + +/** + If this block is not nil, then the block will be used to unarchive object instead + of NSKeyedUnarchiver. You can use this block to support the objects which do not + conform to the `NSCoding` protocol. + + The default value is nil. + */ +@property (nullable, copy) id (^customUnarchiveBlock)(NSData *data); + +/** + When an object needs to be saved as a file, this block will be invoked to generate + a file name for a specified key. If the block is nil, the cache use md5(key) as + default file name. + + The default value is nil. + */ +@property (nullable, copy) NSString *(^customFileNameBlock)(NSString *key); + + + +#pragma mark - Limit +///============================================================================= +/// @name Limit +///============================================================================= + +/** + The maximum number of objects the cache should hold. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit — if the cache goes over the limit, some objects in the + cache could be evicted later in background queue. + */ +@property NSUInteger countLimit; + +/** + The maximum total cost that the cache can hold before it starts evicting objects. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit — if the cache goes over the limit, some objects in the + cache could be evicted later in background queue. + */ +@property NSUInteger costLimit; + +/** + The maximum expiry time of objects in cache. + + @discussion The default value is DBL_MAX, which means no limit. + This is not a strict limit — if an object goes over the limit, the objects could + be evicted later in background queue. + */ +@property NSTimeInterval ageLimit; + +/** + The minimum free disk space (in bytes) which the cache should kept. + + @discussion The default value is 0, which means no limit. + If the free disk space is lower than this value, the cache will remove objects + to free some disk space. This is not a strict limit—if the free disk space goes + over the limit, the objects could be evicted later in background queue. + */ +@property NSUInteger freeDiskSpaceLimit; + +/** + The auto trim check time interval in seconds. Default is 60 (1 minute). + + @discussion The cache holds an internal timer to check whether the cache reaches + its limits, and if the limit is reached, it begins to evict objects. + */ +@property NSTimeInterval autoTrimInterval; + +/** + Set `YES` to enable error logs for debug. + */ +@property BOOL errorLogsEnabled; + +#pragma mark - Initializer +///============================================================================= +/// @name Initializer +///============================================================================= +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +/** + Create a new cache based on the specified path. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + + @return A new cache object, or nil if an error occurs. + + @warning If the cache instance for the specified path already exists in memory, + this method will return it directly, instead of creating a new instance. + */ +- (nullable instancetype)initWithPath:(NSString *)path; + +/** + The designated initializer. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + + @param threshold The data store inline threshold in bytes. If the object's data + size (in bytes) is larger than this value, then object will be stored as a + file, otherwise the object will be stored in sqlite. 0 means all objects will + be stored as separated files, NSUIntegerMax means all objects will be stored + in sqlite. If you don't know your object's size, 20480 is a good choice. + After first initialized you should not change this value of the specified path. + + @return A new cache object, or nil if an error occurs. + + @warning If the cache instance for the specified path already exists in memory, + this method will return it directly, instead of creating a new instance. + */ +- (nullable instancetype)initWithPath:(NSString *)path + inlineThreshold:(NSUInteger)threshold NS_DESIGNATED_INITIALIZER; + + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + Returns a boolean value that indicates whether a given key is in cache. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the value. If nil, just return NO. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(NSString *)key; + +/** + Returns a boolean value with the block that indicates whether a given key is in cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return NO. + @param block A block which will be invoked in background queue when finished. + */ +- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block; + +/** + Returns the value associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the value. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable id)objectForKey:(NSString *)key; + +/** + Returns the value associated with a given key. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return nil. + @param block A block which will be invoked in background queue when finished. + */ +- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id _Nullable object))block; + +/** + Sets the value of the specified key in the cache. + This method may blocks the calling thread until file write finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param key The key with which to associate the value. If nil, this method has no effect. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key; + +/** + Sets the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param block A block which will be invoked in background queue when finished. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(void(^)(void))block; + +/** + Removes the value of the specified key in the cache. + This method may blocks the calling thread until file delete finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + */ +- (void)removeObjectForKey:(NSString *)key; + +/** + Removes the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block; + +/** + Empties the cache. + This method may blocks the calling thread until file delete finished. + */ +- (void)removeAllObjects; + +/** + Empties the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeAllObjectsWithBlock:(void(^)(void))block; + +/** + Empties the cache with block. + This method returns immediately and executes the clear operation with block in background. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + + +/** + Returns the number of objects in this cache. + This method may blocks the calling thread until file read finished. + + @return The total objects count. + */ +- (NSInteger)totalCount; + +/** + Get the number of objects in this cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block; + +/** + Returns the total cost (in bytes) of objects in this cache. + This method may blocks the calling thread until file read finished. + + @return The total objects cost in bytes. + */ +- (NSInteger)totalCost; + +/** + Get the total cost (in bytes) of objects in this cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block; + + +#pragma mark - Trim +///============================================================================= +/// @name Trim +///============================================================================= + +/** + Removes objects from the cache use LRU, until the `totalCount` is below the specified value. + This method may blocks the calling thread until operation finished. + + @param count The total count allowed to remain after the cache has been trimmed. + */ +- (void)trimToCount:(NSUInteger)count; + +/** + Removes objects from the cache use LRU, until the `totalCount` is below the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param count The total count allowed to remain after the cache has been trimmed. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block; + +/** + Removes objects from the cache use LRU, until the `totalCost` is below the specified value. + This method may blocks the calling thread until operation finished. + + @param cost The total cost allowed to remain after the cache has been trimmed. + */ +- (void)trimToCost:(NSUInteger)cost; + +/** + Removes objects from the cache use LRU, until the `totalCost` is below the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param cost The total cost allowed to remain after the cache has been trimmed. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block; + +/** + Removes objects from the cache use LRU, until all expiry objects removed by the specified value. + This method may blocks the calling thread until operation finished. + + @param age The maximum age of the object. + */ +- (void)trimToAge:(NSTimeInterval)age; + +/** + Removes objects from the cache use LRU, until all expiry objects removed by the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param age The maximum age of the object. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block; + + +#pragma mark - Extended Data +///============================================================================= +/// @name Extended Data +///============================================================================= + +/** + Get extended data from an object. + + @discussion See 'setExtendedData:toObject:' for more information. + + @param object An object. + @return The extended data. + */ ++ (nullable NSData *)getExtendedDataFromObject:(id)object; + +/** + Set extended data to an object. + + @discussion You can set any extended data to an object before you save the object + to disk cache. The extended data will also be saved with this object. You can get + the extended data later with "getExtendedDataFromObject:". + + @param extendedData The extended data (pass nil to remove). + @param object The object. + */ ++ (void)setExtendedData:(nullable NSData *)extendedData toObject:(id)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.m new file mode 100755 index 0000000..735cc5d --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYDiskCache.m @@ -0,0 +1,458 @@ +// +// YYDiskCache.m +// YYCache +// +// Created by ibireme on 15/2/11. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYDiskCache.h" +#import "YYKVStorage.h" +#import +#import +#import +#import + +#define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER) +#define Unlock() dispatch_semaphore_signal(self->_lock) + +static const int extended_data_key; + +/// Free disk space in bytes. +static int64_t _YYDiskSpaceFree() { + NSError *error = nil; + NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error]; + if (error) return -1; + int64_t space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue]; + if (space < 0) space = -1; + return space; +} + +/// String's md5 hash. +static NSString *_YYNSStringMD5(NSString *string) { + if (!string) return nil; + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; + CC_MD5(data.bytes, (CC_LONG)data.length, result); + return [NSString stringWithFormat: + @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + result[0], result[1], result[2], result[3], + result[4], result[5], result[6], result[7], + result[8], result[9], result[10], result[11], + result[12], result[13], result[14], result[15] + ]; +} + +/// weak reference for all instances +static NSMapTable *_globalInstances; +static dispatch_semaphore_t _globalInstancesLock; + +static void _YYDiskCacheInitGlobal() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _globalInstancesLock = dispatch_semaphore_create(1); + _globalInstances = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0]; + }); +} + +static YYDiskCache *_YYDiskCacheGetGlobal(NSString *path) { + if (path.length == 0) return nil; + _YYDiskCacheInitGlobal(); + dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER); + id cache = [_globalInstances objectForKey:path]; + dispatch_semaphore_signal(_globalInstancesLock); + return cache; +} + +static void _YYDiskCacheSetGlobal(YYDiskCache *cache) { + if (cache.path.length == 0) return; + _YYDiskCacheInitGlobal(); + dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER); + [_globalInstances setObject:cache forKey:cache.path]; + dispatch_semaphore_signal(_globalInstancesLock); +} + + + +@implementation YYDiskCache { + YYKVStorage *_kv; + dispatch_semaphore_t _lock; + dispatch_queue_t _queue; +} + +- (void)_trimRecursively { + __weak typeof(self) _self = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_autoTrimInterval * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + __strong typeof(_self) self = _self; + if (!self) return; + [self _trimInBackground]; + [self _trimRecursively]; + }); +} + +- (void)_trimInBackground { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + if (!self) return; + Lock(); + [self _trimToCost:self.costLimit]; + [self _trimToCount:self.countLimit]; + [self _trimToAge:self.ageLimit]; + [self _trimToFreeDiskSpace:self.freeDiskSpaceLimit]; + Unlock(); + }); +} + +- (void)_trimToCost:(NSUInteger)costLimit { + if (costLimit >= INT_MAX) return; + [_kv removeItemsToFitSize:(int)costLimit]; + +} + +- (void)_trimToCount:(NSUInteger)countLimit { + if (countLimit >= INT_MAX) return; + [_kv removeItemsToFitCount:(int)countLimit]; +} + +- (void)_trimToAge:(NSTimeInterval)ageLimit { + if (ageLimit <= 0) { + [_kv removeAllItems]; + return; + } + long timestamp = time(NULL); + if (timestamp <= ageLimit) return; + long age = timestamp - ageLimit; + if (age >= INT_MAX) return; + [_kv removeItemsEarlierThanTime:(int)age]; +} + +- (void)_trimToFreeDiskSpace:(NSUInteger)targetFreeDiskSpace { + if (targetFreeDiskSpace == 0) return; + int64_t totalBytes = [_kv getItemsSize]; + if (totalBytes <= 0) return; + int64_t diskFreeBytes = _YYDiskSpaceFree(); + if (diskFreeBytes < 0) return; + int64_t needTrimBytes = targetFreeDiskSpace - diskFreeBytes; + if (needTrimBytes <= 0) return; + int64_t costLimit = totalBytes - needTrimBytes; + if (costLimit < 0) costLimit = 0; + [self _trimToCost:(int)costLimit]; +} + +- (NSString *)_filenameForKey:(NSString *)key { + NSString *filename = nil; + if (_customFileNameBlock) filename = _customFileNameBlock(key); + if (!filename) filename = _YYNSStringMD5(key); + return filename; +} + +- (void)_appWillBeTerminated { + Lock(); + _kv = nil; + Unlock(); +} + +#pragma mark - public + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil]; +} + +- (instancetype)init { + @throw [NSException exceptionWithName:@"YYDiskCache init error" reason:@"YYDiskCache must be initialized with a path. Use 'initWithPath:' or 'initWithPath:inlineThreshold:' instead." userInfo:nil]; + return [self initWithPath:@"" inlineThreshold:0]; +} + +- (instancetype)initWithPath:(NSString *)path { + return [self initWithPath:path inlineThreshold:1024 * 20]; // 20KB +} + +- (instancetype)initWithPath:(NSString *)path + inlineThreshold:(NSUInteger)threshold { + self = [super init]; + if (!self) return nil; + + YYDiskCache *globalCache = _YYDiskCacheGetGlobal(path); + if (globalCache) return globalCache; + + YYKVStorageType type; + if (threshold == 0) { + type = YYKVStorageTypeFile; + } else if (threshold == NSUIntegerMax) { + type = YYKVStorageTypeSQLite; + } else { + type = YYKVStorageTypeMixed; + } + + YYKVStorage *kv = [[YYKVStorage alloc] initWithPath:path type:type]; + if (!kv) return nil; + + _kv = kv; + _path = path; + _lock = dispatch_semaphore_create(1); + _queue = dispatch_queue_create("com.ibireme.cache.disk", DISPATCH_QUEUE_CONCURRENT); + _inlineThreshold = threshold; + _countLimit = NSUIntegerMax; + _costLimit = NSUIntegerMax; + _ageLimit = DBL_MAX; + _freeDiskSpaceLimit = 0; + _autoTrimInterval = 60; + + [self _trimRecursively]; + _YYDiskCacheSetGlobal(self); + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appWillBeTerminated) name:UIApplicationWillTerminateNotification object:nil]; + return self; +} + +- (BOOL)containsObjectForKey:(NSString *)key { + if (!key) return NO; + Lock(); + BOOL contains = [_kv itemExistsForKey:key]; + Unlock(); + return contains; +} + +- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + BOOL contains = [self containsObjectForKey:key]; + block(key, contains); + }); +} + +- (id)objectForKey:(NSString *)key { + if (!key) return nil; + Lock(); + YYKVStorageItem *item = [_kv getItemForKey:key]; + Unlock(); + if (!item.value) return nil; + + id object = nil; + if (_customUnarchiveBlock) { + object = _customUnarchiveBlock(item.value); + } else { + @try { + object = [NSKeyedUnarchiver unarchiveObjectWithData:item.value]; + } + @catch (NSException *exception) { + // nothing to do... + } + } + if (object && item.extendedData) { + [YYDiskCache setExtendedData:item.extendedData toObject:object]; + } + return object; +} + +- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id object))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + id object = [self objectForKey:key]; + block(key, object); + }); +} + +- (void)setObject:(id)object forKey:(NSString *)key { + if (!key) return; + if (!object) { + [self removeObjectForKey:key]; + return; + } + + NSData *extendedData = [YYDiskCache getExtendedDataFromObject:object]; + NSData *value = nil; + if (_customArchiveBlock) { + value = _customArchiveBlock(object); + } else { + @try { + value = [NSKeyedArchiver archivedDataWithRootObject:object]; + } + @catch (NSException *exception) { + // nothing to do... + } + } + if (!value) return; + NSString *filename = nil; + if (_kv.type != YYKVStorageTypeSQLite) { + if (value.length > _inlineThreshold) { + filename = [self _filenameForKey:key]; + } + } + + Lock(); + [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData]; + Unlock(); +} + +- (void)setObject:(id)object forKey:(NSString *)key withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self setObject:object forKey:key]; + if (block) block(); + }); +} + +- (void)removeObjectForKey:(NSString *)key { + if (!key) return; + Lock(); + [_kv removeItemForKey:key]; + Unlock(); +} + +- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self removeObjectForKey:key]; + if (block) block(key); + }); +} + +- (void)removeAllObjects { + Lock(); + [_kv removeAllItems]; + Unlock(); +} + +- (void)removeAllObjectsWithBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self removeAllObjects]; + if (block) block(); + }); +} + +- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + if (!self) { + if (end) end(YES); + return; + } + Lock(); + [_kv removeAllItemsWithProgressBlock:progress endBlock:end]; + Unlock(); + }); +} + +- (NSInteger)totalCount { + Lock(); + int count = [_kv getItemsCount]; + Unlock(); + return count; +} + +- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + NSInteger totalCount = [self totalCount]; + block(totalCount); + }); +} + +- (NSInteger)totalCost { + Lock(); + int count = [_kv getItemsSize]; + Unlock(); + return count; +} + +- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + NSInteger totalCost = [self totalCost]; + block(totalCost); + }); +} + +- (void)trimToCount:(NSUInteger)count { + Lock(); + [self _trimToCount:count]; + Unlock(); +} + +- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToCount:count]; + if (block) block(); + }); +} + +- (void)trimToCost:(NSUInteger)cost { + Lock(); + [self _trimToCost:cost]; + Unlock(); +} + +- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToCost:cost]; + if (block) block(); + }); +} + +- (void)trimToAge:(NSTimeInterval)age { + Lock(); + [self _trimToAge:age]; + Unlock(); +} + +- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToAge:age]; + if (block) block(); + }); +} + ++ (NSData *)getExtendedDataFromObject:(id)object { + if (!object) return nil; + return (NSData *)objc_getAssociatedObject(object, &extended_data_key); +} + ++ (void)setExtendedData:(NSData *)extendedData toObject:(id)object { + if (!object) return; + objc_setAssociatedObject(object, &extended_data_key, extendedData, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@:%@)", self.class, self, _name, _path]; + else return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _path]; +} + +- (BOOL)errorLogsEnabled { + Lock(); + BOOL enabled = _kv.errorLogsEnabled; + Unlock(); + return enabled; +} + +- (void)setErrorLogsEnabled:(BOOL)errorLogsEnabled { + Lock(); + _kv.errorLogsEnabled = errorLogsEnabled; + Unlock(); +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.h new file mode 100755 index 0000000..939a6e4 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.h @@ -0,0 +1,325 @@ +// +// YYKVStorage.h +// YYCache +// +// Created by ibireme on 15/4/22. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYKVStorageItem is used by `YYKVStorage` to store key-value pair and meta data. + Typically, you should not use this class directly. + */ +@interface YYKVStorageItem : NSObject +@property (nonatomic, strong) NSString *key; ///< key +@property (nonatomic, strong) NSData *value; ///< value +@property (nullable, nonatomic, strong) NSString *filename; ///< filename (nil if inline) +@property (nonatomic) int size; ///< value's size in bytes +@property (nonatomic) int modTime; ///< modification unix timestamp +@property (nonatomic) int accessTime; ///< last access unix timestamp +@property (nullable, nonatomic, strong) NSData *extendedData; ///< extended data (nil if no extended data) +@end + +/** + Storage type, indicated where the `YYKVStorageItem.value` stored. + + @discussion Typically, write data to sqlite is faster than extern file, but + reading performance is dependent on data size. In my test (on iPhone 6 64G), + read data from extern file is faster than from sqlite when the data is larger + than 20KB. + + * If you want to store large number of small datas (such as contacts cache), + use YYKVStorageTypeSQLite to get better performance. + * If you want to store large files (such as image cache), + use YYKVStorageTypeFile to get better performance. + * You can use YYKVStorageTypeMixed and choice your storage type for each item. + + See for more information. + */ +typedef NS_ENUM(NSUInteger, YYKVStorageType) { + + /// The `value` is stored as a file in file system. + YYKVStorageTypeFile = 0, + + /// The `value` is stored in sqlite with blob type. + YYKVStorageTypeSQLite = 1, + + /// The `value` is stored in file system or sqlite based on your choice. + YYKVStorageTypeMixed = 2, +}; + + + +/** + YYKVStorage is a key-value storage based on sqlite and file system. + Typically, you should not use this class directly. + + @discussion The designated initializer for YYKVStorage is `initWithPath:type:`. + After initialized, a directory is created based on the `path` to hold key-value data. + Once initialized you should not read or write this directory without the instance. + + You may compile the latest version of sqlite and ignore the libsqlite3.dylib in + iOS system to get 2x~4x speed up. + + @warning The instance of this class is *NOT* thread safe, you need to make sure + that there's only one thread to access the instance at the same time. If you really + need to process large amounts of data in multi-thread, you should split the data + to multiple KVStorage instance (sharding). + */ +@interface YYKVStorage : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +@property (nonatomic, readonly) NSString *path; ///< The path of this storage. +@property (nonatomic, readonly) YYKVStorageType type; ///< The type of this storage. +@property (nonatomic) BOOL errorLogsEnabled; ///< Set `YES` to enable error logs for debug. + +#pragma mark - Initializer +///============================================================================= +/// @name Initializer +///============================================================================= +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +/** + The designated initializer. + + @param path Full path of a directory in which the storage will write data. If + the directory is not exists, it will try to create one, otherwise it will + read the data in this directory. + @param type The storage type. After first initialized you should not change the + type of the specified path. + @return A new storage object, or nil if an error occurs. + @warning Multiple instances with the same path will make the storage unstable. + */ +- (nullable instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type NS_DESIGNATED_INITIALIZER; + + +#pragma mark - Save Items +///============================================================================= +/// @name Save Items +///============================================================================= + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion This method will save the item.key, item.value, item.filename and + item.extendedData to disk or sqlite, other properties will be ignored. item.key + and item.value should not be empty (nil or zero length). + + If the `type` is YYKVStorageTypeFile, then the item.filename should not be empty. + If the `type` is YYKVStorageTypeSQLite, then the item.filename will be ignored. + It the `type` is YYKVStorageTypeMixed, then the item.value will be saved to file + system if the item.filename is not empty, otherwise it will be saved to sqlite. + + @param item An item. + @return Whether succeed. + */ +- (BOOL)saveItem:(YYKVStorageItem *)item; + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion This method will save the key-value pair to sqlite. If the `type` is + YYKVStorageTypeFile, then this method will failed. + + @param key The key, should not be empty (nil or zero length). + @param value The key, should not be empty (nil or zero length). + @return Whether succeed. + */ +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value; + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion + If the `type` is YYKVStorageTypeFile, then the `filename` should not be empty. + If the `type` is YYKVStorageTypeSQLite, then the `filename` will be ignored. + It the `type` is YYKVStorageTypeMixed, then the `value` will be saved to file + system if the `filename` is not empty, otherwise it will be saved to sqlite. + + @param key The key, should not be empty (nil or zero length). + @param value The key, should not be empty (nil or zero length). + @param filename The filename. + @param extendedData The extended data for this item (pass nil to ignore it). + + @return Whether succeed. + */ +- (BOOL)saveItemWithKey:(NSString *)key + value:(NSData *)value + filename:(nullable NSString *)filename + extendedData:(nullable NSData *)extendedData; + +#pragma mark - Remove Items +///============================================================================= +/// @name Remove Items +///============================================================================= + +/** + Remove an item with 'key'. + + @param key The item's key. + @return Whether succeed. + */ +- (BOOL)removeItemForKey:(NSString *)key; + +/** + Remove items with an array of keys. + + @param keys An array of specified keys. + + @return Whether succeed. + */ +- (BOOL)removeItemForKeys:(NSArray *)keys; + +/** + Remove all items which `value` is larger than a specified size. + + @param size The maximum size in bytes. + @return Whether succeed. + */ +- (BOOL)removeItemsLargerThanSize:(int)size; + +/** + Remove all items which last access time is earlier than a specified timestamp. + + @param time The specified unix timestamp. + @return Whether succeed. + */ +- (BOOL)removeItemsEarlierThanTime:(int)time; + +/** + Remove items to make the total size not larger than a specified size. + The least recently used (LRU) items will be removed first. + + @param maxSize The specified size in bytes. + @return Whether succeed. + */ +- (BOOL)removeItemsToFitSize:(int)maxSize; + +/** + Remove items to make the total count not larger than a specified count. + The least recently used (LRU) items will be removed first. + + @param maxCount The specified item count. + @return Whether succeed. + */ +- (BOOL)removeItemsToFitCount:(int)maxCount; + +/** + Remove all items in background queue. + + @discussion This method will remove the files and sqlite database to a trash + folder, and then clear the folder in background queue. So this method is much + faster than `removeAllItemsWithProgressBlock:endBlock:`. + + @return Whether succeed. + */ +- (BOOL)removeAllItems; + +/** + Remove all items. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllItemsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + + +#pragma mark - Get Items +///============================================================================= +/// @name Get Items +///============================================================================= + +/** + Get item with a specified key. + + @param key A specified key. + @return Item for the key, or nil if not exists / error occurs. + */ +- (nullable YYKVStorageItem *)getItemForKey:(NSString *)key; + +/** + Get item information with a specified key. + The `value` in this item will be ignored. + + @param key A specified key. + @return Item information for the key, or nil if not exists / error occurs. + */ +- (nullable YYKVStorageItem *)getItemInfoForKey:(NSString *)key; + +/** + Get item value with a specified key. + + @param key A specified key. + @return Item's value, or nil if not exists / error occurs. + */ +- (nullable NSData *)getItemValueForKey:(NSString *)key; + +/** + Get items with an array of keys. + + @param keys An array of specified keys. + @return An array of `YYKVStorageItem`, or nil if not exists / error occurs. + */ +- (nullable NSArray *)getItemForKeys:(NSArray *)keys; + +/** + Get item infomartions with an array of keys. + The `value` in items will be ignored. + + @param keys An array of specified keys. + @return An array of `YYKVStorageItem`, or nil if not exists / error occurs. + */ +- (nullable NSArray *)getItemInfoForKeys:(NSArray *)keys; + +/** + Get items value with an array of keys. + + @param keys An array of specified keys. + @return A dictionary which key is 'key' and value is 'value', or nil if not + exists / error occurs. + */ +- (nullable NSDictionary *)getItemValueForKeys:(NSArray *)keys; + +#pragma mark - Get Storage Status +///============================================================================= +/// @name Get Storage Status +///============================================================================= + +/** + Whether an item exists for a specified key. + + @param key A specified key. + + @return `YES` if there's an item exists for the key, `NO` if not exists or an error occurs. + */ +- (BOOL)itemExistsForKey:(NSString *)key; + +/** + Get total item count. + @return Total item count, -1 when an error occurs. + */ +- (int)getItemsCount; + +/** + Get item value's total size in bytes. + @return Total size in bytes, -1 when an error occurs. + */ +- (int)getItemsSize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.m new file mode 100755 index 0000000..501dfdd --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYKVStorage.m @@ -0,0 +1,1069 @@ +// +// YYKVStorage.m +// YYCache +// +// Created by ibireme on 15/4/22. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYKVStorage.h" +#import +#import + +#if __has_include() +#import +#else +#import "sqlite3.h" +#endif + + +static const NSUInteger kMaxErrorRetryCount = 8; +static const NSTimeInterval kMinRetryTimeInterval = 2.0; +static const int kPathLengthMax = PATH_MAX - 64; +static NSString *const kDBFileName = @"manifest.sqlite"; +static NSString *const kDBShmFileName = @"manifest.sqlite-shm"; +static NSString *const kDBWalFileName = @"manifest.sqlite-wal"; +static NSString *const kDataDirectoryName = @"data"; +static NSString *const kTrashDirectoryName = @"trash"; + + +/* + File: + /path/ + /manifest.sqlite + /manifest.sqlite-shm + /manifest.sqlite-wal + /data/ + /e10adc3949ba59abbe56e057f20f883e + /e10adc3949ba59abbe56e057f20f883e + /trash/ + /unused_file_or_folder + + SQL: + create table if not exists manifest ( + key text, + filename text, + size integer, + inline_data blob, + modification_time integer, + last_access_time integer, + extended_data blob, + primary key(key) + ); + create index if not exists last_access_time_idx on manifest(last_access_time); + */ + +/// Returns nil in App Extension. +static UIApplication *_YYSharedApplication() { + static BOOL isAppExtension = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class cls = NSClassFromString(@"UIApplication"); + if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES; + if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES; + }); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)]; +#pragma clang diagnostic pop +} + + +@implementation YYKVStorageItem +@end + +@implementation YYKVStorage { + dispatch_queue_t _trashQueue; + + NSString *_path; + NSString *_dbPath; + NSString *_dataPath; + NSString *_trashPath; + + sqlite3 *_db; + CFMutableDictionaryRef _dbStmtCache; + NSTimeInterval _dbLastOpenErrorTime; + NSUInteger _dbOpenErrorCount; +} + + +#pragma mark - db + +- (BOOL)_dbOpen { + if (_db) return YES; + + int result = sqlite3_open(_dbPath.UTF8String, &_db); + if (result == SQLITE_OK) { + CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks; + CFDictionaryValueCallBacks valueCallbacks = {0}; + _dbStmtCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &keyCallbacks, &valueCallbacks); + _dbLastOpenErrorTime = 0; + _dbOpenErrorCount = 0; + return YES; + } else { + _db = NULL; + if (_dbStmtCache) CFRelease(_dbStmtCache); + _dbStmtCache = NULL; + _dbLastOpenErrorTime = CACurrentMediaTime(); + _dbOpenErrorCount++; + + if (_errorLogsEnabled) { + NSLog(@"%s line:%d sqlite open failed (%d).", __FUNCTION__, __LINE__, result); + } + return NO; + } +} + +- (BOOL)_dbClose { + if (!_db) return YES; + + int result = 0; + BOOL retry = NO; + BOOL stmtFinalized = NO; + + if (_dbStmtCache) CFRelease(_dbStmtCache); + _dbStmtCache = NULL; + + do { + retry = NO; + result = sqlite3_close(_db); + if (result == SQLITE_BUSY || result == SQLITE_LOCKED) { + if (!stmtFinalized) { + stmtFinalized = YES; + sqlite3_stmt *stmt; + while ((stmt = sqlite3_next_stmt(_db, nil)) != 0) { + sqlite3_finalize(stmt); + retry = YES; + } + } + } else if (result != SQLITE_OK) { + if (_errorLogsEnabled) { + NSLog(@"%s line:%d sqlite close failed (%d).", __FUNCTION__, __LINE__, result); + } + } + } while (retry); + _db = NULL; + return YES; +} + +- (BOOL)_dbCheck { + if (!_db) { + if (_dbOpenErrorCount < kMaxErrorRetryCount && + CACurrentMediaTime() - _dbLastOpenErrorTime > kMinRetryTimeInterval) { + return [self _dbOpen] && [self _dbInitialize]; + } else { + return NO; + } + } + return YES; +} + +- (BOOL)_dbInitialize { + NSString *sql = @"pragma journal_mode = wal; pragma synchronous = normal; create table if not exists manifest (key text, filename text, size integer, inline_data blob, modification_time integer, last_access_time integer, extended_data blob, primary key(key)); create index if not exists last_access_time_idx on manifest(last_access_time);"; + return [self _dbExecute:sql]; +} + +- (void)_dbCheckpoint { + if (![self _dbCheck]) return; + // Cause a checkpoint to occur, merge `sqlite-wal` file to `sqlite` file. + sqlite3_wal_checkpoint(_db, NULL); +} + +- (BOOL)_dbExecute:(NSString *)sql { + if (sql.length == 0) return NO; + if (![self _dbCheck]) return NO; + + char *error = NULL; + int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &error); + if (error) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite exec error (%d): %s", __FUNCTION__, __LINE__, result, error); + sqlite3_free(error); + } + + return result == SQLITE_OK; +} + +- (sqlite3_stmt *)_dbPrepareStmt:(NSString *)sql { + if (![self _dbCheck] || sql.length == 0 || !_dbStmtCache) return NULL; + sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue(_dbStmtCache, (__bridge const void *)(sql)); + if (!stmt) { + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NULL; + } + CFDictionarySetValue(_dbStmtCache, (__bridge const void *)(sql), stmt); + } else { + sqlite3_reset(stmt); + } + return stmt; +} + +- (NSString *)_dbJoinedKeys:(NSArray *)keys { + NSMutableString *string = [NSMutableString new]; + for (NSUInteger i = 0,max = keys.count; i < max; i++) { + [string appendString:@"?"]; + if (i + 1 != max) { + [string appendString:@","]; + } + } + return string; +} + +- (void)_dbBindJoinedKeys:(NSArray *)keys stmt:(sqlite3_stmt *)stmt fromIndex:(int)index{ + for (int i = 0, max = (int)keys.count; i < max; i++) { + NSString *key = keys[i]; + sqlite3_bind_text(stmt, index + i, key.UTF8String, -1, NULL); + } +} + +- (BOOL)_dbSaveWithKey:(NSString *)key value:(NSData *)value fileName:(NSString *)fileName extendedData:(NSData *)extendedData { + NSString *sql = @"insert or replace into manifest (key, filename, size, inline_data, modification_time, last_access_time, extended_data) values (?1, ?2, ?3, ?4, ?5, ?6, ?7);"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + + int timestamp = (int)time(NULL); + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + sqlite3_bind_text(stmt, 2, fileName.UTF8String, -1, NULL); + sqlite3_bind_int(stmt, 3, (int)value.length); + if (fileName.length == 0) { + sqlite3_bind_blob(stmt, 4, value.bytes, (int)value.length, 0); + } else { + sqlite3_bind_blob(stmt, 4, NULL, 0, 0); + } + sqlite3_bind_int(stmt, 5, timestamp); + sqlite3_bind_int(stmt, 6, timestamp); + sqlite3_bind_blob(stmt, 7, extendedData.bytes, (int)extendedData.length, 0); + + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite insert error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbUpdateAccessTimeWithKey:(NSString *)key { + NSString *sql = @"update manifest set last_access_time = ?1 where key = ?2;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, (int)time(NULL)); + sqlite3_bind_text(stmt, 2, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite update error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbUpdateAccessTimeWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return NO; + int t = (int)time(NULL); + NSString *sql = [NSString stringWithFormat:@"update manifest set last_access_time = %d where key in (%@);", t, [self _dbJoinedKeys:keys]]; + + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + result = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite update error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemWithKey:(NSString *)key { + NSString *sql = @"delete from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d db delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return NO; + NSString *sql = [NSString stringWithFormat:@"delete from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + result = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (result == SQLITE_ERROR) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemsWithSizeLargerThan:(int)size { + NSString *sql = @"delete from manifest where size > ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, size); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemsWithTimeEarlierThan:(int)time { + NSString *sql = @"delete from manifest where last_access_time < ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, time); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (YYKVStorageItem *)_dbGetItemFromStmt:(sqlite3_stmt *)stmt excludeInlineData:(BOOL)excludeInlineData { + int i = 0; + char *key = (char *)sqlite3_column_text(stmt, i++); + char *filename = (char *)sqlite3_column_text(stmt, i++); + int size = sqlite3_column_int(stmt, i++); + const void *inline_data = excludeInlineData ? NULL : sqlite3_column_blob(stmt, i); + int inline_data_bytes = excludeInlineData ? 0 : sqlite3_column_bytes(stmt, i++); + int modification_time = sqlite3_column_int(stmt, i++); + int last_access_time = sqlite3_column_int(stmt, i++); + const void *extended_data = sqlite3_column_blob(stmt, i); + int extended_data_bytes = sqlite3_column_bytes(stmt, i++); + + YYKVStorageItem *item = [YYKVStorageItem new]; + if (key) item.key = [NSString stringWithUTF8String:key]; + if (filename && *filename != 0) item.filename = [NSString stringWithUTF8String:filename]; + item.size = size; + if (inline_data_bytes > 0 && inline_data) item.value = [NSData dataWithBytes:inline_data length:inline_data_bytes]; + item.modTime = modification_time; + item.accessTime = last_access_time; + if (extended_data_bytes > 0 && extended_data) item.extendedData = [NSData dataWithBytes:extended_data length:extended_data_bytes]; + return item; +} + +- (YYKVStorageItem *)_dbGetItemWithKey:(NSString *)key excludeInlineData:(BOOL)excludeInlineData { + NSString *sql = excludeInlineData ? @"select key, filename, size, modification_time, last_access_time, extended_data from manifest where key = ?1;" : @"select key, filename, size, inline_data, modification_time, last_access_time, extended_data from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + YYKVStorageItem *item = nil; + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + item = [self _dbGetItemFromStmt:stmt excludeInlineData:excludeInlineData]; + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + } + return item; +} + +- (NSMutableArray *)_dbGetItemWithKeys:(NSArray *)keys excludeInlineData:(BOOL)excludeInlineData { + if (![self _dbCheck]) return nil; + NSString *sql; + if (excludeInlineData) { + sql = [NSString stringWithFormat:@"select key, filename, size, modification_time, last_access_time, extended_data from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + } else { + sql = [NSString stringWithFormat:@"select key, filename, size, inline_data, modification_time, last_access_time, extended_data from manifest where key in (%@)", [self _dbJoinedKeys:keys]]; + } + + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return nil; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + NSMutableArray *items = [NSMutableArray new]; + do { + result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + YYKVStorageItem *item = [self _dbGetItemFromStmt:stmt excludeInlineData:excludeInlineData]; + if (item) [items addObject:item]; + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + items = nil; + break; + } + } while (1); + sqlite3_finalize(stmt); + return items; +} + +- (NSData *)_dbGetValueWithKey:(NSString *)key { + NSString *sql = @"select inline_data from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + const void *inline_data = sqlite3_column_blob(stmt, 0); + int inline_data_bytes = sqlite3_column_bytes(stmt, 0); + if (!inline_data || inline_data_bytes <= 0) return nil; + return [NSData dataWithBytes:inline_data length:inline_data_bytes]; + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + return nil; + } +} + +- (NSString *)_dbGetFilenameWithKey:(NSString *)key { + NSString *sql = @"select filename from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + return [NSString stringWithUTF8String:filename]; + } + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + } + return nil; +} + +- (NSMutableArray *)_dbGetFilenameWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return nil; + NSString *sql = [NSString stringWithFormat:@"select filename from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return nil; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + NSMutableArray *filenames = [NSMutableArray new]; + do { + result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + sqlite3_finalize(stmt); + return filenames; +} + +- (NSMutableArray *)_dbGetFilenamesWithSizeLargerThan:(int)size { + NSString *sql = @"select filename from manifest where size > ?1 and filename is not null;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, size); + + NSMutableArray *filenames = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + return filenames; +} + +- (NSMutableArray *)_dbGetFilenamesWithTimeEarlierThan:(int)time { + NSString *sql = @"select filename from manifest where last_access_time < ?1 and filename is not null;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, time); + + NSMutableArray *filenames = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + return filenames; +} + +- (NSMutableArray *)_dbGetItemSizeInfoOrderByTimeAscWithLimit:(int)count { + NSString *sql = @"select key, filename, size from manifest order by last_access_time asc limit ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, count); + + NSMutableArray *items = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *key = (char *)sqlite3_column_text(stmt, 0); + char *filename = (char *)sqlite3_column_text(stmt, 1); + int size = sqlite3_column_int(stmt, 2); + NSString *keyStr = key ? [NSString stringWithUTF8String:key] : nil; + if (keyStr) { + YYKVStorageItem *item = [YYKVStorageItem new]; + item.key = key ? [NSString stringWithUTF8String:key] : nil; + item.filename = filename ? [NSString stringWithUTF8String:filename] : nil; + item.size = size; + [items addObject:item]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + items = nil; + break; + } + } while (1); + return items; +} + +- (int)_dbGetItemCountWithKey:(NSString *)key { + NSString *sql = @"select count(key) from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + +- (int)_dbGetTotalItemSize { + NSString *sql = @"select sum(size) from manifest;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + +- (int)_dbGetTotalItemCount { + NSString *sql = @"select count(*) from manifest;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + + +#pragma mark - file + +- (BOOL)_fileWriteWithName:(NSString *)filename data:(NSData *)data { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + return [data writeToFile:path atomically:NO]; +} + +- (NSData *)_fileReadWithName:(NSString *)filename { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + NSData *data = [NSData dataWithContentsOfFile:path]; + return data; +} + +- (BOOL)_fileDeleteWithName:(NSString *)filename { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + return [[NSFileManager defaultManager] removeItemAtPath:path error:NULL]; +} + +- (BOOL)_fileMoveAllToTrash { + CFUUIDRef uuidRef = CFUUIDCreate(NULL); + CFStringRef uuid = CFUUIDCreateString(NULL, uuidRef); + CFRelease(uuidRef); + NSString *tmpPath = [_trashPath stringByAppendingPathComponent:(__bridge NSString *)(uuid)]; + BOOL suc = [[NSFileManager defaultManager] moveItemAtPath:_dataPath toPath:tmpPath error:nil]; + if (suc) { + suc = [[NSFileManager defaultManager] createDirectoryAtPath:_dataPath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + CFRelease(uuid); + return suc; +} + +- (void)_fileEmptyTrashInBackground { + NSString *trashPath = _trashPath; + dispatch_queue_t queue = _trashQueue; + dispatch_async(queue, ^{ + NSFileManager *manager = [NSFileManager new]; + NSArray *directoryContents = [manager contentsOfDirectoryAtPath:trashPath error:NULL]; + for (NSString *path in directoryContents) { + NSString *fullPath = [trashPath stringByAppendingPathComponent:path]; + [manager removeItemAtPath:fullPath error:NULL]; + } + }); +} + + +#pragma mark - private + +/** + Delete all files and empty in background. + Make sure the db is closed. + */ +- (void)_reset { + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBFileName] error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBShmFileName] error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBWalFileName] error:nil]; + [self _fileMoveAllToTrash]; + [self _fileEmptyTrashInBackground]; +} + +#pragma mark - public + +- (instancetype)init { + @throw [NSException exceptionWithName:@"YYKVStorage init error" reason:@"Please use the designated initializer and pass the 'path' and 'type'." userInfo:nil]; + return [self initWithPath:@"" type:YYKVStorageTypeFile]; +} + +- (instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type { + if (path.length == 0 || path.length > kPathLengthMax) { + NSLog(@"YYKVStorage init error: invalid path: [%@].", path); + return nil; + } + if (type > YYKVStorageTypeMixed) { + NSLog(@"YYKVStorage init error: invalid type: %lu.", (unsigned long)type); + return nil; + } + + self = [super init]; + _path = path.copy; + _type = type; + _dataPath = [path stringByAppendingPathComponent:kDataDirectoryName]; + _trashPath = [path stringByAppendingPathComponent:kTrashDirectoryName]; + _trashQueue = dispatch_queue_create("com.ibireme.cache.disk.trash", DISPATCH_QUEUE_SERIAL); + _dbPath = [path stringByAppendingPathComponent:kDBFileName]; + _errorLogsEnabled = YES; + NSError *error = nil; + if (![[NSFileManager defaultManager] createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:&error] || + ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kDataDirectoryName] + withIntermediateDirectories:YES + attributes:nil + error:&error] || + ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kTrashDirectoryName] + withIntermediateDirectories:YES + attributes:nil + error:&error]) { + NSLog(@"YYKVStorage init error:%@", error); + return nil; + } + + if (![self _dbOpen] || ![self _dbInitialize]) { + // db file may broken... + [self _dbClose]; + [self _reset]; // rebuild + if (![self _dbOpen] || ![self _dbInitialize]) { + [self _dbClose]; + NSLog(@"YYKVStorage init error: fail to open sqlite db."); + return nil; + } + } + [self _fileEmptyTrashInBackground]; // empty the trash if failed at last time + return self; +} + +- (void)dealloc { + UIBackgroundTaskIdentifier taskID = [_YYSharedApplication() beginBackgroundTaskWithExpirationHandler:^{}]; + [self _dbClose]; + if (taskID != UIBackgroundTaskInvalid) { + [_YYSharedApplication() endBackgroundTask:taskID]; + } +} + +- (BOOL)saveItem:(YYKVStorageItem *)item { + return [self saveItemWithKey:item.key value:item.value filename:item.filename extendedData:item.extendedData]; +} + +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value { + return [self saveItemWithKey:key value:value filename:nil extendedData:nil]; +} + +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value filename:(NSString *)filename extendedData:(NSData *)extendedData { + if (key.length == 0 || value.length == 0) return NO; + if (_type == YYKVStorageTypeFile && filename.length == 0) { + return NO; + } + + if (filename.length) { + if (![self _fileWriteWithName:filename data:value]) { + return NO; + } + if (![self _dbSaveWithKey:key value:value fileName:filename extendedData:extendedData]) { + [self _fileDeleteWithName:filename]; + return NO; + } + return YES; + } else { + if (_type != YYKVStorageTypeSQLite) { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + [self _fileDeleteWithName:filename]; + } + } + return [self _dbSaveWithKey:key value:value fileName:nil extendedData:extendedData]; + } +} + +- (BOOL)removeItemForKey:(NSString *)key { + if (key.length == 0) return NO; + switch (_type) { + case YYKVStorageTypeSQLite: { + return [self _dbDeleteItemWithKey:key]; + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + [self _fileDeleteWithName:filename]; + } + return [self _dbDeleteItemWithKey:key]; + } break; + default: return NO; + } +} + +- (BOOL)removeItemForKeys:(NSArray *)keys { + if (keys.count == 0) return NO; + switch (_type) { + case YYKVStorageTypeSQLite: { + return [self _dbDeleteItemWithKeys:keys]; + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenameWithKeys:keys]; + for (NSString *filename in filenames) { + [self _fileDeleteWithName:filename]; + } + return [self _dbDeleteItemWithKeys:keys]; + } break; + default: return NO; + } +} + +- (BOOL)removeItemsLargerThanSize:(int)size { + if (size == INT_MAX) return YES; + if (size <= 0) return [self removeAllItems]; + + switch (_type) { + case YYKVStorageTypeSQLite: { + if ([self _dbDeleteItemsWithSizeLargerThan:size]) { + [self _dbCheckpoint]; + return YES; + } + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenamesWithSizeLargerThan:size]; + for (NSString *name in filenames) { + [self _fileDeleteWithName:name]; + } + if ([self _dbDeleteItemsWithSizeLargerThan:size]) { + [self _dbCheckpoint]; + return YES; + } + } break; + } + return NO; +} + +- (BOOL)removeItemsEarlierThanTime:(int)time { + if (time <= 0) return YES; + if (time == INT_MAX) return [self removeAllItems]; + + switch (_type) { + case YYKVStorageTypeSQLite: { + if ([self _dbDeleteItemsWithTimeEarlierThan:time]) { + [self _dbCheckpoint]; + return YES; + } + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenamesWithTimeEarlierThan:time]; + for (NSString *name in filenames) { + [self _fileDeleteWithName:name]; + } + if ([self _dbDeleteItemsWithTimeEarlierThan:time]) { + [self _dbCheckpoint]; + return YES; + } + } break; + } + return NO; +} + +- (BOOL)removeItemsToFitSize:(int)maxSize { + if (maxSize == INT_MAX) return YES; + if (maxSize <= 0) return [self removeAllItems]; + + int total = [self _dbGetTotalItemSize]; + if (total < 0) return NO; + if (total <= maxSize) return YES; + + NSArray *items = nil; + BOOL suc = NO; + do { + int perCount = 16; + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (total > maxSize) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + total -= item.size; + } else { + break; + } + if (!suc) break; + } + } while (total > maxSize && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + return suc; +} + +- (BOOL)removeItemsToFitCount:(int)maxCount { + if (maxCount == INT_MAX) return YES; + if (maxCount <= 0) return [self removeAllItems]; + + int total = [self _dbGetTotalItemCount]; + if (total < 0) return NO; + if (total <= maxCount) return YES; + + NSArray *items = nil; + BOOL suc = NO; + do { + int perCount = 16; + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (total > maxCount) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + total--; + } else { + break; + } + if (!suc) break; + } + } while (total > maxCount && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + return suc; +} + +- (BOOL)removeAllItems { + if (![self _dbClose]) return NO; + [self _reset]; + if (![self _dbOpen]) return NO; + if (![self _dbInitialize]) return NO; + return YES; +} + +- (void)removeAllItemsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + + int total = [self _dbGetTotalItemCount]; + if (total <= 0) { + if (end) end(total < 0); + } else { + int left = total; + int perCount = 32; + NSArray *items = nil; + BOOL suc = NO; + do { + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (left > 0) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + left--; + } else { + break; + } + if (!suc) break; + } + if (progress) progress(total - left, total); + } while (left > 0 && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + if (end) end(!suc); + } +} + +- (YYKVStorageItem *)getItemForKey:(NSString *)key { + if (key.length == 0) return nil; + YYKVStorageItem *item = [self _dbGetItemWithKey:key excludeInlineData:NO]; + if (item) { + [self _dbUpdateAccessTimeWithKey:key]; + if (item.filename) { + item.value = [self _fileReadWithName:item.filename]; + if (!item.value) { + [self _dbDeleteItemWithKey:key]; + item = nil; + } + } + } + return item; +} + +- (YYKVStorageItem *)getItemInfoForKey:(NSString *)key { + if (key.length == 0) return nil; + YYKVStorageItem *item = [self _dbGetItemWithKey:key excludeInlineData:YES]; + return item; +} + +- (NSData *)getItemValueForKey:(NSString *)key { + if (key.length == 0) return nil; + NSData *value = nil; + switch (_type) { + case YYKVStorageTypeFile: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + value = [self _fileReadWithName:filename]; + if (!value) { + [self _dbDeleteItemWithKey:key]; + value = nil; + } + } + } break; + case YYKVStorageTypeSQLite: { + value = [self _dbGetValueWithKey:key]; + } break; + case YYKVStorageTypeMixed: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + value = [self _fileReadWithName:filename]; + if (!value) { + [self _dbDeleteItemWithKey:key]; + value = nil; + } + } else { + value = [self _dbGetValueWithKey:key]; + } + } break; + } + if (value) { + [self _dbUpdateAccessTimeWithKey:key]; + } + return value; +} + +- (NSArray *)getItemForKeys:(NSArray *)keys { + if (keys.count == 0) return nil; + NSMutableArray *items = [self _dbGetItemWithKeys:keys excludeInlineData:NO]; + if (_type != YYKVStorageTypeSQLite) { + for (NSInteger i = 0, max = items.count; i < max; i++) { + YYKVStorageItem *item = items[i]; + if (item.filename) { + item.value = [self _fileReadWithName:item.filename]; + if (!item.value) { + if (item.key) [self _dbDeleteItemWithKey:item.key]; + [items removeObjectAtIndex:i]; + i--; + max--; + } + } + } + } + if (items.count > 0) { + [self _dbUpdateAccessTimeWithKeys:keys]; + } + return items.count ? items : nil; +} + +- (NSArray *)getItemInfoForKeys:(NSArray *)keys { + if (keys.count == 0) return nil; + return [self _dbGetItemWithKeys:keys excludeInlineData:YES]; +} + +- (NSDictionary *)getItemValueForKeys:(NSArray *)keys { + NSMutableArray *items = (NSMutableArray *)[self getItemForKeys:keys]; + NSMutableDictionary *kv = [NSMutableDictionary new]; + for (YYKVStorageItem *item in items) { + if (item.key && item.value) { + [kv setObject:item.value forKey:item.key]; + } + } + return kv.count ? kv : nil; +} + +- (BOOL)itemExistsForKey:(NSString *)key { + if (key.length == 0) return NO; + return [self _dbGetItemCountWithKey:key] > 0; +} + +- (int)getItemsCount { + return [self _dbGetTotalItemCount]; +} + +- (int)getItemsSize { + return [self _dbGetTotalItemSize]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.h b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.h new file mode 100755 index 0000000..ded8440 --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.h @@ -0,0 +1,213 @@ +// +// YYMemoryCache.h +// YYCache +// +// Created by ibireme on 15/2/7. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYMemoryCache is a fast in-memory cache that stores key-value pairs. + In contrast to NSDictionary, keys are retained and not copied. + The API and performance is similar to `NSCache`, all methods are thread-safe. + + YYMemoryCache objects differ from NSCache in a few ways: + + * It uses LRU (least-recently-used) to remove objects; NSCache's eviction method + is non-deterministic. + * It can be controlled by cost, count and age; NSCache's limits are imprecise. + * It can be configured to automatically evict objects when receive memory + warning or app enter background. + + The time of `Access Methods` in YYMemoryCache is typically in constant time (O(1)). + */ +@interface YYMemoryCache : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +/** The name of the cache. Default is nil. */ +@property (nullable, copy) NSString *name; + +/** The number of objects in the cache (read-only) */ +@property (readonly) NSUInteger totalCount; + +/** The total cost of objects in the cache (read-only). */ +@property (readonly) NSUInteger totalCost; + + +#pragma mark - Limit +///============================================================================= +/// @name Limit +///============================================================================= + +/** + The maximum number of objects the cache should hold. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit—if the cache goes over the limit, some objects in the + cache could be evicted later in backgound thread. + */ +@property NSUInteger countLimit; + +/** + The maximum total cost that the cache can hold before it starts evicting objects. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit—if the cache goes over the limit, some objects in the + cache could be evicted later in backgound thread. + */ +@property NSUInteger costLimit; + +/** + The maximum expiry time of objects in cache. + + @discussion The default value is DBL_MAX, which means no limit. + This is not a strict limit—if an object goes over the limit, the object could + be evicted later in backgound thread. + */ +@property NSTimeInterval ageLimit; + +/** + The auto trim check time interval in seconds. Default is 5.0. + + @discussion The cache holds an internal timer to check whether the cache reaches + its limits, and if the limit is reached, it begins to evict objects. + */ +@property NSTimeInterval autoTrimInterval; + +/** + If `YES`, the cache will remove all objects when the app receives a memory warning. + The default value is `YES`. + */ +@property BOOL shouldRemoveAllObjectsOnMemoryWarning; + +/** + If `YES`, The cache will remove all objects when the app enter background. + The default value is `YES`. + */ +@property BOOL shouldRemoveAllObjectsWhenEnteringBackground; + +/** + A block to be executed when the app receives a memory warning. + The default value is nil. + */ +@property (nullable, copy) void(^didReceiveMemoryWarningBlock)(YYMemoryCache *cache); + +/** + A block to be executed when the app enter background. + The default value is nil. + */ +@property (nullable, copy) void(^didEnterBackgroundBlock)(YYMemoryCache *cache); + +/** + If `YES`, the key-value pair will be released on main thread, otherwise on + background thread. Default is NO. + + @discussion You may set this value to `YES` if the key-value object contains + the instance which should be released in main thread (such as UIView/CALayer). + */ +@property BOOL releaseOnMainThread; + +/** + If `YES`, the key-value pair will be released asynchronously to avoid blocking + the access methods, otherwise it will be released in the access method + (such as removeObjectForKey:). Default is YES. + */ +@property BOOL releaseAsynchronously; + + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + Returns a Boolean value that indicates whether a given key is in cache. + + @param key An object identifying the value. If nil, just return `NO`. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(id)key; + +/** + Returns the value associated with a given key. + + @param key An object identifying the value. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable id)objectForKey:(id)key; + +/** + Sets the value of the specified key in the cache (0 cost). + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param key The key with which to associate the value. If nil, this method has no effect. + @discussion Unlike an NSMutableDictionary object, a cache does not copy the key + objects that are put into it. + */ +- (void)setObject:(nullable id)object forKey:(id)key; + +/** + Sets the value of the specified key in the cache, and associates the key-value + pair with the specified cost. + + @param object The object to store in the cache. If nil, it calls `removeObjectForKey`. + @param key The key with which to associate the value. If nil, this method has no effect. + @param cost The cost with which to associate the key-value pair. + @discussion Unlike an NSMutableDictionary object, a cache does not copy the key + objects that are put into it. + */ +- (void)setObject:(nullable id)object forKey:(id)key withCost:(NSUInteger)cost; + +/** + Removes the value of the specified key in the cache. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + */ +- (void)removeObjectForKey:(id)key; + +/** + Empties the cache immediately. + */ +- (void)removeAllObjects; + + +#pragma mark - Trim +///============================================================================= +/// @name Trim +///============================================================================= + +/** + Removes objects from the cache with LRU, until the `totalCount` is below or equal to + the specified value. + @param count The total count allowed to remain after the cache has been trimmed. + */ +- (void)trimToCount:(NSUInteger)count; + +/** + Removes objects from the cache with LRU, until the `totalCost` is or equal to + the specified value. + @param cost The total cost allowed to remain after the cache has been trimmed. + */ +- (void)trimToCost:(NSUInteger)cost; + +/** + Removes objects from the cache with LRU, until all expiry objects removed by the + specified value. + @param age The maximum age (in seconds) of objects. + */ +- (void)trimToAge:(NSTimeInterval)age; + +@end + +NS_ASSUME_NONNULL_END diff --git a/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.m b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.m new file mode 100755 index 0000000..9042d9b --- /dev/null +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaCoreTool/YYCache/YYMemoryCache.m @@ -0,0 +1,505 @@ +// +// YYMemoryCache.m +// YYCache +// +// Created by ibireme on 15/2/7. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYMemoryCache.h" +#import +#import +#import +#import + + +static inline dispatch_queue_t YYMemoryCacheGetReleaseQueue() { + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); +} + +/** + A node in linked map. + Typically, you should not use this class directly. + */ +@interface _YYLinkedMapNode : NSObject { + @package + __unsafe_unretained _YYLinkedMapNode *_prev; // retained by dic + __unsafe_unretained _YYLinkedMapNode *_next; // retained by dic + id _key; + id _value; + NSUInteger _cost; + NSTimeInterval _time; +} +@end + +@implementation _YYLinkedMapNode +@end + + +/** + A linked map used by YYMemoryCache. + It's not thread-safe and does not validate the parameters. + + Typically, you should not use this class directly. + */ +@interface _YYLinkedMap : NSObject { + @package + CFMutableDictionaryRef _dic; // do not set object directly + NSUInteger _totalCost; + NSUInteger _totalCount; + _YYLinkedMapNode *_head; // MRU, do not change it directly + _YYLinkedMapNode *_tail; // LRU, do not change it directly + BOOL _releaseOnMainThread; + BOOL _releaseAsynchronously; +} + +/// Insert a node at head and update the total cost. +/// Node and node.key should not be nil. +- (void)insertNodeAtHead:(_YYLinkedMapNode *)node; + +/// Bring a inner node to header. +/// Node should already inside the dic. +- (void)bringNodeToHead:(_YYLinkedMapNode *)node; + +/// Remove a inner node and update the total cost. +/// Node should already inside the dic. +- (void)removeNode:(_YYLinkedMapNode *)node; + +/// Remove tail node if exist. +- (_YYLinkedMapNode *)removeTailNode; + +/// Remove all node in background queue. +- (void)removeAll; + +@end + +@implementation _YYLinkedMap + +- (instancetype)init { + self = [super init]; + _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + _releaseOnMainThread = NO; + _releaseAsynchronously = YES; + return self; +} + +- (void)dealloc { + CFRelease(_dic); +} + +- (void)insertNodeAtHead:(_YYLinkedMapNode *)node { + CFDictionarySetValue(_dic, (__bridge const void *)(node->_key), (__bridge const void *)(node)); + _totalCost += node->_cost; + _totalCount++; + if (_head) { + node->_next = _head; + _head->_prev = node; + _head = node; + } else { + _head = _tail = node; + } +} + +- (void)bringNodeToHead:(_YYLinkedMapNode *)node { + if (_head == node) return; + + if (_tail == node) { + _tail = node->_prev; + _tail->_next = nil; + } else { + node->_next->_prev = node->_prev; + node->_prev->_next = node->_next; + } + node->_next = _head; + node->_prev = nil; + _head->_prev = node; + _head = node; +} + +- (void)removeNode:(_YYLinkedMapNode *)node { + CFDictionaryRemoveValue(_dic, (__bridge const void *)(node->_key)); + _totalCost -= node->_cost; + _totalCount--; + if (node->_next) node->_next->_prev = node->_prev; + if (node->_prev) node->_prev->_next = node->_next; + if (_head == node) _head = node->_next; + if (_tail == node) _tail = node->_prev; +} + +- (_YYLinkedMapNode *)removeTailNode { + if (!_tail) return nil; + _YYLinkedMapNode *tail = _tail; + CFDictionaryRemoveValue(_dic, (__bridge const void *)(_tail->_key)); + _totalCost -= _tail->_cost; + _totalCount--; + if (_head == _tail) { + _head = _tail = nil; + } else { + _tail = _tail->_prev; + _tail->_next = nil; + } + return tail; +} + +- (void)removeAll { + _totalCost = 0; + _totalCount = 0; + _head = nil; + _tail = nil; + if (CFDictionaryGetCount(_dic) > 0) { + CFMutableDictionaryRef holder = _dic; + _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + if (_releaseAsynchronously) { + dispatch_queue_t queue = _releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + CFRelease(holder); // hold and release in specified queue + }); + } else if (_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + CFRelease(holder); // hold and release in specified queue + }); + } else { + CFRelease(holder); + } + } +} + +@end + + + +@implementation YYMemoryCache { + pthread_mutex_t _lock; + _YYLinkedMap *_lru; + dispatch_queue_t _queue; +} + +- (void)_trimRecursively { + __weak typeof(self) _self = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_autoTrimInterval * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + __strong typeof(_self) self = _self; + if (!self) return; + [self _trimInBackground]; + [self _trimRecursively]; + }); +} + +- (void)_trimInBackground { + dispatch_async(_queue, ^{ + [self _trimToCost:self->_costLimit]; + [self _trimToCount:self->_countLimit]; + [self _trimToAge:self->_ageLimit]; + }); +} + +- (void)_trimToCost:(NSUInteger)costLimit { + BOOL finish = NO; + pthread_mutex_lock(&_lock); + if (costLimit == 0) { + [_lru removeAll]; + finish = YES; + } else if (_lru->_totalCost <= costLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_totalCost > costLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_trimToCount:(NSUInteger)countLimit { + BOOL finish = NO; + pthread_mutex_lock(&_lock); + if (countLimit == 0) { + [_lru removeAll]; + finish = YES; + } else if (_lru->_totalCount <= countLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_totalCount > countLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_trimToAge:(NSTimeInterval)ageLimit { + BOOL finish = NO; + NSTimeInterval now = CACurrentMediaTime(); + pthread_mutex_lock(&_lock); + if (ageLimit <= 0) { + [_lru removeAll]; + finish = YES; + } else if (!_lru->_tail || (now - _lru->_tail->_time) <= ageLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_tail && (now - _lru->_tail->_time) > ageLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_appDidReceiveMemoryWarningNotification { + if (self.didReceiveMemoryWarningBlock) { + self.didReceiveMemoryWarningBlock(self); + } + if (self.shouldRemoveAllObjectsOnMemoryWarning) { + [self removeAllObjects]; + } +} + +- (void)_appDidEnterBackgroundNotification { + if (self.didEnterBackgroundBlock) { + self.didEnterBackgroundBlock(self); + } + if (self.shouldRemoveAllObjectsWhenEnteringBackground) { + [self removeAllObjects]; + } +} + +#pragma mark - public + +- (instancetype)init { + self = super.init; + pthread_mutex_init(&_lock, NULL); + _lru = [_YYLinkedMap new]; + _queue = dispatch_queue_create("com.ibireme.cache.memory", DISPATCH_QUEUE_SERIAL); + + _countLimit = NSUIntegerMax; + _costLimit = NSUIntegerMax; + _ageLimit = DBL_MAX; + _autoTrimInterval = 5.0; + _shouldRemoveAllObjectsOnMemoryWarning = YES; + _shouldRemoveAllObjectsWhenEnteringBackground = YES; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidReceiveMemoryWarningNotification) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidEnterBackgroundNotification) name:UIApplicationDidEnterBackgroundNotification object:nil]; + + [self _trimRecursively]; + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; + [_lru removeAll]; + pthread_mutex_destroy(&_lock); +} + +- (NSUInteger)totalCount { + pthread_mutex_lock(&_lock); + NSUInteger count = _lru->_totalCount; + pthread_mutex_unlock(&_lock); + return count; +} + +- (NSUInteger)totalCost { + pthread_mutex_lock(&_lock); + NSUInteger totalCost = _lru->_totalCost; + pthread_mutex_unlock(&_lock); + return totalCost; +} + +- (BOOL)releaseOnMainThread { + pthread_mutex_lock(&_lock); + BOOL releaseOnMainThread = _lru->_releaseOnMainThread; + pthread_mutex_unlock(&_lock); + return releaseOnMainThread; +} + +- (void)setReleaseOnMainThread:(BOOL)releaseOnMainThread { + pthread_mutex_lock(&_lock); + _lru->_releaseOnMainThread = releaseOnMainThread; + pthread_mutex_unlock(&_lock); +} + +- (BOOL)releaseAsynchronously { + pthread_mutex_lock(&_lock); + BOOL releaseAsynchronously = _lru->_releaseAsynchronously; + pthread_mutex_unlock(&_lock); + return releaseAsynchronously; +} + +- (void)setReleaseAsynchronously:(BOOL)releaseAsynchronously { + pthread_mutex_lock(&_lock); + _lru->_releaseAsynchronously = releaseAsynchronously; + pthread_mutex_unlock(&_lock); +} + +- (BOOL)containsObjectForKey:(id)key { + if (!key) return NO; + pthread_mutex_lock(&_lock); + BOOL contains = CFDictionaryContainsKey(_lru->_dic, (__bridge const void *)(key)); + pthread_mutex_unlock(&_lock); + return contains; +} + +- (id)objectForKey:(id)key { + if (!key) return nil; + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + if (node) { + node->_time = CACurrentMediaTime(); + [_lru bringNodeToHead:node]; + } + pthread_mutex_unlock(&_lock); + return node ? node->_value : nil; +} + +- (void)setObject:(id)object forKey:(id)key { + [self setObject:object forKey:key withCost:0]; +} + +- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost { + if (!key) return; + if (!object) { + [self removeObjectForKey:key]; + return; + } + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + NSTimeInterval now = CACurrentMediaTime(); + if (node) { + _lru->_totalCost -= node->_cost; + _lru->_totalCost += cost; + node->_cost = cost; + node->_time = now; + node->_value = object; + [_lru bringNodeToHead:node]; + } else { + node = [_YYLinkedMapNode new]; + node->_cost = cost; + node->_time = now; + node->_key = key; + node->_value = object; + [_lru insertNodeAtHead:node]; + } + if (_lru->_totalCost > _costLimit) { + dispatch_async(_queue, ^{ + [self trimToCost:_costLimit]; + }); + } + if (_lru->_totalCount > _countLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (_lru->_releaseAsynchronously) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [node class]; //hold and release in queue + }); + } else if (_lru->_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + [node class]; //hold and release in queue + }); + } + } + pthread_mutex_unlock(&_lock); +} + +- (void)removeObjectForKey:(id)key { + if (!key) return; + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + if (node) { + [_lru removeNode:node]; + if (_lru->_releaseAsynchronously) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [node class]; //hold and release in queue + }); + } else if (_lru->_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + [node class]; //hold and release in queue + }); + } + } + pthread_mutex_unlock(&_lock); +} + +- (void)removeAllObjects { + pthread_mutex_lock(&_lock); + [_lru removeAll]; + pthread_mutex_unlock(&_lock); +} + +- (void)trimToCount:(NSUInteger)count { + if (count == 0) { + [self removeAllObjects]; + return; + } + [self _trimToCount:count]; +} + +- (void)trimToCost:(NSUInteger)cost { + [self _trimToCost:cost]; +} + +- (void)trimToAge:(NSTimeInterval)age { + [self _trimToAge:age]; +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name]; + else return [NSString stringWithFormat:@"<%@: %p>", self.class, self]; +} + +@end diff --git a/jiaModuleDemo/BaseModule/JiaMacros/JiaMacros.h b/jiaModuleDemo/BaseModule/JiaCore/JiaMacros/JiaMacros.h similarity index 97% rename from jiaModuleDemo/BaseModule/JiaMacros/JiaMacros.h rename to jiaModuleDemo/BaseModule/JiaCore/JiaMacros/JiaMacros.h index 119d0fd..07e3923 100644 --- a/jiaModuleDemo/BaseModule/JiaMacros/JiaMacros.h +++ b/jiaModuleDemo/BaseModule/JiaCore/JiaMacros/JiaMacros.h @@ -155,7 +155,7 @@ //弱引用/强引用 可配对引用在外面用MPWeakSelf(self),block用MPStrongSelf(self) 也可以单独引用在外面用MPWeakSelf(self) block里面用weakself -#define MPWeakSelf(type) __weak typeof(type) weak##type = type; -#define MPStrongSelf(type) __strong typeof(type) type = weak##type; +#define JiaCoreWeakSelf(type) __weak typeof(type) weak##type = type; +#define JiaCoreStrongSelf(type) __strong typeof(type) type = weak##type; #endif /* jiaMacros_h */ diff --git a/jiaModuleDemo/BaseModule/JiaGT/XAspect-GeTuiAppDelegate.m b/jiaModuleDemo/BaseModule/JiaGT/XAspect-GeTuiAppDelegate.m index fa8602a..78fa8db 100644 --- a/jiaModuleDemo/BaseModule/JiaGT/XAspect-GeTuiAppDelegate.m +++ b/jiaModuleDemo/BaseModule/JiaGT/XAspect-GeTuiAppDelegate.m @@ -28,6 +28,8 @@ AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) { + NSLog(@"成功加载个推模块"); + //个推初始化 [self initLoadGeTui:launchOptions]; diff --git a/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.h b/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.h index 4bbd3f8..ec7a822 100644 --- a/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.h +++ b/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.h @@ -7,7 +7,7 @@ // #import -#import "JiaBaseViewController.h" +#import "designerModulePrefixHeader.h" #import "HeaderDesignerConfig.h" @interface DesignerViewController : JiaBaseViewController diff --git a/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.m b/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.m index cb7b4d4..0712a75 100644 --- a/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.m +++ b/jiaModuleDemo/DesignerModule/Controller/DesignerViewController.m @@ -30,6 +30,8 @@ - (void)viewDidLoad { self.navigationItem.title=@"设计师模块"; NSLog(@"当前参数:%@",self.parameterDictionary); + NSLog(@"%@",[self getMessage]); + NSLog(@"%@",[self getOtherMessage]); //测试网络请求 DesignerServiceApi *serverApi=[[DesignerServiceApi alloc]init]; @@ -42,6 +44,9 @@ - (void)viewDidLoad { - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; + + UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"" message:[self getMessage] delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; + [alert show]; } - (void)viewDidAppear:(BOOL)animated { @@ -116,6 +121,7 @@ -(UILabel *)myDesignIDLabel _myDesignIDLabel.textColor=[UIColor whiteColor]; _myDesignIDLabel.text=self.parameterDictionary[kDesignerModuleActionsDictionaryKeyID]; } + return _myDesignIDLabel; } @@ -140,4 +146,15 @@ - (UIButton *)returnButton return _returnButton; } + +-(NSString *)getMessage +{ + return @"我是原来的内容"; +} + +-(NSString *)getOtherMessage +{ + return @"我是getOtherMessage的内容"; +} + @end diff --git a/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.h b/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.h new file mode 100644 index 0000000..f3db5cc --- /dev/null +++ b/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.h @@ -0,0 +1,13 @@ +// +// DesignerDetailModel.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface DesignerDetailModel : NSObject + +@end diff --git a/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.m b/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.m new file mode 100644 index 0000000..6500677 --- /dev/null +++ b/jiaModuleDemo/DesignerModule/Model/DesignerDetailModel.m @@ -0,0 +1,13 @@ +// +// DesignerDetailModel.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "DesignerDetailModel.h" + +@implementation DesignerDetailModel + +@end diff --git a/jiaModuleDemo/DesignerModule/Other/designerModulePrefixHeader.h b/jiaModuleDemo/DesignerModule/Other/designerModulePrefixHeader.h index 582d98d..222f555 100644 --- a/jiaModuleDemo/DesignerModule/Other/designerModulePrefixHeader.h +++ b/jiaModuleDemo/DesignerModule/Other/designerModulePrefixHeader.h @@ -18,5 +18,6 @@ #import "MBProgressHUD.h" #import "MBProgressHUD+MP.h" #import "YTKNetwork.h" +#import "JiaBaseViewController.h" #endif /* designerModulePrefixHeader_h */ diff --git a/jiaModuleDemo/DesignerModule/Other/jiaDesignerConfigManager.h b/jiaModuleDemo/DesignerModule/Other/jiaDesignerConfigManager.h index 92c72a4..a3e8e32 100644 --- a/jiaModuleDemo/DesignerModule/Other/jiaDesignerConfigManager.h +++ b/jiaModuleDemo/DesignerModule/Other/jiaDesignerConfigManager.h @@ -8,6 +8,8 @@ #import +#define JiaDesignerConfigManagerInstance [jiaDesignerConfigManager sharedInstance] + @interface jiaDesignerConfigManager : NSObject + (jiaDesignerConfigManager *)sharedInstance; diff --git a/jiaModuleDemo/DesignerModule/Service/DesignerServiceApi.m b/jiaModuleDemo/DesignerModule/Service/DesignerServiceApi.m index b0ddf13..cb75286 100644 --- a/jiaModuleDemo/DesignerModule/Service/DesignerServiceApi.m +++ b/jiaModuleDemo/DesignerModule/Service/DesignerServiceApi.m @@ -11,7 +11,7 @@ @implementation DesignerServiceApi - (NSString *)requestUrl { - return [NSString stringWithFormat:@"%@%@",[jiaDesignerConfigManager sharedInstance].prefixNetWorkUrl,@"projects/1/replenishment-documents"]; + return [NSString stringWithFormat:@"%@%@",JiaDesignerConfigManagerInstance.prefixNetWorkUrl,@"projects/1/replenishment-documents"]; } - (YTKRequestMethod)requestMethod { diff --git a/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.h b/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.h new file mode 100644 index 0000000..8a62087 --- /dev/null +++ b/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.h @@ -0,0 +1,13 @@ +// +// DesignerHeaderView.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface DesignerHeaderView : UIView + +@end diff --git a/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.m b/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.m new file mode 100644 index 0000000..7103817 --- /dev/null +++ b/jiaModuleDemo/DesignerModule/View/DesignerHeaderView.m @@ -0,0 +1,13 @@ +// +// DesignerHeaderView.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "DesignerHeaderView.h" + +@implementation DesignerHeaderView + +@end diff --git a/jiaModuleDemo/ProjectImage/10.png b/jiaModuleDemo/ProjectImage/10.png new file mode 100644 index 0000000000000000000000000000000000000000..11384a019988c86e9ccadc5b5be36c76794269e2 GIT binary patch literal 28639 zcmeFZcTkgU*Do6NQEb3t0R#n9dY3L8MWh$$Bovk2d#{fQs5I%)JE3J&ii`URL8Jaut*}`HxLIhP^W&cyTSHx|wfR^WO`@JCnK^HEn zyDmy>T|dYtw4TUcG^hH4wgI2d!SVsUmx?s50N|F3hrUpDsrS`^NMj{JY> zr&#iB?ltykZMgbctpT@}L?Z=h_~`I&FAuTARQcd~6z@53T2|NvKg^+!G(8~&mK6fgq`xsoI)3f^`~T9hUaS!^{XBwBSowHw z&CQ+mD^IVrknQQoVHEEL_BR;k>4h1uCusTTduca=AP|=D4Eef0_u&f zhq@ve8>CFgSI}B>d-bkJ52?FmQTUyWAoQxtu0Bz`CBc^)yh4Gg;~d%uY8j=TrdAS< z7^>m5>CTuE@-f$^S66*8(K)9qratju$JcCz(s#Dg#P$}Q0Y^J{u08?CAQ{%<(F-Ox zkN%=drgcA;O0C(Hl2V8qnb*2Te}_#s+Tw)GcQ>-aefpr`=04A-l$c!JS(yRE=q-eW zSi>P+dd3vtpnz)DioJb$0vC{$=vyDX*h<|?9Zp?7RYnH)&;B(lJ#Zn&#Jkb~27mgrE`Cp@E*WXV@~+8v(Lztddz9Q;hl35Jt6Qf0d$r!ahN(f+8E* zwDZYftROSGs}G}M3>A)L=1G$@h^?L7(BQH>9er(=MnqGTy_e3i(byYAME_jMrMcA6 z*RFD9agZ=M=#X;i{!XOV_vyZuqb1UGZqJ+ivJIffA9x2i7YqDJ& zF3y%krO*XTrH^l~YzdS(X=3#KqBC@TM_8KXi)h85O@bzI3ZA;3g47NVy_dII)@nHx z3_^^+NRsY@8bIsrGhm*^wB-ec3iv2aZ6lnN86#R2$^^#~Cv4mb0vL zDg9h{aJ6W*q|h{~b5!yfia{(lxo?-lBjCg0kcB`hI_CxM;mVuy{z7X-mjez6>O7P6 z3KbEn#T30ynUzWq?VS(9Lr*=D9gbCeSmhm~wfiJeM-wj|VQK@6`ubpFN!zQxvhxTP zk|Sy)@e5}Rf=8bTX|6kt?8ATMnRmR7dH$v0iz3eFaKY8|PyZiwoTG?$<~6>C*%;Ax zk}L*uxHjsgHAUQT4%v_>Rp2TcyHPRJN&9i>Z_Xgo3N6gi223v2!?T;qZ{q62R73L7 zomAUj9~lYTU&zNdPuY`uEX%My27J=K(Y{7E#`o?i4Gsr6=-ED>32;oNahqRT=2a5U zh%W#$?&`uH@7o;KRAL#4(unRe$X?Do16>$XiM{RIurBN*Q!ow5yow@;P1KKm<*)x- z4SkZK{!7Pqk0szn9a3wLzCXWVk3piu3E5_29j)iNV(a6l9P7y_rfu$>V;*q($^KrX zu-O)M8yj=Cxd_*~dG*b{{1tcCP)|l_rngUQbt({GCxYc!^V8tu;ZnHJ3M&kxH^rh_ zyh1uLShzzQc&>@S;)Nb#VW4tCru{ZQ-ok!SZUHs77$GWxjh5TM7e*seZlfixtdO2mb2>RD!%-W+h~mO% z3A1DT8VgL=9-q`Dn0#ALM)p>iCkNUC7|8krF@gi}!-o&lO2wwAmRyx@YL-IKv(M4A zuoGmZO9p|V*sk}x0X=z;Tf-%tPRzd(CA1Pyo_8hY*La5b&a#TNE^Azl2)^`H~jr?nNIP;$IdB+=niGA&i_Y!H(8|IEorz)Zv3S^^cjil`E=oYoJ z(J37{^;T?;8#G6Jrn)&@lH9lV!lY%npy#mU6Ub zgi8Imn}sNg*Iah*ec8`7h3ey8BNMP-CTEsPo3<{`C+?* zn|^2!Aw}$ZiP( zjpZ=rW)u{VqtI~v5peb7ry0buuBvqR41B1up_*J*m|7jopYZSXv-uR!D>pZ@&gsPG z<>83djC^aWf3S70?d7MFfac)}ZEfOlLKxL8FJ)85g;07h+up#3O0dR!dq!Le$OBd0kL;YmWZeq7DFO@8rC0xQ@uGGPbRcajrE6@I6FQOq{K=6CFX z1~@%>Mp;LGjT2MH(OcKuE4b{`9W>l%92TGCq_yv+-JXu0Tnnjflp7w~m2q;5+sau8Pgp9!AbazF;k@1E;T-VAOD3W|So0jTpG zp8QG76h;M@KHIflatMpmKxs}HQ$7zH3v&N!Y?O)2YX`?en6$2-J$;GVheyE$Qe!Gu zX}a8KlRNii82MPzR4{%jNSmXf8{lX<$=eoP=9 z=jx!!D+-ckPRhL;l%X=j9UgJ-?JtR^gd1fUho7|sd2L6MuqvfU=3ctLmXLYZ1Yq3r zj@KZNEJ+}6EF?Yj>cJ^kHhF1b$#`#RIUrXKL`H@dn1`KTNg@&+s!;plq;p3gl_!5( zKQ@$LUB>8nR?j2VFR{ z{H3?!}e@utg@u;t*T@4E609U8BU$Jd^!Du;4Y+x$rF z4j+z7a^kHn<$fKVj;2SVx%BUXjZO8>eKMWccW%qj`aooh@9c|^kORB+mbjz!pfE1~ zsaH}^o8BnzboF1F&%!hhk9`vwp9f9R#g?|RT=ShM2Ws1rq|wE=0*AYIM66rEf|nG) z#gX=fK|yDBAD)yy{8dqUo;PzS1<9!G9IO#i%b~Q$Yi?sWY|<=rl5y1z1me@r`DX8RC$O0z7-4n6)G%%}4Ks7=9DH$S~t0yKM3U+>8|Y5XYnvkg9Md0xCKa2$Z0w!?h;A%L`~Qskhe zsoQIpqa*Gq13$FHenclWTz8Dw2D|RqePv)n6;|V8)=gizOpwI zVddN1+N& zB^&y!&-Bx3QHisyPgb=@t>g-O*&EDe6+g=vtw5jmq2FO-6K5UkSHnB-Q|6)w8JQE_ zLT9*odMvZBb^q5_J|D9asMy8Dq0e()s3dY1^?RC`nOO+YfqxztW3M9p3KKe+z%MyD zIgW+ttE;P5%P6DbfR*JF-O&D*l?}=524?@O+S5-ZvN16+wxgBV51E*_@`+1J*2ImV zv!RbvTteQPFMHD^^ea%OjXew7y+8D6)zcnlhcN~kG&D3s@#ZV9$kgGe0#+xN5K%pt>X@&KE8Jb_{8D+|x3MlolmG>2rfP@66z6b9cDTBfL`!z$t!b$)H z;@RwaQH~DjfGv2{8p^NKwLjzz_#QnL?<$X*0Jj$>~;ZQ(?dQgd@8vQrjG8>%V1`kufgY_sKDm!ot-s= zVV!NlLSJTu6N;#}*q4d%+i2D=Ahg+xlqLrruZdzeyOxLGE7RZJLL1$S^eRlshKF@} zQ-n)K160O6@xw)39UYqH=6TY`tAg?h3fQ&GgoJ#IiJ#iQzyN-%25$K)%?5^ao_VS? z7)39!>R8F6@}C`oC`8?RVPuqcw7C-deSI3yGN<(-4&yrJs91y=xC&N4 z*yZ;#bQw$^%;u0_pQIV)d4);yZEETQCWWYu_I3pz{qo=K45L2Sh5wH*2&2vW^{M_R zgS7$kC@fXR@+uhq(2LE^{Gb=bcKFOSiuH7{GBMJLg;I3IZ&TEj zLBG3G(C#G1+mL%uWnWYa8!DXORLw5(Kt))RbG`Xg(5AuHY@WYam|Il}cGPW-SUQv@ z?;8G@oo7$~IH4?&(7cw|ev+6S$00_g$2F~b*>&DrAi35NC*FMUI~+fd8|HABA>}9J zf!E0|C>T$)u(a&LVvo+dpB%VcymYCntu23erNVQ4LW~E7P~~ghjb-Mze_uAX*0PuG zA{m(}ay=G7*xHI=PM7i<*>lm-nvsaPa^(uN-Z{JF2+tJ~5@ORHMSry3w9)0EsuNM$ zb1(gI>cWx$LTen1y2kWX`K8K(A`d#?}@pTL0hjIUEOs~)@moLA6 znU}~{dUZV| zF~jDi|8~N-`*f7Y?3O7HE;&z>fuas}+7@kv&aSFJ(Er|NC}s@ROB~u;!zLsq7W{L8 ztQg>|h@gPuy@ZO23b0+QuzR`D(pq|YiBXI)^3-_mjOqG%hMn_}HjhjB!Y7ZhJ>4de03e<#wNae%f zT>Shm!l`+x*GwP1+umIsQr6JG(3twa!UTTf!{eH~xTK_-dkA7R#vnLw9e4F$*#B^; zx%!#JUV6OFFohIWT#(7_1XsuoALXDi&ukAwVP4) zejgT7lblA{xz6DKRB%@zgb!to%snD{^dpiRJ|*YU$egMJ-@o`t1^0lJT@VMl^2f(| zOVmB_+*jHtor41n;aBV8#vR=1}hC{1P%d90JV6(i?_V z15EjXo$=0gV6$?upy*Vo7bZiq0_jz<5|K&3Z|8RP@Q=~^q4^f6wthKcG3VGR-x!I> zKYw2Aw)jgvl)kaCu~;Kh+OtL<7(Vs4WRxSo{QCh@N7Jxann%DjdH{o)E@VIYsLT{) zqFtamaEHa5VVl8ctzndyJf%1x+hKN`Tc4DtgQ(+#fn4bIfgc}kt%ar~=1W^8c<}32 zMB=lT#59Vm!dO!d8IP4->pf%aPrE|7biA*?@fdjU(orH z?Hz(vl3paU(tieEACqMeqjXk5b#h!el-A>M&9!T}{6|Y6=eBpYw7xgEHzVCs3uNfC z)oL>OiRq~c-YtUEP6NQ3ETGIlX^`SIWae6~6M|v*OGlBq)#A%;Kp*=!$9%n1xS~C`zC+jF0)pPJ=^nMxB8G>o$5Sw_KykQOwCK=&+`5jl1Em^_ z04u`oS1cEp@DS_vFyDjgZGwtVzTk%EUHeAATR{P|c9Ng_dXhcR8o#=sZri4@DCD46 zh)`QDjD9X0mx)Zhsl~h8?7=1!U|lHEJYlkrtci*ei;2x$HL4jGDfPjv2r_Ng2R`ZhI}q!h=hR$ay@J#orV%As9g-4)M~UtUqX z1OjJ}Q}}NK=YsEERA-x;xMCPqoZHI#*GGz60mrrXca5yu}@Dv+^E#Ng7A1C zs8Hhd!{%FF*zlKZ0%f}At0%sW{l+Oxui-zXhLwPN9;fqr8g4@WT4KZM5-p*f5;Iog7J=$JZE z=$#F~E+=S+*x+wTCB(YCfCWmG_rY&xv<_Vm$5ZO3zh%0!XnYp=iHq^<+(g&5TV8G| zw|JvcEVu21+SN7Vy$9YF=#qSt>voU0tB8VhM!B+TGr+~=9m_A#i}}59f!7d_F(aaN z51~hP3;5Y_Uv@RAjm?_6t*{nyT@1!IdSjFKpOnf2%^AC4;c?Vpr8+_A)z$+GQ-MzG zkZuer4fCl9pK$6S)t+Y|(TAUX(ThG6Sy}u06`{1kPsyfX1VgAb!qMxgl-)Hjo!#Cp z6RvMCI=)X+y;JAA@5AGbrw~R-rqvoVF#>UES#VVBuYdpjc%s~kyqry#%M>;{RJ$~m zh#+Pz)8@zo1{QW8m>U1WXTE^%KEu46Ux4kd^(_)+X62`xxtCL>Ixt*J?d~{n?V9a6 zPmStCNlX_tHzSHovBKX&N1IHvir#Nn>Ra*hvMo)DVvVJ+$q6cnI$K!UxG;GvyosQ&+Vv{b!~>1hwb<*$}7zC@lNvc{D=>)8RsCdfexywfLjYrl?dF{!J0k{IrO)Fy5L z!1rA(@%nQq8A??d?e9gCXv92CS`3vqMy%*3sSUg-q}$Ri1Yb4REPAV|bk%azgUj;X z;6&sVC}GE^&TfuL!z+mkA-bwVH24oLfHg2U7BND*xy^_*zIoW~!)~9Z`}*zh&AM(( zckdCM1)`(1%{hJV8g1$U=Z`+Q7i7F0qd)Xf89jqN3Mq+4CpWeEI?WM<@`?j~`)_Rh ztj9lT1{?&up?1<33>ZToaEkDUdDq(>zdcJ(~ zd2Fw^PqUq~l+|FV+~{4*Ry7v&n1~%2m>|D0?!Wm)OK@kH{j18_-9vVfZ!Oo5d3J$J zrWLVx$vDeqJ*Lwt6iBS-zv~D+mw{BL8>e)wQf#E5Nt}0q6J$S*_hs`42h;Fom5l%`UEPD@Lth>UK<{>;|)cEGauB+{3 z<;9E|nreGSwtT&w`l3Ojnx60mM6kCcM=unk8)Wd8Q46cxWT5J|bJFrr+R2NWCj4gM zXG}#|@bcQ`Ls<)-l``Zm0b`m}pPriJ4%2`8lnHF;-uwIA$>ux5+ZbnFCXKpgoV}nl zwW4A}UdVveE}9X_Rcb=M_BgG4nyLX*uz@E3y+z zUfQ>>+i-u5sV-fipYLSL96lnf)VVFHml@VPpZysbSHjhLt{nbSacX%^HQ&l~kmiM- z%INIR|4~{BHnoNgn2Q*!;iVcA?LZYYBArTU!;$RL4-5g$=)xA4;LU3ckht38OGl}8gi^f&ZQQ*QVeh4EHQrGCl}a#ZIQd4_xc{9J}Doq?R2C^ILB z0f7Rs85j}7Oq|B3|8sQc9jaBmjYg`;#tbxV@_yp(I~ZtGM==_k7p5pGRNwZo?kK9&G%Er64`b0f+?)&-4K zLD-HC^CegbaFhlHvr??RhMnz=w)hfFQ_=hR^0p(DQ2_tX4`~0DXut&V1L3J2G{qzK zJ(~y}Ct>TtM!8rv&lb&aSwkl4u7iPjKwP5<-6V@kFN*4323nx$Jt#_8 zO!#Q?*}ARcmr^_Fdv)mD zXx-ZFMLibuvtKiy{=t)3nl`SLSS2<5NPonu>}_X{fz+wff*->ww$qD6%W|#u6)Q;e z)?iSEUH+j=+90EJw7#oei*0>Vp^q~;asC@?Y@TS?JA7{B2j9RKUwF+IOR`b$=U(Ik zmFgH&SR?nOPi+xUU#i5(W8L02Uxeq%8^@DA>#h?0Mx1H0uy}9k<2!GwjdrTnVOr@M zl5_<~Oj>_s^d4uQ`3r-WyT=rT?CLmF>gUhaF?mOXv9$n&Yb^va;mk0-foTduZi)z7oJnLK@^WB`Jj^c&u!YG6?#Waf#_;=gDA|%}N}K(R7y$mXgCIk0VeP7a08&)G)9}!@Qf}ZwVR2*Og(BM< zt7X&U4C2n5u$`dCWnqrrR;IZlBUFOaR~sr`hM03OeAtd)_g0+8`S>dSu^a?|GCQTKxHQcIs| z&o89fXL=paTE*riMy}Xw#XpGRB&FH90O6_r)kR9SXsMLE0jCO`-3j>I+Vc8zF=)M5 z8sx9Q@xKUYudG>uUG45t=Y2jjqX*rG$ksg}Wx4>3jP}jHkECaUVHp6VB=PnfIY=b7 zV3^+ffdMKAk|B`y{s0r1&NX0a%6Tz?Q$JtFP^3ME>qV~Uj`9yxyXp*e%Q=>RG5u@$ zr_|%A>7|>_W0JY@u|guD6<3_Orun$D=bv9EdaKn(+}@C| zOp^B(VVR#Rok;yIbCIOtmV)?1zHAU<^TCo-%JwpA z^R|IL&d0CvRMIII@iU{p@OXSBT&=20G+B6~?Vn=fq3-q1*!_(DqPgoKNXNX|(tB&t z?$5Q)>I`|4HkSRYyR@)~TcPfHD0MZi-Eop^Ful2_sWySmX<=TjoASbxM0>=AtIXW# z2KX32=5$`vWPV~MF^G0EZl#DfhS~c1bl}jsrY9bsnU~w5QA4F$`%2a7Iolm8rZzgL zJ(7zW7PM4BjYR7@W+RB7l*qxG~vNQSQv4-)jts#(1rW4+|t9EDH&}(WS zYc$}?UCj%T;$!mmQn;xn3K(Gy7m|G%3r4u{819eS%1+4TzWV11%p;k5`;N zO8A&;@L!@XCmmv;AP+20nK21hX8WDzB9Rm6v3ImI_`y-3mNNErHD-28su(Mgiob?{2I7ePiv_IkT4*k13^JVH9+{;op|e26fpF% zp~=v1AfoS=cF#!_snb2w;S?-+OPWusQ~o+$ep}&5ip5Bj4rV1c)`&r*6wA;1)xH-CmR%`0o+eFH^o~h@N~7@bW-_5g5Rw4VQseF2S1D^c;!#8eBr!VAFGBLdiVTK%LIbEZD+M$KS9! zoVJO-wK!{XLSn4|&jg37&h}i@An^c6iiG^SQ@I)7YXN>Ey9ApC7m{IkIbM~-&wGG_ zaROW;=#X0(uo}dXwl78H=F2a9fYMQwSdroK|CwQtIS=L>g87M^07N6ee&`FRgyP19 zM}CN{xIgA^L#(e^9b2zV@E>i>S_#cAPkJ5`_c61!cj>JC_OL)F4maq^8FEw8nrpfq z$&=WYCSD=~T@GY*ftXj3pAkm%sUg;TJ49WebKCojDha!ht3!HjY?4_(Tdj;4#x%w! z1!-4+yr``1Q@}21Ta)nAi{7;_8z62BBe4|tinH-jz{hjtzcYvb{ZLf@?e$A<0gJ7x zvpcD&q~!GUJH%pfj&pC+(8F;|)*~uI2;4Fh#NWp zkUToRc44@-1*PXGRcI4_%0=_`38lM@Wl6qEWu|oc?kB{W)B_DKlRz*lj<AH?mT5*(QxO^W6++n zFiBO=UdNa$F5n-EVt&8X;&JM8rLURZx{%Lbze3-}%jm8VezzPfSr+GPnIm}S{{UIq zF^U&bs0ysTSR+sskgV?mOktdzcYZHj4en~+2Xcz0A@R8vWUQUtuYen5^RpHHuQEub%aW%$#8e0{x= zny-mpfVIZk>*bgabA{Bg64{!d}E~yw(PDat|_nGGPa`s<59hcHQ@M z7ltsuxfd)T?!NRX!*5;8!rWXj79`E}%8hJbL4-v}aPfm$Zx+M#gTmjy3@+3aPh|Te|Vm^ zic2I&O#!;azWJj&Le~BFlT}%90sFX*A3w(CJ+|>T;2d?gV=>@UI$yXR`rYds z4>hn%S=+R)e~Oc8NM7>)a&x~@FaK!aifj>&L8Yve@2;k|_e|W&UQ5ANHlUas1$@E4 z$3OF%30d~s0eLbm4h|&}S%TT_^9mMOfkRx(bQ-OkDZl`^(nN!`o%ocMb>CsM@(Cbt zKr3JVL(OZ%UbM*|b{=^9vh%MbZwI>?0`7?K-s&<)Yy*#q3Jl{e!e#b(+s~i)7zG9p zID*sYt8!fD;-Qw71%LrkbaLV!KtSssogQxxX2KYYEqhagDC-u5NB|si~=es6uu7cAj*=QK8H1PtrZP-6S8u6@)#?4om&n zN4O0@ex;%5{mkErm@pUM;N#OcJUomo?MoKCbKTX;%S)#SbV`>FsDdINZ|~bp6M#tq z8W3%u1C|~i-l-0WPaUw1AFy_J{|^-rESD}FFb*iUz@eoFK~DWLsb^}bA{?BYqyivq zRn>@G6%a2ua{}=fZ5zl{sIwVjbr`Qz3ZtNRbqBf`q8@plEKAFPo4T#7ZOnI)#Hdk7 z0(xB20@RP_+^HEW1sQl70O*Z>@u|6a>lVH7O)$*~V8u0gEo;X1wt~-HaNk=U6F`28 zNWxgAS#eCA8o?&MFVL!-5gqt{#XYdJXVJR=`4wWwbx!Bb+ixI%0?ig*BrSV5@VSql zl;~HCoDz@gzzWIB%P06+v()HO>-NV{3-0~=?(#%~0Yi<|_wHSx$I1wcBc{>A?kP!JSxC}VGuiByRIipP9pLzsw3g^wKnRi(SUVCd zNqoqOJEU!B2PkDJqE3Om1TY#+07W>ymM7hN4fKz^!6X{??AZ^sQqYgABk<1p2bgPi z*Gs^kg+`>MXXfTsRZ9`#sFoBG(#g)w7De3$Qf2$@KG}3A6=vtT)1STbC-QC!5m}E0 z4pyN*>A_N;odwStZ4vAK>BbsEAWB)Ufm}>Hdi(7q<^rb4%Zc{-B{Dsdyhwrb@!bin zTn#e7s!uOCgVGO38f;~xjOxxE_P5`%^va-Oji8-iTR`y40u(kQ`&KSvqop}AK$xdJ zD7hxvKv>7Y0*-cFfP_2Sy;qBEd#us*D=xO$oc4>308AMbwCl2Rs`8o(UU1iiY4JtM zEDd*`FwXm~tgt+gM@O$oANV-ZX#;Hg>5*GH+Mx-pEJ=eJe_4EpNTM5wWf3U9d95kx zmQA(fmtkom+*hA}&CdM7@891ml_7zr-qHZpXSkOT9%Fj zYgh4Oo?3~oOrg=jugcsXz}+3FR#BYliSL7wn$@SNWj|ej=-B)hF_GT*>V1p(u1zQ< zZBAyauSkrAWi8HD#r(_l3n?nGgfl`|o_`Hdgo~o%(c(GU7Dkqf#~lI=Dn(cTo(*&9 zB-VvpO>z+DJoHgArZbFga;_wt(Q9=7Er=K$s_dD3Rb~d|qeVo<%;cUM5xF^N;p3Eg zeTd0?bobr$eNnEV`6|_^hxC$st%C~Y2E@dk+=}_(*6c6E)h|C10Im3H4Z!!ZuP^1WZC7@Z=9po+id{@nG3nP5l(t-m-|&tnkbEvv|?iNmvQ6IC&L$NHrPr z;H2Z)9#?Em%}>fGY1u~AicE@^3KbU2EwZ%EuH~t=@Qg=S>dNjb(bPU1%(6+WN{NCD%F4ATr@kr#usSyMpAD^SSIE`A*H7FoX zs(avv2U;m*O8L!xcC@w0S5;NfN%__;^d#p3n@*xGrHgwEraHB7$jHc$Wzag>Tx{qp zTRNUkY>>#;bC}4@2a)K?5fAm-^>ri% zO;-*Rt%(D5Ej)e&XmjVj3i9+0zf~0pS}NBRkMr$NL)?0H7vhW>x^( zIyU|vd{AJrn>W8-^9BBiklD}cVQIJ0zBX_dA(G~1Y*CUAjG^_g&O};4L2lAXVrIe~warSGkI6DdBsE@ArbUTa7eY{*p(ZJ1fMmKV% zkw>-c632|2QVo?>vq;{_<>qtx^s2RRuXBs;96a&3Fyr zYYXGAaoSLXPqomH`a)5y<3e2zti4A_BiY8H$hyeJ#=tQ-<=V%GoR{BoU+9^TS$HHa z&>GcxA#;DFZKdZVV`@hdMf+H6>d@gInxG?jtRGH~k=wVq+UU&nZF%foTH;zbQGi(2 zyi=7WzIR3>#0OCIc86dReC0d$wx2J{ew2E*u2Ho=%#x1Gw2D>jeX|C;6Ysgwu<5IX zynOtfsWW+Rg+Va}k?!pGac#|E@M3uUCsyn+N>Oe+@faFB(9c8$DU1Q`E=Ou_0qT@c z5mh}g@rM!$uzo!)typ`J)STRO8D~+aNu#2oqG~7~1?uXxYi^Q`!-X-`)z#*8&@s;o z>h=|KT9T;ud#5i7^IK9`ugKSgxgSL$v+bPOg2lKZkKg9CSEo zd0u*NCVdEn3~TI=O+IyTTV9-05+K%O+6#(yd$tR3RLFj$NLb!tSYPp?KsxDU!0waV z^9+rCb~U~Bh>oQ2esZw0_xF2J3;hQd0FN#q3~OsF7o3$9Fi^e-TD79(n_m|Fl=}8v{TMGEbO;r}g^H{O z+>)k@ci)t+Zxl-oPZ9lQ@N~%9m}Lq~MRpJ7{PobF5C}y07tqrno+b|18m__Ee6rmw?!B3H_3G7Ht3HNiKz5@O?rI?Wy@s3`0UIU$)2A#F ze-n_}w)(j)a6a*ksr{u^&SwWt$RN6t6S)m=#Gtz6~mC_D{)30 z-QC(ICK2BwFU2OoQ;x5`?WIBP!mdiw*bf+`Mt-QX6;eUv3z8OItY|Mvv4`v z(CWEgT#Dx(-3H#;Lny+&XajXNS!55G=+GL=NWkYKXqhfHEM{n@ia5AW1?=m3-umZt z^AWzpFfXczvckD}1zz1OB@DJfQRr0oHJ>Et(VV>g41EG)C!F=yl+fNsyjN00K}3Lv~>> zEg#3hklbe@MZ0!01H3@s_}a{jo)8WAv};(TN-Rj>!!v_U$6QKHQGw7V&obsB5IgGQ zNnYu&BDd%HtYKEw&(pQc5}HH6Bq?oeZSgMpoQF&+fs_h673f&am=T@@Gc+_rDxA=D zDFF}KvVj@VQc_md0!vQc%Bgbm-n~^J%5qbgeLrRrG-Xc;k}LqFdwXkZU>(;43?cmH z$`IJ;5KRwoZQ^LPrf+U`HkV$)(|RCBo=(s*!X)s}0@z5KgUuQI6bdy`YB;-X1VRcB zSx|(h-%)j83@!Qn)-^D&g;Ws`5fPz`5-CQ#d2_xuO-!3q-T+vWq*bt49?U1zb^wi1 z1aoTEb#Za2HsH>1bN+|(NxqBeUd&2Bo6t#mS9bd*F&uAq^Ks2j0?U&z z8FUsvDggiy5|`^qM+_6GciPElTU}321Rl_q@yB!X^B~;oo9}Y|ml&>fPk6?gf_)0+ zGHVE~VMnTVs5buqDn{tr{dSkK8Kiuz7k{M#cRvFREEllWJ8bL3_hP&I`n<;V*S8nJ zFxh3^q@BCYAUS%YAFLrRwDxyYLOUSJ6PDqbw%^`d^u-s!hs$81IOkS!bq^qq%cIvD z`%{GNNL2A=ApiL-7{C~XgV<@Q<#-)@S|Il|C~y%1H3=SIPDU*-P43G%z@t_GJ&9xP z&6F|a=jUfJ2?Bp6jOYP3e*FD?vZTO+88VU`6SVrJlf-MhJE+39JZ6=N2E6@rkzii; zAvIAk1{gOrfDYi*PeZadwlk8!&avsskb;7`4($dc5;-KvWh7P}*tZViBSo#Er)lPt z!T%oNH!yd)hnuzeDoM8M6Aix0`APQ}7eIB6u*0~JTH50mVCN6NrIcQ(%`^a!JgCj! zG&MC<8vM7EizgN%4Y<|6O@rufyaklEA5XOW_wucK1O;LUVS3m>8xb8HoycdpzCD`% zgoBAm4k#0gMo%C`B#Z!%dGYC9lP^H*91oNO2=>`|dDVg4837mx+$zK8IjKkntN|RT zl*TV3@2=dcb-;=MF-<4}Pyz&^{QQ&PXBEFWP-jxG(3{#+Drz@UD$tj7SK7bctn&cC z8c81IEl0K_ZvQoEZcRXS?-r*Hmj`inQG5C0RZ-GsW8%r5{Cdet|K`r!yDJDUM-cy} zh&Vu#%N^>VDpV~eM51uui8r!6E;e=;M6KIXm?utY9>Nnj0#7k;}>RKB3(zGk}$mk#TLbN)9mU2LZIR3-(KQ zcee_lE9;+~66=5nCM^z&KypqdQSTwV;5 zf-QJ?S9kZ0A{H14A-4rpwa<^90G8<>z@p$J$v8RKf;PD3J2n&a0E*H1y2?9`RKg>x zM%uvlK#TyW*=VpPB;f`jCU*H?X&@I}W2Ny&*Uu;D4+BF4YO4-E*77`f@PwouKuMAC z%dZd+=sg2rQ`9U8w~A(vss#im;Ie6ebsKnd@fvU@=))19>_@_($oUX_#RmfUMVh60 z7c*nGUSX2Bf-0eDc9gr#8HgNvGo)Z7${Tn&*V?3IjUj+)JS6M|0a|m5O`WuV(#Aa- zK)uWo5VHYb(V3NY7W??n3j-2f>)fWGrWO)R7jfSTa_-zYIx$!Cm~GG(8V=BzWU#UI zZ1yRxUL6EQ3oq=`RrV{ml)$nwCvg5y+Jn5umu-5{GBR$=B!WH;GxWqC2nb7Lz641sGEwCo5_=IHy{ zBWSf3?BYEMgX7!_#;~?ui&D>p_Z(H*PFv1piI}04A@i03$&xq#E(AkA02!QrEs~0^ zv(sD=gMFg2e`nCt?)bT2JAh*( z~26d z-E`j}b^b4KBPSI-eHmCtse|da%BrgFyTf3nFhgnpE_uWau5%RtaETO|k^J_&Jmx=B z^|jIf;6wm+edgUr!p1`ZRsjx>w|@|ANbt8uq;!amAL6r@6c}uw9$*3hU`Ov+1RMs@ zkvTa#f0Oiip)9();!|_WtbpL~>|X?jJO9p~To1iZ+DVX0a{uj%bDHY6W}1zVUh6X&zF?6*xtU;Jk)w1|4nX# zu%9<6qjmS3L`H#~DuJBPsAd*d&4-yv9P|7s5O^ zj3F1jw;HRhtBb_~ull&$(-n}7NF|*s{;Nc9A6eHh4hqLNEoi}k87}DMK_3*GwWeYc zP5ScFa)KiJ(|kkJa*mTHP}iIY-;z4`%fSD`mqC#VkGFrrIN|a4ImE!gqoD7J{QZBM zIrz_i^W$^NUOU;2sJHq$%+|@o)>-x8Bv|tngj2s2UjJ3L3V?aVm|jn9PrF&aB!BU* zlZYQ7;8F}aWfVWL=xj?`e+1)ew}SE7ww|dNjxvgW4JHyY4~mB|OgNb+GPN)S*TXOnHyI&eM5IQoIL&NQy$pB$a;5?# z%6XiROZ5M-e!ZswdF#?Ik7|{3&*~CJ)`R%a5O9;*kI#wZ6~NiWc3O1yZLoceKk^j` zT__kgs$S^AkSHv50n)nOJ9bDs?)npWPZ=JrB|04cDcJ>HRGNZ#g*j;_kBq25)+iqW z{lD2Lj%Zf%Ew%fZO^8+ot*Q^q>nwSTa%>4199%dR*1kla*Bd?-Ej1DscKm{U97Ft7 z!WWZ(VYQJ3iE>czQ)-N*iQU@M?~-NbBPd!m;{d_EcJ}hmGYOITAN{7LU6@?2ofKuJ zHf&PlSEll+)O>jgeZJ||Y%Ydx&E32jDt@4CtTK_cTcWr!^;Mya;ZIzgynyHSpmep< z-d_Hk9EY3o>ya7U0k%qGNPmnCmGr$;3CBAkYOD1SdvMr8r}L|TYl+cD?uN~Bkza)z zzb)mZSEF{P*;(Nz8$!h=Z=8RVSpGQ>h!oDftiHolZnXKO{1UJHBwDeZf-I90% zHDxRly1q(gYL* zQeX8ZN1tX7cb-fnf9rj!sn|qW&2RCx{>9q6;`-=v=5-m)ITB7ZnJvl^Pu)W43e|A_ zvrX2PT>eMTo_+>RBd*>`uabpj-m{Q>MrnE~PvWuEt=kT|@%-xDyg*i8_U8IpSUi7L zNZ^k3t&D!#1xmfa-}uG}tH{)>r>c7nAIEq*Hg7kkdL#KV#8eV@`^n}prf`nRqXz|w zg)!p$x!ioxhgQdy?r5&do9*hdz_w51#eYxA;dnfO?f+7WUHB#-zdiGcuAr~3Y@A}; zun|eGw4kBtyqSDZ4)HA#HcB%g=7_=&Ev>*I6){n9DC=J=~)B_6!rp1odfX z-#fl}iuc7JOCb~g<~DDRvJ(lFtLzjO!K%!S?{mK@lROzVOhI zTfrx7rKNQ%;xIDg#k!t+FDHi!s#ot_$H%PlXML~~B8T(KkquU;74uhzCHt>i^4)S%>O0yO=67CG z-BOV>Dbt15rmWv4cAn6^Bk)+n*MO4#O1*xD^Xi)5>R7CEjqqf~xlqY{J{9(L@A#6E zXH09zl)eMMVk;YlY@0G`+)>0#(fh}D)tzu>amWgcjO zyKN(vB;Y%NUi-a^r|IsM6DI0cpW#s>DJw>F-8Ae~+mry6$+{04NgV?#ra85vzjNF8 zjxDaMRg6EqYEX!Kg{r@Lim6%c^kJ{bq4YP@6vNq9e@~f|)H!@5kon6ry9s0XEXj*-Kn~1`46Sr9&P8a(pkwEC8*77&oe?Lc-jX;4~zbB7SmoV z9CucztIB!4X%>XIoI+V*W+E#3UaO1`_)M4c5WMR%2*fM$Cip-G-OMoHfJA6en;9Zzdh;B{X18VV`RZPuAz_;=RDqBO%({L~{C8r`dZ(G0?9ltP3i)|u4p^rbK7Z4A%~D7$FFiHQ_;XceN)2K=B@6y} znKC8VFTdRPBGKmRT1PXX-ihFo8klUxjPoBphW$EHwR5W4OD=nYYi#79s)-B;uv6A7Ces?mqq3SV`4|PMY|NxLeU+y>N0VnG z-}6NZ)=wnHdKZ4r|MC1C-Qh(>>T_kv^;c}Wq5u~Jj#Ukw%25+HCCENEb#jwn&dYd zBURAs<~!}$5Yz_$^n=`J4RxUry7C1X7a~RTgX1A?uO-gi{2c$M`KZ~&;$5!$j7DSA zROvgHcMGpR{-No|2=U)EhIHL-YEQk0!Bj3pv>1H0DHXZ+Gf}VfB4$fsOn&{2=SXsH zhWvi`{Zst8bQ1w*}g7>^@V#W*WDUPgF>86_*7WPYZiAGWzCb-7D?nlB(|jKZkAG;luE`Z&5WFK@fEhRo7dw9zKcZ6=YrAB%YIg#}E(E{Fl=iky(n9 z%eNN%BQNv&ByK14`0e-0%=xNqZ^pmCP8VC|w+Px5#v5dI^Fw6i6@KZ#m+5N9J^h26 z53YKq+TdY1^fI!Zb5UfjZ|~W}EjPXC-srN3a}tscDl97CcQ5fsV2Tc{@3ZZFnPyig zP3ZKMth4aw8|!lsph6N}4yrj7U#WU0&Nmbg?$DIw|zGKTeaD!1U$24$5>tYAn zp2{z^h=c|lI+YNs&8$rE;gvBlLR%BOCfBSf>+*#%zN3vQs^fN_Y_K!*YC31Vk0^Dm zJ7(1&y{$?imGZ0B#!PYVCjBEa{aF0xo{@1G#A4`2<1si*K{JX3B|FgON|J)o5O^xkl<36}h(1>h3W7?WI zaSL9DFv{PpR{4HQ2FmF^5h0;Z@EWQ503S%Bu!m?tKMdXyVtV?-iMMUqO5EptD|T?Z z4}N4%K*16Hk8RrEJZu=P#4Em_qk8n{SkV>G-$kb2-?g#%Z{GU<)jjyHZ>v7_wC!he z8?mvq%?)O4)0>)%pfy+QF`@}AU)@U_aG$o&ufT-o!MQ+ar{XgSXLPYZPU3et2wjfH z&?r|{z7LiWvlsLURcWh(9B4$ABPn?&8|K)JBzZ#+-|+F@4CS$C0ZhR-GhlwWKJ4jJ z5r)Ea4J$~2wYebJ;XfR$z6fyni}CmnG2ny0kOk<~d#YPdQc_Z3_U%r5CbV-Vpew-d za+K{}2PiJ2o>X}xEG^Aw)1G_s^5qdkJgLXErrK&{vEAPSgE>KFm}aefEBDL>CXlgJ zwSxchD4S1q|K#)ttn2@+x8KysI zBOeG_hEx}G+-Qq3NGy5F8DyPe{`QtAl3pB#LZfA@3FHr7&uPBjm z?VG%(2(*uUi|X#&yt4ULzp0W=z!#?tUc|;`7Z+cI9&WkDR`BMKz(@rrmIvt39C^2j zuHoCMu9ko*spH$zRQ3P`Oa!{TmH~62$-Y11tP0P&_FZ9+jdcOAqg8l~okBxvuRUCn zmSY*Trdn9N9B*Z1Ww!mnJlb=|+Z>6Mge!nO)b$R7_LJ_V!j6}heF`$v^WAj1kGWP2 z$Zmf;q$|tsGu_)YLLyGnwH!g8OCDgw==sS>Cm48zhMe+&EM-{PvX~ey=PrsWKJeB^ z79yF&+UjR9IxU0q>jZ+$Xf&EjAy5m+KnDRyuHKs+#SZ$_Yd;ezrb>H|`9~Vxt(j<| zp9I?xZchUFv7puq*+!TTw$0Jkj4YC7K?DJd|EVE9tIdRXPJ&wRbjIfU7JgBXq z;TE&DzK#X*iE4olOd<)a(3BQXo-w)H<7#~E+BFjke(ZUezYmDo60AQKI0@0^dx3Y> zTIIVC6CIs4L)*~V+F0@NPXYtDysPLMB4Y*Z`;vQeR$H43&BP!HHUnuNjx>O9#wH4D zI>2CxgIPh~Du83@0^HXIYm8u#71egOjoP%iPsf&mSu4S&RF@>gF@F5`8zF3dRTsdm z^)teX%UggJnxifdXn?;Myd6MY_y#1+EO_pgd4<@n)Q2>*~UvxNymZ(9MnC4Tu zoB+ZUX$!os1?OdWT}J3cd?wNWG!e-^*9+~l39u?*na|K??wBe9J{%g4ClJKI31(xM zDZzb3WvWU_A-pn9IWSZtMk1IM;2`NB%T|7cD)m#y-o|E>=KRFNiH(iZ8TpNXjp?>D zmB)x^m^^MA0-B*^;1UtKfh9Kef5EaDnkI0V1N01*@)Y5Qf;)EDM!kU+{LcheRF{8r zX1IThkdTlj{+fyk_n&`aCaWdvi*6x!%>;SYCx#z__3jM>4p6zMxcXyf;Ox6SE)y<2rP}rN^%6A$#4uLfCjgG{y-fl+ zpUc^Ph=5dH1#kp#0LjYJybvxJNT+42uHI{myPyu{>Cr{jGw~#3WMq^;4gx+E9b1B} z#|y?Q_?IG9g+K>@7ZE#tUK1jqseOKAK;p82mFWNs()nfY?ayVHuPi@j0XvAaH@3b4>F7sz|}bY@8Hcy*ah;E+wb+@>&|^uCZOiy zRj~}sQNBnXNsBy)vbi9e7eN73X96xLuJ7MKcFW05N$KY<7r+XEzdhs*iW1&WW{`+t z#@NYkMG}!cPBK*H;RF7;0Lf>iaIhsyfjAh%Q+Xl?eoY_;?`H=-AY=t_Mly^`2Pf+2 zLIKIFZD#PcI@}o1W+sUj5Jm*5-2!q!ca^Va^aB(~ z@pRM%H63UKF2URLu{9c$=4?-%3RtI+WsA$+lTpJ#f7q%v?PAj{zw#&dUUqi(E8Zo4 z-9dX2w1o)PE*|cW4)Bft;T~Ht@aPz->jT=hWXDvi35-~Na zj2r^D*O>T81;4DZdJYZ_f=xeJ^30j+ZxtYW7MqfiV%^`0km)X6GDhglKSB zWx-+`!J;YyGe73jij+)%f7Ff%O=yX4{AtCcp_hG+^#?3G2OY-&?>F7tVn(CD$`_e$ zoB;kBAKBe}d;eYAL|C(8*M3EWcD;v_-@wW$9nv(BNF0$(j*T@QPNc^t^rowF#EyjC znVKga5o@(GMtCLw4vv912BFrKQ9s*Jnoz3Y@c&4@@ElrCQTn2`|?9sR6rpFm)kM68^K`)+;EofX!z z7yv;kqK3zqxet`5K#nSRQ6|j}@Ca#x0kcp*@yJki)OH|*0Y=Wv(@AokpQh|eK$$T9 z+?@wVXaZ(D%mN~6MTAlgxGlXw4^1Icrlw2qIbc?mX(#}&;kxe6oMsmm^xxPudVR-r z<^oQp)6i*2l41%~I+8(>xwI<@>LdBXT3rxDtR>6_u!+R3V`sV^%V>&9Q5%zLHb*2u zx38tQ+>;w{%zHJEm`&jb1K0`Pj0jMy z1eeGK10w-%YGim=80Y}_z`pm6h1EtjQUS=aa^oDD4IP*$MAh?u^EhGEUIBgMvr}oa zMp2iOi^@&gCT$5a+#Vm)qWh0ZT^9(Ly-(X(zP$v6B?J#(qQ}BI+S1CD38;5>)1 zWuPH`Yl~MJ8{@Y!oe$DYZ^se=K7TQWGpCjNsHq{<=m|nS3Yc>f1(iB0y`H*p1?(Dt z1!FVc_sIfrVhNCG118sWzID;9urH6JGC|p?wa3Y0AmtY^$snxHU^_%oH-DY-~TR+WMXy%`U|(oLA4_~C(w*w^`IbX=1hW|gE5aEc$g5g8wH=jVysMmhr})ekoUW<8HT;DHDRnH zOlEAZy*3^ML<@l^f&~Utcco7u9N)qGT;9EVH}-SXNw5H84-X0`m1eNEXIS1neIUR% z28>r#I*0o6$^IHkD76ZDHW1;rh&nhl(p~LOMQvOI^H@mXTbM!I9!wMtE{p<2IHt>~ z1Be*y6k9DMBO(+f>qFkD#R#^Rs)hy~xeT@EHZlo_R130ez%N>|mMpVqYOs2^)!94Z z7FD+pvIFo{;ZRG7RqbA?3YVDwzwR^ZJm}UrLw0U>A&%4?P$nf$sY)vgSFmS(~htR!ZMW{knVue za|+xga^H|Far+!9A(?mqdyTlx%c;1UiX5}zlk@m^zUC5CjB;{vesi@v(vX9**A35K zD$k>L|7=}fNMYqcy$WmqW4-$D#LcBb_!*b3H^?M|PpO|gc~ahgIS)>E8BO{E&oBOh zeFVS%oDCU0uz9r@EYEAm*w8&jLMBxv8k^&YeSQ<-b%}#ohPA!J6j8?n zt%lCd&Y~h;h|^vT;#98NtUmu420>RbHz!BfB;P12D~njR!#52QNg%8-LV?6JN_QgC z#`aB#(OphPu%Z@zV}k16vy=TaVK1!@BW_BR%K!=!!q`9-33#TjARff7m29sLMf#1V zJ&pmoxUq$=Dnhw~LICL%Ai0lXny=c#{>L9J2xSY(v(bENUn{a}=NfEERv;Hy*NG}B zTEGkKu$wy>92{IX2m5*xM3Ry6=FQSK>&P*%!GdC6LQdBWLE~H+r2adEOd;*~dle!| z&kf6B8(}f&RjNuz**70V}=Y*v`uYsu8A0yp9N7+m zC<-YU_eFWKCG8p)k1WaU`zG81xn38 zKJ6}bCW9I)fSE)gP~Wa$ZC4`4xe!7w5~vRx@HXj$V%w+J{V~GrLdZl&nuXBx;K74l ziyG)RA)D4moB{<9(aSzIjzU?87&SPuHnO*ar4YU1`j_-EIO@m7_5*e1j5>H9B7ckA z8Ep9=L}q`=C*8teFjj9#5XYWbec*pamfx43`Rk0bj^EOF7P7N~b_V{U)yF5iJcB4h zhbM&VPgID%*e-9;Zf>tZo|_v4>JFY(8-@MziWh;+>|dOmGoj%LY&kR_03i*(|D34v zUvIVjr#zqk=^uYa%|3=X3Y*U{;4Z=AEw}Y3zZ{`{F)14nK4D8;J{gYu{h#{?!49%^ YXvH4M{%gO38Zu0@s?PO-YkxoZUvMphNdN!< literal 0 HcmV?d00001 diff --git a/jiaModuleDemo/ProjectModule/Controller/ProjectViewController.h b/jiaModuleDemo/ProjectModule/Controller/ProjectViewController.h index e8d09ce..aad9787 100644 --- a/jiaModuleDemo/ProjectModule/Controller/ProjectViewController.h +++ b/jiaModuleDemo/ProjectModule/Controller/ProjectViewController.h @@ -7,7 +7,8 @@ // #import +#import "projectModulePrefixHeader.h" -@interface ProjectViewController : UIViewController +@interface ProjectViewController : JiaBaseViewController @end diff --git a/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.h b/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.h new file mode 100644 index 0000000..6d174ae --- /dev/null +++ b/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.h @@ -0,0 +1,13 @@ +// +// JiaProjectConfigManager.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface JiaProjectConfigManager : NSObject + +@end diff --git a/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.m b/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.m new file mode 100644 index 0000000..73e7f32 --- /dev/null +++ b/jiaModuleDemo/ProjectModule/Other/JiaProjectConfigManager.m @@ -0,0 +1,13 @@ +// +// JiaProjectConfigManager.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaProjectConfigManager.h" + +@implementation JiaProjectConfigManager + +@end diff --git a/jiaModuleDemo/ProjectModule/Other/projectModuleMacros.h b/jiaModuleDemo/ProjectModule/Other/projectModuleMacros.h new file mode 100644 index 0000000..4569fe3 --- /dev/null +++ b/jiaModuleDemo/ProjectModule/Other/projectModuleMacros.h @@ -0,0 +1,13 @@ +// +// projectModuleMacros.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#ifndef projectModuleMacros_h +#define projectModuleMacros_h + + +#endif /* projectModuleMacros_h */ diff --git a/jiaModuleDemo/ProjectModule/Other/projectModulePrefixHeader.h b/jiaModuleDemo/ProjectModule/Other/projectModulePrefixHeader.h new file mode 100644 index 0000000..e9dc94c --- /dev/null +++ b/jiaModuleDemo/ProjectModule/Other/projectModulePrefixHeader.h @@ -0,0 +1,23 @@ +// +// projectModulePrefixHeader.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#ifndef projectModulePrefixHeader_h +#define projectModulePrefixHeader_h + +#import "JiaMacros.h" +#import "projectModuleMacros.h" +#import +#import +#import +#import "UIImageView+WebCache.h" +#import "MBProgressHUD.h" +#import "MBProgressHUD+MP.h" +#import "YTKNetwork.h" +#import "JiaBaseViewController.h" + +#endif /* projectModulePrefixHeader_h */ diff --git a/jiaModuleDemo/UserModule/Controller/UserViewController.h b/jiaModuleDemo/UserModule/Controller/UserViewController.h index 13d8252..d0f8427 100644 --- a/jiaModuleDemo/UserModule/Controller/UserViewController.h +++ b/jiaModuleDemo/UserModule/Controller/UserViewController.h @@ -7,7 +7,8 @@ // #import +#import "userModulePrefixHeader.h" -@interface UserViewController : UIViewController +@interface UserViewController : JiaBaseViewController @end diff --git a/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.h b/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.h new file mode 100644 index 0000000..ccfcabe --- /dev/null +++ b/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.h @@ -0,0 +1,13 @@ +// +// JiaUserConfigManager.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import + +@interface JiaUserConfigManager : NSObject + +@end diff --git a/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.m b/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.m new file mode 100644 index 0000000..4ae6d33 --- /dev/null +++ b/jiaModuleDemo/UserModule/Other/JiaUserConfigManager.m @@ -0,0 +1,13 @@ +// +// JiaUserConfigManager.m +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#import "JiaUserConfigManager.h" + +@implementation JiaUserConfigManager + +@end diff --git a/jiaModuleDemo/UserModule/Other/userModuleMacros.h b/jiaModuleDemo/UserModule/Other/userModuleMacros.h new file mode 100644 index 0000000..bb4ad61 --- /dev/null +++ b/jiaModuleDemo/UserModule/Other/userModuleMacros.h @@ -0,0 +1,13 @@ +// +// userModuleMacros.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#ifndef userModuleMacros_h +#define userModuleMacros_h + + +#endif /* userModuleMacros_h */ diff --git a/jiaModuleDemo/UserModule/Other/userModulePrefixHeader.h b/jiaModuleDemo/UserModule/Other/userModulePrefixHeader.h new file mode 100644 index 0000000..08c868e --- /dev/null +++ b/jiaModuleDemo/UserModule/Other/userModulePrefixHeader.h @@ -0,0 +1,23 @@ +// +// userModulePrefixHeader.h +// jiaModuleDemo +// +// Created by wujunyang on 16/9/27. +// Copyright © 2016年 wujunyang. All rights reserved. +// + +#ifndef userModulePrefixHeader_h +#define userModulePrefixHeader_h + +#import "JiaMacros.h" +#import "userModuleMacros.h" +#import +#import +#import +#import "UIImageView+WebCache.h" +#import "MBProgressHUD.h" +#import "MBProgressHUD+MP.h" +#import "YTKNetwork.h" +#import "JiaBaseViewController.h" + +#endif /* userModulePrefixHeader_h */